FreeRTOS列表与列表项
定义分析
列表
列表是FreeRTOS的数据结构,和链表相似。列表是用来跟踪FreeRTOS的数据任务。
列表项
列表项
链表项就是存放列表中的项目,FreeRTOS中提供了两种列表项:列表项和迷你列表项。
迷你列表项
相关函数
1.列表初始化 vListInitialise(&TestList); // {TestList:列表}
2.列表项初始化 vListInitialiseItem(&ListItem1); // {ListItem1:列表项1}
3.列表项插入 vListInsert(&TestList,&ListItem1); //{向列表TestList中插入列表项1ListItem1}
4.列表项末尾插入 vListInsertEnd(&TestList,&ListItem2); //{向列表TestList尾插入列表项2ListItem2}
5.列表项删除 uxListRemove(&ListItem2); //{ListItem2:列表项2}
6.列表的遍历 listGET_OWNER_OF_NEXT_ENTRY() //{用户不能使用}
实验现象
要求
程序
#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "timer.h"
#include "lcd.h"
#include "key.h"
#include "FreeRTOS.h"
#include "task.h"
//优先级
#define START_TASK_PRIO 1
#define TASK1_TASK_PRIO 2
#define LIST_TASK_PRIO 3
//堆栈大小
#define START_STK_SIZE 128
#define TASK1_STK_SIZE 128
#define LIST_STK_SIZE 128
//任务句柄
TaskHandle_t StartTask_Handler;
TaskHandle_t Task1Task_Handler;
TaskHandle_t ListTask_Handler;
//任务函数
void start_task(void *pvParameters);
void task1_task(void *pvParameters);
void list_task(void *pvParameters);
//定义一个列表和3个列表项
List_t TestList; //列表
ListItem_t ListItem1; //列表项1
ListItem_t ListItem2; //列表项2
ListItem_t ListItem3; //列表项3
int main(void)
{
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//分组4
delay_init(168); //初始化延时函数
uart_init(115200); //串口初始化
LED_Init(); //灯初始化
KEY_Init(); //按键初始化
//开始创建任务
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(); //开启调度器
}
//开始任务函数
void start_task(void *pvParameters)
{
taskENTER_CRITICAL(); //进入临界区
//创建任务1
xTaskCreate((TaskFunction_t )task1_task,
(const char* )"task1_task",
(uint16_t )TASK1_STK_SIZE,
(void* )NULL,
(UBaseType_t )TASK1_TASK_PRIO,
(TaskHandle_t* )&Task1Task_Handler);
//创建列表任务
xTaskCreate((TaskFunction_t )list_task,
(const char* )"list_task",
(uint16_t )LIST_STK_SIZE,
(void* )NULL,
(UBaseType_t )LIST_TASK_PRIO,
(TaskHandle_t* )&ListTask_Handler);
vTaskDelete(StartTask_Handler); //ɾ³ý¿ªÊ¼ÈÎÎñ删除开始任务
taskEXIT_CRITICAL(); //退出临界区
}
//任务1 task1
void task1_task(void *pvParameters)
{
while(1)
{
LED0=!LED0;
vTaskDelay(500); //延时
}
}
//list列表任务
void list_task(void *pvParameters)
{
//第一步:初始化列表和列表项
vListInitialise(&TestList);
vListInitialiseItem(&ListItem1);
vListInitialiseItem(&ListItem2);
vListInitialiseItem(&ListItem3);
ListItem1.xItemValue=40; //ListItem1列表项ª40
ListItem2.xItemValue=60; //ListItem2列表项ª60
ListItem3.xItemValue=50; //ListItem3列表项ª50
//第二步:打印列表和其他列表项地址
printf("/*******************打印列表和其他列表项地址*******************/\r\n");
printf("项目 地址 \r\n");
printf("TestList %#x \r\n",(int)&TestList);
printf("TestList->pxIndex %#x \r\n",(int)TestList.pxIndex);
printf("TestList->xListEnd %#x \r\n",(int)(&TestList.xListEnd));
printf("ListItem1 %#x \r\n",(int)&ListItem1);
printf("ListItem2 %#x \r\n",(int)&ListItem2);
printf("ListItem3 %#x \r\n",(int)&ListItem3);
printf("/************************结束**************************/\r\n");
printf("按下KEY_UP继续\r\n\r\n\r\n");
while(KEY_Scan(0)!=WKUP_PRES) delay_ms(10); //等待KEY_UP按下
//第三步:向TestList添加ListItem1列表项
vListInsert(&TestList,&ListItem1); //添加ListItem1列表项
printf("/******************添加ListItem1列表项*****************/\r\n");
printf("ÏîÄ¿ µØÖ· \r\n");
printf("TestList->xListEnd->pxNext %#x \r\n",(int)(TestList.xListEnd.pxNext));
printf("ListItem1->pxNext %#x \r\n",(int)(ListItem1.pxNext));
printf("/*******************前后分割线********************/\r\n");
printf("TestList->xListEnd->pxPrevious %#x \r\n",(int)(TestList.xListEnd.pxPrevious));
printf("ListItem1->pxPrevious %#x \r\n",(int)(ListItem1.pxPrevious));
printf("/************************结束**************************/\r\n");
printf("按下KEY_UP继续\r\n\r\n\r\n");
while(KEY_Scan(0)!=WKUP_PRES) delay_ms(10); //等待KEY_UP按下
//第四步:向TestList添加ListItem2列表项
vListInsert(&TestList,&ListItem2); //添加ListItem2列表项
printf("/******************添加ListItem2列表项*****************/\r\n");
printf("项目 地址 \r\n");
printf("TestList->xListEnd->pxNext %#x \r\n",(int)(TestList.xListEnd.pxNext));
printf("ListItem1->pxNext %#x \r\n",(int)(ListItem1.pxNext));
printf("ListItem2->pxNext %#x \r\n",(int)(ListItem2.pxNext));
printf("/*******************前后分割线********************/\r\n");
printf("TestList->xListEnd->pxPrevious %#x \r\n",(int)(TestList.xListEnd.pxPrevious));
printf("ListItem1->pxPrevious %#x \r\n",(int)(ListItem1.pxPrevious));
printf("ListItem2->pxPrevious %#x \r\n",(int)(ListItem2.pxPrevious));
printf("/************************结束**************************/\r\n");
printf("按下KEY_UP继续\r\n\r\n\r\n");
while(KEY_Scan(0)!=WKUP_PRES) delay_ms(10); //等待KEY_UP按下
//第五步:向TestList添加ListItem3列表项
vListInsert(&TestList,&ListItem3); //添加ListItem3列表项
printf("/******************添加ListItem3列表项****************/\r\n");
printf("项目 地址 \r\n");
printf("TestList->xListEnd->pxNext %#x \r\n",(int)(TestList.xListEnd.pxNext));
printf("ListItem1->pxNext %#x \r\n",(int)(ListItem1.pxNext));
printf("ListItem3->pxNext %#x \r\n",(int)(ListItem3.pxNext));
printf("ListItem2->pxNext %#x \r\n",(int)(ListItem2.pxNext));
printf("/*******************前后分割线********************/\r\n");
printf("TestList->xListEnd->pxPrevious %#x \r\n",(int)(TestList.xListEnd.pxPrevious));
printf("ListItem1->pxPrevious %#x \r\n",(int)(ListItem1.pxPrevious));
printf("ListItem3->pxPrevious %#x \r\n",(int)(ListItem3.pxPrevious));
printf("ListItem2->pxPrevious %#x \r\n",(int)(ListItem2.pxPrevious));
printf("/************************结束**************************/\r\n");
printf("按下KEY_UP继续\r\n\r\n\r\n");
while(KEY_Scan(0)!=WKUP_PRES) delay_ms(10); //等待KEY_UP按下
//第六步:删除列表项ListItem2
uxListRemove(&ListItem2); //ɾ³ýListItem2
printf("/******************删除列表项ListItem2*****************/\r\n");
printf("项目 地址 \r\n");
printf("TestList->xListEnd->pxNext %#x \r\n",(int)(TestList.xListEnd.pxNext));
printf("ListItem1->pxNext %#x \r\n",(int)(ListItem1.pxNext));
printf("ListItem3->pxNext %#x \r\n",(int)(ListItem3.pxNext));
printf("/********************前后分割线*******************/\r\n");
printf("TestList->xListEnd->pxPrevious %#x \r\n",(int)(TestList.xListEnd.pxPrevious));
printf("ListItem1->pxPrevious %#x \r\n",(int)(ListItem1.pxPrevious));
printf("ListItem3->pxPrevious %#x \r\n",(int)(ListItem3.pxPrevious));
printf("/************************结束**************************/\r\n");
printf("按下KEY_UP继续\r\n\r\n\r\n");
while(KEY_Scan(0)!=WKUP_PRES) delay_ms(10); //等待KEY_UP按下
//第七步:在结尾添加列表项ListItem2
TestList.pxIndex=TestList.pxIndex->pxNext; //在结尾添加列表项ListItem2
vListInsertEnd(&TestList,&ListItem2); //在结尾添加列表项ListItem2
printf("/***************在结尾添加列表项ListItem2***************/\r\n");
printf("ÏîÄ¿ µØÖ· \r\n");
printf("TestList->pxIndex %#x \r\n",(int)TestList.pxIndex);
printf("TestList->xListEnd->pxNext %#x \r\n",(int)(TestList.xListEnd.pxNext));
printf("ListItem2->pxNext %#x \r\n",(int)(ListItem2.pxNext));
printf("ListItem1->pxNext %#x \r\n",(int)(ListItem1.pxNext));
printf("ListItem3->pxNext %#x \r\n",(int)(ListItem3.pxNext));
printf("/*****************前后分割线*******************/\r\n");
printf("TestList->xListEnd->pxPrevious %#x \r\n",(int)(TestList.xListEnd.pxPrevious));
printf("ListItem2->pxPrevious %#x \r\n",(int)(ListItem2.pxPrevious));
printf("ListItem1->pxPrevious %#x \r\n",(int)(ListItem1.pxPrevious));
printf("ListItem3->pxPrevious %#x \r\n",(int)(ListItem3.pxPrevious));
printf("/************************结束**************************/\r\n\r\n\r\n");
while(1)
{
LED1=!LED1;
vTaskDelay(1000);
}
}