广告
返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >FreeRTOS进阶列表和列表项示例分析
  • 324
分享到

FreeRTOS进阶列表和列表项示例分析

2024-04-02 19:04:59 324人浏览 泡泡鱼
摘要

目录前言1.初始化列表2.初始化列表项4.将列表项插入到列表末端前言 FreeRTOS内核调度大量使用了列表(list)和列表项(list item)数据结构。我们如果想一探Free

前言

FreeRTOS内核调度大量使用了列表(list)和列表项(list item)数据结构。我们如果想一探FreeRTOS背后的运行机制,首先遇到的拦路虎就是列表和列表项。对于FreeRTOS内核来说,列表就是它最基础的部分。我们在这一章集中讲解列表和列表项的结构以及操作函数,在下一章讲解任务创建时,会用到本章的知识点。

列表被FreeRTOS调度器使用,用于跟踪任务,处于就绪、挂起、延时的任务,都会被挂接到各自的列表中。用户程序如果有需要,也可以使用列表。

FreeRTOS列表使用指针指向列表项。一个列表(list)下面可能有很多个列表项(list item),每个列表项都有一个指针指向列表。如图1-1所示。

图1-1:列表与列表项

列表项有两种形式,全功能版的列表项xLIST_ITEM和迷你版的列表项xMINI_LIST_ITEM。我们来看一下它们具体的定义,先看全功能版。

struct xLIST_ITEM
{
     listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE           
     configLIST_VOLATILE TickType_t xItemValue;           
     struct xLIST_ITEM * configLIST_VOLATILE pxNext;      
     struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;  
     void * pvOwner;                                     
     void * configLIST_VOLATILE pvContainer;             
     listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE          
};
typedef struct xLIST_ITEM ListItem_t;

宏listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE和listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE用于检查列表项数据是否完整,在projdefs.h中,如果将宏configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES设置为1,则使能列表项数据完整性检查,则宏listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE和listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE会被两个已知的数值代替。

xItemValue是列表项值,通常是一个被跟踪的任务优先级或是一个调度事件的计数器值。如果任务因为等待从队列取数据而进入阻塞状态,则任务的事件列表项的列表项值保存任务优先级有关信息,状态列表项的列表项值保存阻塞时间有关的信息。这个变量被configLIST_VOLATILE修饰,configLIST_VOLATILE被映射成C语言关键字volatile,表明这个变量是“易变的”,告诉编译器不得对这个变量进行代码优化,因为列表项的成员可能会在中断服务程序中被更新。关于volatile关键字,如果不是熟悉的话,可以参考我的博文《编写优质嵌入式C程序》第3.2.4节。

pxNext和pxPrevious是列表项类型指针,用来指向列表中下一个和上一个列表项,通过这两个指针,列表项之间可以形成类似双向链表结构。

指针pvOwner通常指向一个任务TCB。

指针pvContainer指向包含该列表项的列表。

迷你版的列表项xMINI_LIST_ITEM是全功能版列表项xLIST_ITEM的一个子集,定义如下所示:

