一:理论基础
二:列表项的插入和删除实际操作
1、实验目的:观察插入列表项、移除列表项的地址变化情况。具体的函数、结构体可以在list.c,list.h中找到。
2、在动态任务代码的基础上修改main.c文件,代码如下 :
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "LED.h"
#include "Key.h"
#include "OLED.h"
#include "Serial.h"
#include "FreeRTOS.h"
#include "task.h"
List_t TestList; /*定义测试列表*/
ListItem_t ListItem1; /*定义测试列表项1*/
ListItem_t ListItem2; /*定义测试列表项2*/
ListItem_t ListItem3; /*定义测试列表项3*/
#define START_STK_DEPTH 64
#define START_TASK_PRIO 1
TaskHandle_t start_task_handler;
void start_task(void * pvParameters);
#define LED2_STK_DEPTH 64
#define LED2_TASK_PRIO 2
TaskHandle_t led2_task_handler;
void led2_task(char * pvParameters);
#define LED3_STK_DEPTH 64
#define LED3_TASK_PRIO 3
TaskHandle_t led3_task_handler;
void led3_task(char * pvParameters);
#define Stop_LED2_STK_DEPTH 64
#define Stop_LED2_TASK_PRIO 4
TaskHandle_t stop_LED2_task_handler;
void stop_LED2_task(char * pvParameters);
int main(void)
{
LED_Init();
Serial_Init();
xTaskCreate( (TaskFunction_t) start_task, //创建开始任务
(const char * ) "start_task",
(uint16_t ) START_STK_DEPTH,
(void * ) NULL,
(UBaseType_t ) START_TASK_PRIO,
(TaskHandle_t *) &start_task_handler);
vTaskStartScheduler(); //开启任务调度器
}
/*******开始任务函数*****/
void start_task(void * pvParameters)
{
taskENTER_CRITICAL();
xTaskCreate((TaskFunction_t) led2_task,
(const char * ) "led2_task",
(uint16_t ) LED2_STK_DEPTH,
(void * ) NULL,
(UBaseType_t ) LED2_TASK_PRIO,
(TaskHandle_t *) &led2_task_handler);
xTaskCreate((TaskFunction_t) led3_task,
(const char * ) "led3_task",
(uint16_t ) LED3_STK_DEPTH,
(void * ) NULL,
(UBaseType_t ) LED3_TASK_PRIO,
(TaskHandle_t *) &led3_task_handler);
xTaskCreate((TaskFunction_t) stop_LED2_task,
(const char * ) "stop_LED2_task",
(uint16_t ) Stop_LED2_STK_DEPTH,
(void * ) NULL,
(UBaseType_t ) Stop_LED2_TASK_PRIO,
(TaskHandle_t *) &stop_LED2_task_handler);
vTaskDelete(start_task_handler);
taskEXIT_CRITICAL();
}
void led2_task(char * pvParameters)
{
for(;;)
{
Serial_Printf("LED2_task\r\n");
LED1_Turn();
vTaskDelay(333);
}
}
void led3_task(char * pvParameters)
{
for(;;)
{
Serial_Printf("LED3_task\r\n");
LED2_Turn();
vTaskDelay(500);
}
}
void stop_LED2_task(char * pvParameters)
{
vListInitialise((List_t* )&TestList); /*初始化列表*/
vListInitialiseItem((ListItem_t* )&ListItem1); /*初始化列表项1*/
vListInitialiseItem((ListItem_t* )&ListItem2); /*初始化列表项2*/
vListInitialiseItem((ListItem_t* )&ListItem3); /*初始化列表项3*/
ListItem1.xItemValue=40;
ListItem1.xItemValue=60;
ListItem1.xItemValue=50;
/*打印列表和列表项地址*/
/*
printf("ListItem1->pxNext\t\t0x%p\r\n", (ListItem1.pxNext));
这段代码输出的是一个指针变量 ListItem1 的成员变量 pxNext 的地址。
pxNext 是一个指针类型,它指向链表中的下一个节点。
在这里,%p 是输出指针地址的格式控制符,0x 是输出地址前缀。
*/
Serial_Printf("/**************打印列表和列表项地址*********/\r\n");
Serial_Printf("项目\t\t\t地址\r\n");
Serial_Printf("TestList\t\t0x%p\t\r\n", &TestList);
Serial_Printf("TestList->pxIndex\t0x%p\t\r\n", TestList.pxIndex);
Serial_Printf("TestList->xListEnd\t0x%p\t\r\n", (&TestList.xListEnd));
Serial_Printf("ListItem1\t\t0x%p\t\r\n", &ListItem1);
Serial_Printf("ListItem2\t\t0x%p\t\r\n", &ListItem2);
Serial_Printf("ListItem3\t\t0x%p\t\r\n", &ListItem3);
Serial_Printf("/**************************结束˸***************************/\r\n");
Serial_Printf("\r\n/*****************֚插入列表项1******************/\r\n");
vListInsert((List_t* )&TestList,
(ListItem_t*)&ListItem1);
Serial_Printf("项目\t\t\t地址\r\n");
Serial_Printf("TestList->xListEnd->pxNext\t0x%p\r\n", (TestList.xListEnd.pxNext));
Serial_Printf("ListItem1->pxNext\t\t0x%p\r\n", (ListItem1.pxNext));
Serial_Printf("TestList->xListEnd->pxPrevious\t0x%p\r\n", (TestList.xListEnd.pxPrevious));
Serial_Printf("ListItem1->pxPrevious\t\t0x%p\r\n", (ListItem1.pxPrevious));
Serial_Printf("/**************************结束***************************/\r\n");
Serial_Printf("\r\n/*****************֚插入列表项2******************/\r\n");
vListInsert((List_t* )&TestList,
(ListItem_t*)&ListItem2);
Serial_Printf("项目\t\t\t地址\r\n");
Serial_Printf("TestList->xListEnd->pxNext\t0x%p\r\n", (TestList.xListEnd.pxNext));
Serial_Printf("ListItem2->pxNext\t\t0x%p\r\n", (ListItem2.pxNext));
Serial_Printf("TestList->xListEnd->pxPrevious\t0x%p\r\n", (TestList.xListEnd.pxPrevious));
Serial_Printf("ListItem2->pxPrevious\t\t0x%p\r\n", (ListItem2.pxPrevious));
Serial_Printf("/**************************结束***************************/\r\n");
Serial_Printf("\r\n/*****************֚插入列表项3******************/\r\n");
vListInsert((List_t* )&TestList,
(ListItem_t*)&ListItem3);
Serial_Printf("项目\t\t\t地址\r\n");
Serial_Printf("TestList->xListEnd->pxNext\t0x%p\r\n", (TestList.xListEnd.pxNext));
Serial_Printf("ListItem3->pxNext\t\t0x%p\r\n", (ListItem3.pxNext));
Serial_Printf("TestList->xListEnd->pxPrevious\t0x%p\r\n", (TestList.xListEnd.pxPrevious));
Serial_Printf("ListItem3->pxPrevious\t\t0x%p\r\n", (ListItem3.pxPrevious));
Serial_Printf("/**************************结束***************************/\r\n");
Serial_Printf("\r\n/*******************֚移除列表项2********************/\r\n");
uxListRemove((ListItem_t* )&ListItem2);
Serial_Printf("项目\t\t\t地址\r\n");
Serial_Printf("TestList->xListEnd->pxNext\t0x%p\r\n", (TestList.xListEnd.pxNext));
Serial_Printf("ListItem1->pxNext\t\t0x%p\r\n", (ListItem1.pxNext));
Serial_Printf("ListItem3->pxNext\t\t0x%p\r\n", (ListItem3.pxNext));
Serial_Printf("TestList->xListEnd->pxPrevious\t0x%p\r\n", (TestList.xListEnd.pxPrevious));
Serial_Printf("ListItem1->pxPrevious\t\t0x%p\r\n", (ListItem1.pxPrevious));
Serial_Printf("ListItem3->pxPrevious\t\t0x%p\r\n", (ListItem3.pxPrevious));
printf("/**************************结束***************************/\r\n");
Serial_Printf("\r\n/*******************֚插入末尾列表项2********************/\r\n");
vListInsertEnd((List_t* )&TestList,
(ListItem_t* )&ListItem2);
Serial_Printf("项目\t\t\t地址\r\n");
Serial_Printf("TestList->pxIndex\t\t0x%p\r\n", TestList.pxIndex);
Serial_Printf("TestList->xListEnd->pxNext\t0x%p\r\n", (TestList.xListEnd.pxNext));
Serial_Printf("ListItem1->pxNext\t\t0x%p\r\n", (ListItem1.pxNext));
Serial_Printf("ListItem2->pxNext\t\t0x%p\r\n", (ListItem2.pxNext));
Serial_Printf("ListItem3->pxNext\t\t0x%p\r\n", (ListItem3.pxNext));
Serial_Printf("TestList->xListEnd->pxPrevious\t0x%p\r\n", (TestList.xListEnd.pxPrevious));
Serial_Printf("ListItem1->pxPrevious\t\t0x%p\r\n", (ListItem1.pxPrevious));
Serial_Printf("ListItem2->pxPrevious\t\t0x%p\r\n", (ListItem2.pxPrevious));
Serial_Printf("ListItem3->pxPrevious\t\t0x%p\r\n", (ListItem3.pxPrevious));
Serial_Printf("/**************************结束˸***************************/\r\n");
for(;;)
{
vTaskDelay(10);
}
}
3、实验结果