列表就像双向链表,里面的列表项双向连接
列表结构体List_t:
a.uxNumberOfItems 列表项的数目
b.pxIndex 指针,指向列表中的某一项,方便函数API使用
c.xListEnd 列表最末尾
列表项结构体ListItem_t:
a.xItemValue 列表项的值
b.pxNext 指向下一个列表项
c.pxPrevious 指向上一个列表项
d.pvOwner 指向列表项拥有者->任务控制块
e.pxContainer 所在列表(就绪列表,阻塞列表,挂起列表)
mini列表项结构体MiniListItem_t(标记末尾和其他插入的列表项):
a.xItemValue 列表项的值
b.pxNext 指向下一个列表项
c.pxPrevious 指向上一个列表项
列表相关API
初始化列表 vListInitialise
(
List_t
*
const
pxList
) 参数:待初始化列表
初始化列表项 vListInitialiseItem
(
ListItem_t
*
const
pxItem
) 参数:带初始化列表项
列表末尾插入列表项 vListInsertEnd(List_t * const pxList,ListItem_t * const pxNewListItem)
(有序) 参数:列表,待插入列表项
列表插入列表项 vListInsert(List_t * const pxList,ListItem_t * const pxNewListItem)
(无序) 参数:列表,待插入列表项
列表移除列表项 uxListRemove
(
ListItem_t
*
const
pxItemToRemove
)
参数:待移除列表项
返回值:移除后列表项剩余数量
freertos_demo代码
//freertos_demo.c
#include "freertos_demo.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
#include "./SYSTEM/delay/delay.h"
/*FreeRTOS*********************************************************************************************/
#include "FreeRTOS.h"
#include "task.h"
/******************************************************************************************************/
/*FreeRTOS配置*/
/* START_TASK 任务 配置
* 包括: 任务句柄 任务优先级 堆栈大小 创建任务
*/
#define START_TASK_PRIO 1
#define START_TASK_STACK_SIZE 128
TaskHandle_t start_task_handler;
void start_task(void * pvParameters);
/* TASK1 任务 配置
* 包括: 任务句柄 任务优先级 堆栈大小 创建任务
*/
#define TASK1_PRIO 2
#define TASK1_STACK_SIZE 128
TaskHandle_t task1_handler;
void task1(void* pv);
/* TASK2 任务 配置
* 包括: 任务句柄 任务优先级 堆栈大小 创建任务
*/
#define TASK2_PRIO 3
#define TASK2_STACK_SIZE 128
TaskHandle_t task2_handler;
void task2(void* pv);
/******************************************************************************************************/
List_t TestList; //定义测试列表
ListItem_t ListItem1; //定义测试列表项1
ListItem_t ListItem2; //定义测试列表项2
ListItem_t ListItem3; //定义测试列表项3
/**
* @brief FreeRTOS例程入口函数
* @param 无
* @retval 无
*/
void freertos_demo(void)
{
xTaskCreate((TaskFunction_t ) start_task, //创建开始任务
(char* ) "start_task",
(unsigned portSHORT) START_TASK_STACK_SIZE,
(void * ) NULL,
(portBASE_TYPE ) START_TASK_PRIO,
(TaskHandle_t* ) &start_task_handler );
vTaskStartScheduler(); //启动任务调度器
}
void start_task(void* pvPara)
{
taskENTER_CRITICAL(); //进入临界区
xTaskCreate((TaskFunction_t ) task1, //创建任务一
(char* ) "task1",
(unsigned portSHORT) TASK1_STACK_SIZE,
(void * ) NULL,
(portBASE_TYPE ) TASK1_PRIO,
(TaskHandle_t* ) &task1_handler );
xTaskCreate((TaskFunction_t ) task2, //创建任务二
(char* ) "task2",
(unsigned portSHORT) TASK2_STACK_SIZE,
(void * ) NULL,
(portBASE_TYPE ) TASK2_PRIO,
(TaskHandle_t* ) &task2_handler );
vTaskDelete(NULL); //删除start_task任务
taskEXIT_CRITICAL(); //退出临界区
}
//任务一 实现LED每500ms翻转一次
void task1(void* pv)
{
while(1)
{
LED0_TOGGLE(); //翻转LED0电平
vTaskDelay(500);
}
}
//任务二 实现列表先插入删除实验
void task2(void* pv)
{
vListInitialise( &TestList ); //初始化列表
vListInitialiseItem( &ListItem1 ); //初始化列表项1
vListInitialiseItem( &ListItem2 ); //初始化列表项2
vListInitialiseItem( &ListItem3 ); //初始化列表项3
ListItem1.xItemValue = 40; //定义列表项的值
ListItem2.xItemValue = 60;
ListItem3.xItemValue = 50;
vTaskDelay(10000);
/* 第二步:打印列表和其他列表项的地址 */
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");
/* 第三步:列表项1插入列表 */
printf("\r\n/*****************第三步:列表项1插入列表******************/\r\n");
vListInsert((List_t* )&TestList, /* 列表 */
(ListItem_t*)&ListItem1); /* 列表项 */
printf("项目\t\t\t\t地址\r\n");
printf("TestList->xListEnd->pxNext\t0x%p\r\n", (TestList.xListEnd.pxNext));
printf("ListItem1->pxNext\t\t0x%p\r\n", (ListItem1.pxNext));
printf("TestList->xListEnd->pxPrevious\t0x%p\r\n", (TestList.xListEnd.pxPrevious));
printf("ListItem1->pxPrevious\t\t0x%p\r\n", (ListItem1.pxPrevious));
printf("/**************************结束***************************/\r\n");
/* 第四步:列表项2插入列表 */
printf("\r\n/*****************第四步:列表项2插入列表******************/\r\n");
vListInsert((List_t* )&TestList, /* 列表 */
(ListItem_t*)&ListItem2); /* 列表项 */
printf("项目\t\t\t\t地址\r\n");
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("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("/**************************结束***************************/\r\n");
/* 第五步:列表项3插入列表 */
printf("\r\n/*****************第五步:列表项3插入列表******************/\r\n");
vListInsert((List_t* )&TestList, /* 列表 */
(ListItem_t*)&ListItem3); /* 列表项 */
printf("项目\t\t\t\t地址\r\n");
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");
/* 第六步:移除列表项2 */
printf("\r\n/*******************第六步:移除列表项2********************/\r\n");
uxListRemove((ListItem_t* )&ListItem2); /* 移除列表项 */
printf("项目\t\t\t\t地址\r\n");
printf("TestList->xListEnd->pxNext\t0x%p\r\n", (TestList.xListEnd.pxNext));
printf("ListItem1->pxNext\t\t0x%p\r\n", (ListItem1.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("ListItem3->pxPrevious\t\t0x%p\r\n", (ListItem3.pxPrevious));
printf("/**************************结束***************************/\r\n");
/* 第七步:列表末尾添加列表项2 */
printf("\r\n/****************第七步:列表末尾添加列表项2****************/\r\n");
TestList.pxIndex = &ListItem1;
vListInsertEnd((List_t* )&TestList, /* 列表 */
(ListItem_t* )&ListItem2); /* 列表项 */
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)
{
vTaskDelay(1000);
}
}
//freertos_demo.h
#ifndef __FREERTOS_DEMO_H
#define __FREERTOS_DEMO_H
void freertos_demo(void);
#endif
main.c
#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/usart/usart.h"
#include "./SYSTEM/delay/delay.h"
#include "./BSP/LED/led.h"
#include "./BSP/LCD/lcd.h"
#include "./BSP/KEY/key.h"
#include "./BSP/SRAM/sram.h"
#include "./MALLOC/malloc.h"
#include "freertos_demo.h"
#include "./BSP/TIMER/btim.h"
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(336, 8, 2, 7); /* 设置时钟,168Mhz */
delay_init(168); /* 延时初始化 */
usart_init(115200); /* 串口初始化为115200 */
led_init(); /* 初始化LED */
lcd_init(); /* 初始化LCD */
key_init(); /* 初始化按键 */
sram_init(); /* SRAM初始化 */
my_mem_init(SRAMIN); /* 初始化内部SRAM内存池 */
my_mem_init(SRAMEX); /* 初始化外部SRAM内存池 */
my_mem_init(SRAMCCM); /* 初始化内部CCM内存池 */
freertos_demo();
}