struct xMINI_LIST_ITEM
{
     listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE           
     configLIST_VOLATILE TickType_t xItemValue;
     struct xLIST_ITEM * configLIST_VOLATILE pxNext;
     struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
typedef struct xMINI_LIST_ITEM MiniListItem_t;

既然有了全功能版的列表项,为什么还要声明迷你版的列表项呢?这是因为列表结构体需要一个列表项成员,但又不需要列表项中的所有字段,所以才有了迷你版列表项。列表结构体定义为:

typedef struct xLIST
{
     listFIRST_LIST_INTEGRITY_CHECK_VALUE                        
     configLIST_VOLATILE UBaseType_t uxNumberOfItems;
     ListItem_t * configLIST_VOLATILE pxIndex;                   
     MiniListItem_t xListEnd;                                    
     listSECOND_LIST_INTEGRITY_CHECK_VALUE                       
}List_t;

和列表项定义相同,宏listFIRST_LIST_INTEGRITY_CHECK_VALUE和listSECOND_LIST_INTEGRITY_CHECK_VALUE用于检查列表项数据是否完整,在projdefs.h中,如果将宏configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES设置为1,则使能列表项数据完整性检查,则宏listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE和listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE会被两个已知的数值代替。

uxNumberOfItems表示该列表中挂接的列表项数目,0表示列表为空。

列表项类型指针用于遍历列表,列表初始化后,这个指针指向&xListEnd。通过宏listGET_OWNER_OF_NEXT_ENTRY()来获取列表中的下一个列表项。

列表项xListEnd用于标记列表结束。xListEnd.xItemValue被初始化为一个常数,其值与硬件架构相关,为0xFFFF(16位架构)或者0xFFFFFFFF(32位架构)。

下面我们看一下列表操作。FreeROTS提供了几个api函数,用于初始化列表和列表项以及列表项插入操作。

1.初始化列表

列表结构体中包含一个列表项成员,主要用于标记列表结束。初始化列表就是把这个列表项插入到列表中。

void vListInitialise( List_t * const pxList )
{
     
     pxList->pxIndex = ( ListItem_t * )&( pxList->xListEnd );                  
     
     pxList->xListEnd.xItemValue =portMAX_DELAY;
     
     pxList->xListEnd.pxNext = (ListItem_t * ) &( pxList->xListEnd );
     pxList->xListEnd.pxPrevious= ( ListItem_t * ) &( pxList->xListEnd );
     pxList->uxNumberOfItems = ( UBaseType_t) 0U;
      
     listSET_LIST_INTEGRITY_CHECK_1_VALUE(pxList );
     listSET_LIST_INTEGRITY_CHECK_2_VALUE(pxList );
}

如果宏configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES设置为1,则使能列表项数据完整性检查,则宏listSET_LIST_INTEGRITY_CHECK_1_VALUE()和listSET_LIST_INTEGRITY_CHECK_2_VALUE被一个已知值代替,默认为0x5a5a(16位架构)或者0x5a5a5a5a(32位架构)。

假设禁止列表数据完整性检查,初始化后的列表如图1-2所示,uxNumberOfItems被初始化为0,xListEnd.xItemValue初始化为0xffffffff,pxIndex、xListEnd.pxNext和xListEnd.pxPrevious初始化为指向列表项xListEnd。

图1-2:初始化后的列表

2.初始化列表项

列表项的初始比较简单,只要确保列表项不在任何列表中即可。

void vListInitialiseItem( ListItem_t * const pxItem )
{
     pxItem->pvContainer = NULL;
     
     listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE(pxItem );
     listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE(pxItem );
}

如果宏configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES设置为1,则使能列表项数据完整性检查,则宏listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE和listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE会被两个已知的数值代替,默认为0x5a5a(16位架构)或者0x5a5a5a5a(32位架构)。

假设禁止列表项数据完整性检查,初始化后的列表项如图1-3所示。仅是将指针pvContainer设置为空指针,该指针用于指向包含该列表项的列表,这里设置为NULL表示这个列表项不属于任何列表。

图1-3:初始化后的列表项

3.将列表项插入到列表中,列表项所在的位置取决于列表项的列表项值(xItemValue)。

每个列表项对象都有一个列表项值(xItemValue),通常是一个被跟踪的任务优先级或是一个调度事件的计数器值。调用API函数vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem)可以将pxNewListItem指向的列表项插入到pxList指向的列表中,列表项在列表的位置由pxNewListItem->xItemValue决定,按照升序排列。

void vListInsert( List_t * const pxList, ListItem_t * const pxNewListItem )
{
ListItem_t *pxIterator;
const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
         
         listTEST_LIST_INTEGRITY( pxList );
         listTEST_LIST_ITEM_INTEGRITY(pxNewListItem );
         
         if( xValueOfInsertion == portMAX_DELAY)
         {
                   pxIterator =pxList->xListEnd.pxPrevious;
         }
         else
         {
                   for( pxIterator = (ListItem_t * ) &( pxList->xListEnd );pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator =pxIterator->pxNext )
                   {
                            
                   }
         }
         pxNewListItem->pxNext =pxIterator->pxNext;
         pxNewListItem->pxNext->pxPrevious= pxNewListItem;
         pxNewListItem->pxPrevious =pxIterator;
         pxIterator->pxNext = pxNewListItem;
         pxNewListItem->pvContainer = ( void* ) pxList;
         ( pxList->uxNumberOfItems )++;
}

