6、FreeRTOS - 列表、列表项、任务控制块TCB

在网上学习 FreeRTOS 列表后做的一些笔记和总结,仅供学习交流。


目录

列表简介

列表的定义

列表项的定义

迷你列表项的定义

列表、列表项、迷你列表项、TCB 之间的关系


列表简介

FreeRTOS 中任务有多种状态:就绪态、运行态、阻塞态、挂起态。当存在多个任务都处于某个状态时,为了方便处理这些任务,会把这些任务组成一个列表。

 

列表,是 FreeRTOS 系统创建的一个结构体(底层是一个数据结构,跟链表有点类似,可以把列表看成链表中的链表头,不过链表头一般只存放下一个结构体地址,而列表存放着更多的信息),由多个相同状态的任务(以列表项的形式存放)组成(列表内的指针指向多个列表项),用于对任务的跟踪和处理。

列表分为三大类:

就绪列表

阻塞列表

挂起列表

任务的每一种状态都会有一个列表,就绪态的任务就有一个列表项位于就绪列表中。

为什么运行态没有列表?

因为每次只有一个任务是运行态,所以根本不需要列表。


列表的定义

typedef struct xLIST
{
    	listFIRST_LIST_INTEGRITY_CHECK_VALUE			/* 校验值 */
    	volatile UBaseType_t uxNumberOfItems;			/* 列表中的列表项数量 */
   	    ListItem_t * configLIST_VOLATILE pxIndex		/* 用于遍历列表项的指针 */
    	MiniListItem_t xListEnd					        /* 末尾列表项 */
    	listSECOND_LIST_INTEGRITY_CHECK_VALUE		    /* 校验值 */
} List_t;

1)listFIRST_LIST_INTEGRITY_CHECK_VALUE、listSECOND_LIST_INTEGRITY_CHECK_VALUE:

这两个宏是确定的已知常量, FreeRTOS 通过检查这两个常量的值,来判断列表的数据在程序运行过程中,是否遭到破坏 ,该功能一般用于调试, 默认是不开启的。

 

2)uxNumberOfItems:用于记录列表中列表项的个数(不包含 xListEnd)。

 

3)pxIndex:指向列表中的某个列表项,一般用于遍历列表中的所有列表项。

 

4)xListEnd:末尾列表项(或迷你列表项),排在列表项的最末尾,表示列表的结束位置,给其他列表项起到一个定位的作用。


列表项的定义

typedef 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							            /* 列表项的拥有者 */
    	struct xLIST * configLIST_VOLATILE pxContainer; 	/* 列表项所在列表 */
   	    listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE			/* 用于检测列表项的数据完整性 */
} ListItem_t; 	

1)xItemValue:列表项的值,这个值多用于按升序对列表中的列表项进行排序。

 

2)pxNext 和 pxPrevious:分别用于指向列表中列表项的下一个列表项和上一个列表项。

 

3)pxOwner:指向拥有该列表项的对象。通常是指向任务控制块,每个任务都有属于自己的任务控制块,里面一般就有一个列表项。

 

任务控制块(简称 TCB,是一个结构体)是任务的身份证,每个任务都有一个属于自己的 TCB,里面存有任务的所有信息,比如任务的状态、任务的优先级、任务的栈指针、任务名称、任务的形参等。TCB 里面存放的信息是提供给系统使用的,系统对这个任务的所有操作,都是通过这个任务控制块里面存放的信息来实现的,比如根据优先级进行任务切换等等。

 

4)pxContainer:指向列表项所在列表,例如就绪列表。列表项都是一个个独立的结构体,如果不用指针指向,根本不知道这个结构体跟列表有什么关系。

每个列表项对应一个任务。


迷你列表项的定义

typedef 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; 	/* 下一个列表项 */
} MiniListItem_t;

1)xItemValue:列表项的值,这个值多用于按升序对列表中的列表项进行排序。

 

2)pxNext 和 pxPrevious:分别用于指向列表中列表项的下一个列表项和上一个列表项。

迷你列表项,又称末尾列表项,只用于标记列表的末尾和挂载其他插入列表中的列表项,因此不需要成员变量 pxOwner 和 pxContainer,以节省内存开销。


列表、列表项、迷你列表项、TCB 之间的关系

c80674d228e04ce5bc168c82c5165a97.png

从图中可以看出,多个列表项组成了一个双向链表,列表中指向该双向链表中任意一个列表项和末尾列表项,因为列表的任意指向列表项这个特性,所以只要有列表,就可以实现列表项的增删查改功能,从任意位置中插入或删除列表项,查询或修改任意位置的列表项。

 

列表项间的地址非连续的,是人为的连接到一起的。列表项的数目是由后期添加的个数决定的,随时可以改变。在操作系统中任务的数量是不确定的,随时都有可能加任务或者删任务,并且任务状态是会发生改变的(例如就绪态的任务变成阻塞态,就会从就绪列表转移到阻塞列表),所以非常适用列表(即链表)这种数据结构,才用列表的方式去处理数据。

添加列表项的过程图示:

列表刚被创建时,只有三个初始成员:uxNumberOfItems、*pxIndex、xLiseEnd (末尾列表项)。末尾列表项的作用就类似于坐标,作为其他列表项的坐标,让它们来挂载连接,这样才能变成链表,如下

cdb05895cf884f259301c25927424ffc.png

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值