FreeRTOS列表

发布时间:2023年12月26日

一、博主针对列表的理解如下:

(1)列表是 FreeRTOS 中最基本的一种数据结构,其在物理存储单元上是非连续、非顺序的。FreeRTOS 中的列表是一个双向链表。

(2)vListInsertEnd():用于将待插入列表的列表项插入到列表 pxIndex 指针指向列表项的前面(如果pxIndex指向listend,那么也就是将列表项插入到Listend的前面,然后例如我们假设Listend为第一个结点,那么实质就是将列表项插入到链表的最后一个,即我们可以将listend当成头节点,然后? vListInsertEnd()方法就是插入到列表的末尾)

(3)vListInsert():用于将待插入列表的列表项按照列表项值升序排序的顺序,有序地插入到列表

(4)特征1:freertos的链表是一个回环链表,然后listEnd可以看作一个头节点,存储值为MAX,用于排序

(5)特征2:如果listEnd看作一个头节点,ListEnd的pre永远指向链表的最后一个结点,而listEnd的next永远指向链表的第一个结点

(6)?TestList.pxIndex = &ListItem1;如果将列表的pxIndex指向的结点改变,那么vListInsertEnd插入的结点位置不在是listend的前面,而是ListItem1结点的前面,并且pxIndex指向的结点改变,并不会改变之前链表的任何指向关系(包括Listend),但是改变vListInsertEnd插入结点的位置

(7)不可以重复插入同一个列表项,因为他们的地址是相同的,然后如果再次插入之后,链表之间的指向就会混乱,比如l1,l2,l3,他们的值分别是1,2,3,然后我要再次插入l2,此时链表为l1,l2,l2,l3,但是因为l2的地址是一样的,所以l2的next会指向l2,l2的pre也会指向l2,此时链表直接断开

(7)注意:博主此处将listend当作C语言链表中带头结点的链表来处理,方便理解(也可以把Listend当成列表的最后一个结点,因为链表本身就是双向循环列表,所谓的头结点都是为了方便理解)

二、初始化列表,列表项和最小列表项

?

三、验证代码

#include "freeRTOS_demo.h"

#define START_TASK_PRIO         1
#define START_TASK_STACK_SIZE   128
TaskHandle_t    start_task_handler;
void start_task( void * pvParameters );

#define TASK2_PRIO         3
#define TASK2_STACK_SIZE   128
TaskHandle_t    task2_handler;
void task2( void * pvParameters );

List_t          TestList;           /* 定义测试列表 */
ListItem_t      ListItem1;          /* 定义测试列表项1 */
ListItem_t      ListItem2;          /* 定义测试列表项2 */
ListItem_t      ListItem3;          /* 定义测试列表项3 */

void freertos_demo(void)
{    
    xTaskCreate((TaskFunction_t         )   start_task,
                (char *                 )   "start_task",
                (configSTACK_DEPTH_TYPE )   START_TASK_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   START_TASK_PRIO,
                (TaskHandle_t *         )   &start_task_handler );
    vTaskStartScheduler();
}


void start_task( void * pvParameters )
{
    taskENTER_CRITICAL();               /* 进入临界区 */
                
    xTaskCreate((TaskFunction_t         )   task2,
                (char *                 )   "task2",
                (configSTACK_DEPTH_TYPE )   TASK2_STACK_SIZE,
                (void *                 )   NULL,
                (UBaseType_t            )   TASK2_PRIO,
                (TaskHandle_t *         )   &task2_handler );
    vTaskDelete(NULL);
    taskEXIT_CRITICAL();                /* 退出临界区 */
}


void task2( void * pvParameters )
{
	vListInitialise(&TestList);         /* 初始化列表 */
    vListInitialiseItem(&ListItem1);    /* 初始化列表项1 */
    vListInitialiseItem(&ListItem2);    /* 初始化列表项2 */
    vListInitialiseItem(&ListItem3);    /* 初始化列表项3 */
    ListItem1.xItemValue = 40;
    ListItem2.xItemValue = 60;
    ListItem3.xItemValue = 50;

    printf("/**************打印列表和列表项的地址**************/\r\n");
    printf("项目\t\t\t地址\r\n");
    printf("TestList\t\t0x%p\t\r\n", &TestList);
    printf("TestList->pxIndex\t0x%p\t\r\n", TestList.pxIndex);
    printf("TestList->xListEnd\t0x%p\t\r\n", (&TestList.xListEnd));
    printf("ListItem1\t\t0x%p\t\r\n", &ListItem1);
    printf("ListItem2\t\t0x%p\t\r\n", &ListItem2);
    printf("ListItem3\t\t0x%p\t\r\n", &ListItem3);
    printf("/**************************结束***************************/\r\n");
	
	//双向循环链表顺序  listend listItem1 listItem3 listItem2
	vListInsert( (List_t*)&TestList , (ListItem_t*)&ListItem1 );
	vListInsert( (List_t*)&TestList , (ListItem_t*)&ListItem2 );
	vListInsert( (List_t*)&TestList , (ListItem_t*)&ListItem3 );
	
	//双向循环链表顺序  listend listItem1 listItem2
	uxListRemove((ListItem_t*)&ListItem3);
	
	//双向循环链表顺序  listend listItem1 listItem2 listItem3
	vListInsertEnd( (List_t*)&TestList , (ListItem_t* )&ListItem3 );
	
	printf("项目\t\t\t\t地址\r\n");
    printf("TestList->pxIndex\t\t0x%p\r\n", TestList.pxIndex);
    printf("TestList->xListEnd->pxNext\t0x%p\r\n", (TestList.xListEnd.pxNext));
    printf("ListItem1->pxNext\t\t0x%p\r\n", (ListItem1.pxNext));
    printf("ListItem2->pxNext\t\t0x%p\r\n", (ListItem2.pxNext));
    printf("ListItem3->pxNext\t\t0x%p\r\n", (ListItem3.pxNext));
    printf("TestList->xListEnd->pxPrevious\t0x%p\r\n", (TestList.xListEnd.pxPrevious));
    printf("ListItem1->pxPrevious\t\t0x%p\r\n", (ListItem1.pxPrevious));
    printf("ListItem2->pxPrevious\t\t0x%p\r\n", (ListItem2.pxPrevious));
    printf("ListItem3->pxPrevious\t\t0x%p\r\n", (ListItem3.pxPrevious));
    printf("/************************实验结束***************************/\r\n");
    
    while(1)
    {
       
    }
}

?

文章来源:https://blog.csdn.net/m0_61973119/article/details/135208921
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。