FreeRTOS列表

目录:

一:列表、列表项、迷你列表项结构
二:列表和列表项的初始化
三:列表项插入
四:列表项遍历
五:列表项末尾插入
六:列表项删除

一:列表、列表项、迷你列表项结构

//列表
166 typedef struct xLIST
167 {
168     listFIRST_LIST_INTEGRITY_CHECK_VALUE          //检查列表完整性
169     volatile UBaseType_t uxNumberOfItems;            //列表项数量
170     ListItem_t * configLIST_VOLATILE pxIndex;        //遍历列表时当前列表项的指针
171     MiniListItem_t xListEnd;                      /*< 包含最大可能项值的列表项,这意味着它始终位于列表的末尾,因此用作标记。 */                
172     listSECOND_LIST_INTEGRITY_CHECK_VALUE         //检查列表完整性
173 } List_t;
列表示意图
//列表项
142 struct xLIST_ITEM
143 {
144     listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE              
145     configLIST_VOLATILE TickType_t xItemValue;              /*列表项值 */
146     struct xLIST_ITEM * configLIST_VOLATILE pxNext;         /*指向下一个列表项的指针 */
147     struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;     /* 指向上一个列表项的指针*/
148     void * pvOwner;                                         /*所属任务 */
149     struct xLIST * configLIST_VOLATILE pxContainer;         /*所属列表 */
150     listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE              
151 };
152 typedef struct xLIST_ITEM ListItem_t; 
列表项示意图
//迷你列表项
154 struct xMINI_LIST_ITEM
155 {
156     listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE     
157     configLIST_VOLATILE TickType_t xItemValue;
158     struct xLIST_ITEM * configLIST_VOLATILE pxNext;
159     struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;
160 };
161 typedef struct xMINI_LIST_ITEM MiniListItem_t;

二:列表和列表项的初始化

//列表初始化
 48 void vListInitialise( List_t * const pxList )
 49 {
 53     pxList->pxIndex = ( ListItem_t * ) &( pxList->xListEnd ); /*将列表项索引指向迷你列表项 */
 54 
 55     /* 列表结尾值是列表中可能的最高值,以确保它保持在列表的末尾。*/
 57     pxList->xListEnd.xItemValue = portMAX_DELAY;
 58 
 59     /* 当列表为空时,迷你列表项的pxNext、pxPrevious指针指向自己*/
 61     pxList->xListEnd.pxNext = ( ListItem_t * ) &( pxList->xListEnd );    
 62     pxList->xListEnd.pxPrevious = ( ListItem_t * ) &( pxList->xListEnd ); 
 63 
 64     pxList->uxNumberOfItems = ( UBaseType_t ) 0U;
 65 
 68     listSET_LIST_INTEGRITY_CHECK_1_VALUE( pxList );
 69     listSET_LIST_INTEGRITY_CHECK_2_VALUE( pxList );
 70 }
列表初始化
//列表项初始化
 73 void vListInitialiseItem( ListItem_t * const pxItem )
 74 {
 75     /* 确保列表项没有被记录在列表中 */
 76     pxItem->pxContainer = NULL;
 77 
 80     listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
 81     listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
 82 }
列表项初始化

三:列表项插入

//
115 void vListInsert( List_t * const pxList,                                                                                                                                                                       
116                   ListItem_t * const pxNewListItem )
117 {
118     ListItem_t * pxIterator;
119     const TickType_t xValueOfInsertion = pxNewListItem->xItemValue;
120 
121     /*检查列表和列表项数据的完整性,仅当configASSERT()定义时有效。*/
124     listTEST_LIST_INTEGRITY( pxList );
125     listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
126 
127     /*将新的列表项插入到列表,根据xItemValue的值升序插入列表*/
135     if( xValueOfInsertion == portMAX_DELAY )
136     {   //若值等于最大值,将其之间插入到末尾
137         pxIterator = pxList->xListEnd.pxPrevious;
138     }
139     else
140     {   //若值不等于最大值,寻找插入位置
163         for( pxIterator = ( ListItem_t * ) &( pxList->xListEnd ); pxIterator->pxNext->xItemValue <= xValueOfInsertion; pxIterator = pxIterator->pxNext ) /*将待插入列表项的值依次(按从前往后的顺序)与已插入的列表项的值作比较,当比较时待插入列表项的值较小时,插入位置确定 */
164         {
165             /*空 */
167         }
168     }
169 
170     pxNewListItem->pxNext = pxIterator->pxNext;
171     pxNewListItem->pxNext->pxPrevious = pxNewListItem;
172     pxNewListItem->pxPrevious = pxIterator;
173     pxIterator->pxNext = pxNewListItem;
174 
175     /*记录列表项所属列表*/
177     pxNewListItem->pxContainer = pxList;
178 
179     ( pxList->uxNumberOfItems )++;
180 }
11.jpg