根据xItemValue的值将新的列表项插入到列表。如果列表中存在与新列表项xItemValue值相同的列表项,则新插入的列表项位于它之后。如果列表项的xItemValue值等于portMAX_DELAY(列表结束标记,我们在讲列表数据结构时,说到每个列表数据结构体中都有一个列表项成员xListEnd,用于标记列表结束。xListEnd.xItemValue被初始化为一个常数,其值与硬件架构相关,为0xFFFF或者0xFFFFFFFF。这个常数在移植层定义,即宏portMAX_DELAY),则表示到达了列表结束位置。

我们用图示的方法来讲解这个函数,我们假设一个列表项值(xItemValue)为32的列表项插入到如图1-2所示的初始化后的列表中,调用vListInsert()函数后,列表和列表项的关系如图1-4所示。列表项xListItem_1的成员指针pxNext和pxPrevious都指向了xListEnd,而xListEnd的成员指针pxNext和pxPrevious都指向了列表项xListItem_1;列表项xListItem_1的成员指针pvContainer指向了列表xList_1;列表成员uxNumberOfItems为1。

图1-4:将列表项插入到列表

在此基础上,如果再将一个列表项值(xItemValue)为40的列表项插入到列表中,调用vListInsert()函数后,列表和列表项的关系如图1-5所示。

图1-5:将列表项插入到列表

4.将列表项插入到列表末端

第3节讲的API插入函数是根据列表项中的列表项值(xItemValue)来决定插入位置的,本节所讲的API函数vListInsertEnd()是简单的将列表项插入到列表的末端。在下一章任务创建分析的文章中,将会遇到这个API函数,到时再以图标的形式分析这个函数,现在给出这个函数的源码

void vListInsertEnd( List_t * const pxList, ListItem_t * const pxNewListItem )
{
ListItem_t* const pxIndex = pxList->pxIndex;
         
         listTEST_LIST_INTEGRITY( pxList );
         listTEST_LIST_ITEM_INTEGRITY(pxNewListItem );
         
         pxNewListItem->pxNext = pxIndex;
         pxNewListItem->pxPrevious =pxIndex->pxPrevious;
         mtCOVERAGE_TEST_DELAY();
         pxIndex->pxPrevious->pxNext =pxNewListItem;
         pxIndex->pxPrevious = pxNewListItem;
         pxNewListItem->pvContainer = ( void* ) pxList;
         ( pxList->uxNumberOfItems )++;
}

以上就是FreeRTOS进阶系列列表和列表项示例分析的详细内容,更多关于FreeRTOS进阶列表和列表项的资料请关注编程网其它相关文章!

--结束END--

本文标题: FreeRTOS进阶列表和列表项示例分析

