STM32F103移植FreeRTOS系列十二:列表项的插入和删除实验(文末附代码)

本实验基于stm32f103rct6和正点原子源码进行

12.1 实验程序设计

1、实验目的: 学习使用 FreeRTOS 列表和列表项相应的操作函数的使用,观察这些操作函数的运行结果 和我们理论分析的是否一致。

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

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

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

task2_task: 列表和列表项操作任务,调用列表和列表项相关的 API 函数,并且通过串口 输出相应的信息来观察这些 API 函数的运行过程。 实验需要用到 KEY_UP 按键(PA0),用于控制任务的运行。

其实代码和原子的区别也不大,只要更改对应的.c和.h文件就行了。例如key.c,led.c这些,看到这里的应该都随便拿捏的。

这里就简单记录一下实验结果吧。

 第一步和第二步

	//第一步:初始化列表和列表项
	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");

第一步和第二步是用来初始化列表和列表项的,并且通过串口输出列表和列表项的地址, 这一步是开发板复位后默认运行的,串口调试助手信息如下所示:

由于这些列表和列表项地址前六位都为 0X200000,只有最低 2 位不同,所以我们就用最低 2 位代表这些列表和列表项的地址。注意!列表和列表项的地址在不同的硬件平台或编译软件 上是不同的,以自己的实际实验结果为准!简单的分析一下图 7.7.2.1 可以得到如下信息:

1、列表 TestList 地址为 bc。

2、列表项 ListItem1、ListItem2 和 ListItem3 的地址分别为 d0、e4 和 f8。

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

第三步

	while(KEY_Scan(0)!=WKUP_PRES) delay_ms(10);					//等待KEY_UP键按下
	
	//第三步:向列表TestList添加列表项ListItem1,并通过串口打印所有
	//列表项中成员变量pxNext和pxPrevious的值,通过这两个值观察列表
	//项在列表中的连接情况。
	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键按下

 1、xListEnd 的 pxNext 指向地址 d0,而 d0 是 ListItem1 的地址,说明 xListEnd 的 pxNext 指 向 ListItem1。(环形)

2、列表项 ListItem1 的 pxNext 指向地址 c4,而 c4是 xListEnd 的地址,说明 ListItem1 的 pxNext 指向 xListEnd。

3、xListEnd 的 pxPrevious 指向地址 d0,而 d0是 ListItem1 的地址,说明 xListEnd 的 pxPrevious 指向 ListItem2。

4、ListItem1 的 pxPrevious 指向地址 c4,c4 是 xListEnd 的地址,说明 ListItem1 的 pxPrevious 指向 xListEnd。

第四步

 1、xListEnd 的 pxNext 指向 ListItem1。

2、ListItem1 的 pxNext 指向 ListItem2。

3、ListItem2 的 pxNext 指向 xListEnd。

4、列表项的 pxPrevious 分析过程类似,后面的步骤中就不做分析了

 第五步

 1、xListEnd 的 pxNext 指向 ListItem1。

2、ListItem1 的 pxNext 指向 ListItem3。

3、ListItem3 的 pxNext 指向 ListItem2。

4、ListItem2 的 pxNext 指向 xListEnd。

第六步和第七步

这两步是观察函数 uxListRemove()和 vListInsertEnd()的运行过程的

我这里就只对第七步进行分析

 这一句会改变TestList.pxIndex指向的位置,默认情况指向列表尾项,这里把这个指向列表一了

所以排列由

132变为213,因为这个插入函数就是插入TestList.pxIndex指向的位置前一位。

 1、xListEnd 的 pxNext 指向 ListItem2。

2、ListItem1 的 pxNext 指向 ListItem3。

3、ListItem3 的 pxNext 指向 xListEnd。

4、ListItem2 的 pxNext 指向ListItem1。

大家自行根据串口调试助手输出的信息做分析

链接:https://pan.baidu.com/s/1ZHX16Nuim6pWLH-y2XM7zQ?pwd=rtos 
提取码:rtos

猜你喜欢

转载自blog.csdn.net/qq_51519091/article/details/131604382
今日推荐