for循环结束时pxIterator指向职位50的列表项,此时执行170-173行代码,确定值为60的列表项在列表中的顺序。

四:列表项遍历

279 #define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList )                                          
280     {                                                                                          
281         List_t * const pxConstList = ( pxList );            // pxList 表示要遍历的列表                                  
282                              
284         ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;     //将pxIndex指向下一个列表项                  
285         if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) )   
286         {    //因为xListEnd不是列表项,若pxIndex指向xListEnd,则将其重新指向处于列表头的列表项                                                                                  
287             ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;                   
288         }                                                                                      
289         ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner;                                        
290     }

此函数用于从多个同优先级的就绪任务中查找下一个要运行的任务。

五:列表项末尾插入

 85 void vListInsertEnd( List_t * const pxList,
 86                      ListItem_t * const pxNewListItem )
 87 {
 88     ListItem_t * const pxIndex = pxList->pxIndex;
 89 
 90     /*完成对列表和列表项的完整性检查*/
 93     listTEST_LIST_INTEGRITY( pxList );
 94     listTEST_LIST_ITEM_INTEGRITY( pxNewListItem );
 95 
 96     /* 这里所谓的末尾要根据列表的成员变量pxIndex 来确定的! 前面说了列表中的 pxIndex 成员变量是用来遍历列表的, pxIndex 所指向的列表项就是要遍历的开始列表项,也就是说 pxIndex 所指向的列表项就代表列表头! 由于是个环形列表,所以新的列表项就应该插入到 pxIndex 所指向的列表项的前面。 */
 99     pxNewListItem->pxNext = pxIndex;
100     pxNewListItem->pxPrevious = pxIndex->pxPrevious;
101 
102     /* Only used during decision coverage testing. */
103     mtCOVERAGE_TEST_DELAY();
104 
105     pxIndex->pxPrevious->pxNext = pxNewListItem;
106     pxIndex->pxPrevious = pxNewListItem;
107 
108     /* Remember which list the item is in. */
109     pxNewListItem->pxContainer = pxList;
110 
111     ( pxList->uxNumberOfItems )++;
112 }

插入到 pxIndex 所指向的列表项的前面

六:列表项删除

183 UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )
184 {
185 /* The list item knows which list it is in.  Obtain the list from the list
186  * item. */
187     List_t * const pxList = pxItemToRemove->pxContainer;
188 
189     pxItemToRemove->pxNext->pxPrevious = pxItemToRemove->pxPrevious;
190     pxItemToRemove->pxPrevious->pxNext = pxItemToRemove->pxNext;
191 
192     /* Only used during decision coverage testing. */
193     mtCOVERAGE_TEST_DELAY();
194 
195     /* Make sure the index is left pointing to a valid item. */
196     if( pxList->pxIndex == pxItemToRemove )
197     {
198         pxList->pxIndex = pxItemToRemove->pxPrevious;
199     }
200     else
201     {
202         mtCOVERAGE_TEST_MARKER();
203     }
204 
205     pxItemToRemove->pxContainer = NULL;
206     ( pxList->uxNumberOfItems )--;
207 
208     return pxList->uxNumberOfItems;
209 }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,911评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,014评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,129评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,283评论 1 264
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,159评论 4 357
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,161评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,565评论 3 382
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,251评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,531评论 1 292
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,619评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,383评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,255评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,624评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,916评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,199评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,553评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,756评论 2 335