本文链接: https://www.lsjlt.com/news/145376.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • FreeRTOS进阶列表和列表项示例分析
    目录前言1.初始化列表2.初始化列表项4.将列表项插入到列表末端前言 FreeRTOS内核调度大量使用了列表(list)和列表项(list item)数据结构。我们如果想一探Free...
    99+
    2022-11-13
  • FreeRTOS列表和列表项怎么应用
    今天小编给大家分享一下FreeRTOS列表和列表项怎么应用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。前言FreeRTOS...
    99+
    2023-06-29
  • FreeRTOS进阶之队列示例完全解析
    目录前言1.队列创建函数2.入队2.1 xQueueGenericSend()2.2 xQueueGenericSendFromISR ()3.出队前言 FreeRTOS提供了多种任...
    99+
    2022-11-13
  • FreeRTOS实时操作系统的列表与列表项操作示例
    目录前言列表项数据结构列表项初始化列表数据结构将列表项按照升序排列插入到列表将列表项从列表删除    前言 FreeRTOS列表与列表项其实就是链表和节点,在li...
    99+
    2022-11-13
  • Bootstrap列表组的示例分析
    这篇文章主要介绍Bootstrap列表组的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!基础列表组基础列表组,看上去就是去掉了列表符号的列表项,并且配上一些特定的样式。在Bo...
    99+
    2022-10-19
  • python列表解析式的示例分析
    这篇文章给大家分享的是有关python列表解析式的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。列表解析式比如我们有一系列水果的名字,存放在fruit列表里,如果我们希望把列表的内容都改成大写,我们可以有...
    99+
    2023-06-27
  • html有序列表的示例分析
    小编给大家分享一下html有序列表的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!有序列表用数字进行标记。列表始于 <ol> 标签。每个列表项...
    99+
    2023-06-17
  • Redis压缩列表的示例分析
    这篇文章主要介绍了Redis压缩列表的示例分析,具有一定借鉴价值,需要的朋友可以参考下。希望大家阅读完这篇文章后大有收获。下面让小编带着大家一起了解一下。此篇文章是主要介绍Redis在数据存储方面的其中一种...
    99+
    2022-10-18
  • CSS列表属性的示例分析
    这篇文章主要介绍了CSS列表属性的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。 CSS 列表 从某种含意上讲,不是描摹性的文本...
    99+
    2022-10-19
  • Bootstrap中列表组的示例分析
    这篇文章主要介绍了Bootstrap中列表组的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。列表组是Bootstrap框架新增的一个组件,可以用来制作列表清单、垂直导...
    99+
    2023-06-14
  • VB.NET对象列表的示例分析
    小编给大家分享一下VB.NET对象列表的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!第一步步是要创建一个同用列表,你可以从多种途径获取数据,但是最简单的...
    99+
    2023-06-17
  • python列表案例分析
    本篇内容主要讲解“python列表案例分析”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“python列表案例分析”吧!下面要学的是列表:任务1、“千年虫”我来了函数enumerateenumer...
    99+
    2023-06-29
  • HTML中速查列表的示例分析
    这篇文章主要介绍了HTML中速查列表的示例分析,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。HTML 基本文档<!DOCTYPE&nb...
    99+
    2022-10-19
  • python中列表索引的示例分析
    这篇文章给大家分享的是有关python中列表索引的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。Python主要用来做什么Python主要应用于:1、Web开发;2、数据科学研究;3、网络爬虫;4、嵌入式...
    99+
    2023-06-14
  • python列表中缓存的示例分析
    这篇文章将为大家详细讲解有关python列表中缓存的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1、说明当删除一个列表之后,会将该列表中槽位引用的数据项地址全部清空。并且将该列表的引用存放至一个...
    99+
    2023-06-15
  • js中DOM三级列表的示例分析
    这篇文章将为大家详细讲解有关js中DOM三级列表的示例分析,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。效果图:代码如下:<!DOCTYPE HTML&g...
    99+
    2022-10-19
  • splitlines在python中返回列表的示例分析
    这篇文章主要介绍splitlines在python中返回列表的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!1、说明splitlines()方法用于按照换行符(\r、\r\n、\n) 分割,返回一个是否包含换...
    99+
    2023-06-15
  • python列表中数据类型的示例分析
    这篇文章给大家分享的是有关python列表中数据类型的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。python的五大特点是什么python的五大特点:1.简单易学,开发程序时,专注的是解决问题,而不是搞...
    99+
    2023-06-14
  • Python陷阱与缺陷列表的示例分析
    Python陷阱与缺陷列表的示例分析,针对这个问题,这篇文章详细介绍了相对应的分析和解答,希望可以帮助更多想解决这个问题的小伙伴找到更简单易行的方法。我个人对陷阱的定义是这样的:代码看起来可以工作,但不是以你“想当然“”的方式。如果一段代码...
    99+
    2023-06-17
  • Vue列表页渲染优化的示例分析
    小编给大家分享一下Vue列表页渲染优化的示例分析,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!想法初始化时,vue会对data做...
    99+
    2022-10-19
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作