FreeRTOS(九)----列表和列表项

目录

列表和列表项的初始化

列表项的插入


列表是 FreeRTOS 中的一个数据结构,概念上和链表有点类似,列表被用来跟踪 FreeRTOS 中的任务。与列表相关的全部东西都在文件 list.c 和 list.h 中。在 list.h 中定义了一个叫 List_t 的结构体,如下:

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

                                               

 

列表项就是存放在列表中的项目,FreeRTOS 提供了两种列表项:列表项迷你列表项。这两个都在文件 list.h 中有定义,先来看一下列表项,定义如下:

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           pvContainer;
    listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE_VOLATILE
};
typedef struct  xLIST_ITEM	ListItem_t
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;

 

  • 列表和列表项初始化

列表的初始化其实就是初始化列表结构体List_t 中的各个成员变量,列表的初始化通过使函数 vListInitialise()来完成,此函数在 list.c 中有定义,函数如下:

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 );
}

列表项初始化由函数 vListInitialiseItem()来完成,函数如下:

void vListInitialiseItem( ListItem_t * const pxItem )
{
    pxItem->pvContainer = NULL;    //初始化pvContainer 为 NULL
    
    //初始化用于完整性检查的变量,如果开启了这个功能的话。
    listSET_FIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );             
    listSET_SECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE( pxItem );
}

​​​​

  • 列表项插入

列表项的插入操作通过函数 vListInsert()来完成,函数原型如下:

void vListInsert( List_t * const   pxList,ListItem_t * const   pxNewListItem )

通过图片来演示一下这个插入过程,向一个空的列表中插入三个列表项,这三个列表项的值分别为 40,60 和 50。

 

  • 插入与删除实验

本实验设计 3 个任务:start_task、task1_task 和 list_task,这三个任务的任务功能如下:

start_task:  用来创建其他 2 个任务。

task1_task:应用任务 1,控制 LED0 闪烁,用来提示系统正在运行。

task2_task:  列表和列表项操作任务,调用列表和列表项相关的 API 函数,并且通过串口输出相应的信息来观察这些 API 函数的运行过程。

 

任务优先级、堆栈大小和任务句柄等的设置:

#define START_TASK_PRIO	  1	         //任务优先级
#define START_STK_SIZE    128	     //任务堆栈大小
TaskHandle_t StartTask_Handler;      //任务句柄
void start_task(void *pvParameters); //任务函数	

#define TASK1_TASK_PRIO	  2	         //任务优先级
#define TASK1_STK_SIZE    128	     //任务堆栈大小
TaskHandle_t Task1Task_Handler;      //任务句柄
void task1_task(void *pvParameters); //任务函数	


#define LIST_TASK_PRIO	  3	         //任务优先级
#define LIST_STK_SIZE	  128	     //任务堆栈大小
TaskHandle_t ListTask_Handler;		 //任务句柄
void list_task(void *pvParameters);  //任务函数

 

列表和列表项的定义:

 

main函数:

int main(void)
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组 4         
    delay_init(168);	//初始化延时函数
    uart_init(115200);	//初始化串口
    LED_Init();	//初始化 LED 端口
    KEY_Init();	//初始化按键
    LCD_Init();	//初始化 LCD

    POINT_COLOR = RED; LCD_ShowString(30,10,200,16,16,"ATK STM32F103/407");
    LCD_ShowString(30,30,200,16,16,"FreeRTOS Examp 7-1");                 
    LCD_ShowString(30,50,200,16,16,"list and listItem");     
    LCD_ShowString(30,70,200,16,16,"ATOM@ALIENTEK");     
    LCD_ShowString(30,90,200,16,16,"2016/11/25");
    
    //创建开始任务		
    xTaskCreate((TaskFunction_t	)start_task,	//任务函数
    (const char*	)"start_task",	//任务名称
    (uint16_t	)START_STK_SIZE,	//任务堆栈大小
    (void*	)NULL,	//传递给任务函数的参数
    (UBaseType_t	)START_TASK_PRIO,	//任务优先级
    (TaskHandle_t*	)&StartTask_Handler);	//任务句柄
    vTaskStartScheduler();		//开启任务调度
}

 

验证:

  1. 列表 TestList 地址为 b4。
  2. 列表项 ListItem1、ListItem2 和 ListItem3 的地址分别为 c8、dc 和 f0
  3. 列表 TestList 的xListEnd 地址为 bc。
  4. 列表 TestList 的pxIndex 指向地址 bc,而这个地址正是迷你列表项 xListEnd,说明 pxIndex指向 xListEnd,这个和我们分析列表初始化函数 vListInitialise()的时候得到的结果是一致的。

 

   

  1. xListEnd 的 pxNext 指向地址 c8,而 c8 是 ListItem1 的地址,说明 xListEnd 的 pxNext 指向 ListItem1。
  2. 列表项 ListItem1 的 pxNext 指向地址 bc,而 bc 是 xListEnd 的地址,说明 ListItem1 的pxNext 指向xListEnd。
  3. xListEnd 的pxPrevious 指向地址c8,而 c8 是ListItem1 的地址,说明 xListEnd 的pxPrevious指向 ListItem2。
  4. ListItem1 的 pxPrevious 指向地址 bc,bc 是xListEnd 的地址,说明 ListItem1 的 pxPrevious指向 xListEnd。

 

       

  1. xListEnd 的 pxNext 指向 ListItem1。
  2. ListItem1 的 pxNext 指向 ListItem2。
  3. ListItem2 的 pxNext 指向 xListEnd。
  4. 列表项的 pxPrevious 分析过程类似,后面的步骤中就不做分析了,只看 pxNext 成员变量。

 

     

  1. xListEnd 的 pxNext 指向 ListItem1。
  2. ListItem1 的 pxNext 指向 ListItem3。
  3. ListItem3 的 pxNext 指向 ListItem2。
  4. ListItem2 的 pxNext 指向 xListEnd。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值