最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

【教程】STM32 FreeRTOS實(shí)時(shí)系統(tǒng)移植系列6:FreeRTOS 列表和列表項(xiàng)

2021-08-27 09:15 作者:華清遠(yuǎn)見(jiàn)研發(fā)中心  | 我要投稿

1.寫在前面:

?

本文章為《STM32MP157開發(fā)教程之FreeRTOS操作系統(tǒng)篇》系列中的一篇,筆者使用的開發(fā)平臺(tái)為華清遠(yuǎn)見(jiàn)FS-MP1A開發(fā)板(STM32MP157開發(fā)板)。stm32mp157是ARM雙核,2個(gè)A7核,1個(gè)M4核,A7核上可以跑Linux操作系統(tǒng),M4核上可以跑FreeRTOS、RT-Thread等實(shí)時(shí)操作系統(tǒng),STM32MP157開發(fā)板所以既可以學(xué)嵌入式linux,也可以學(xué)stm32單片機(jī)。

針對(duì)FS-MP1A開發(fā)板,除了FreeRTOS操作系統(tǒng)篇外,還包括其他多系列教程,包括Cortex-A7開發(fā)篇、Cortex-M4開發(fā)篇、擴(kuò)展板驅(qū)動(dòng)移植篇、Linux應(yīng)用開發(fā)篇、Linux系統(tǒng)移植篇、Linux驅(qū)動(dòng)開發(fā)篇、硬件設(shè)計(jì)篇、人工智能機(jī)器視覺(jué)篇、Qt應(yīng)用編程篇、Qt綜合項(xiàng)目實(shí)戰(zhàn)篇等。歡迎關(guān)注,更多stm32mp157開發(fā)教程及視頻,可加技術(shù)交流Q群459754978,感謝關(guān)注。

FS-MP1A開發(fā)板詳情介紹:https://item.taobao.com/item.htm?id=622457259672

2.FreeRTOS列表和列表項(xiàng)

2.1列表和列表項(xiàng)簡(jiǎn)介

學(xué)習(xí)FreeRTOS,肯定少不了列表和列表項(xiàng),列表和列表項(xiàng)是FreeRTOS的一個(gè)數(shù)據(jù)結(jié)構(gòu),它是FreeRTOS的基石。

列表被用來(lái)跟蹤FreeRTOS中的任務(wù),在list.h文件中定義了列表結(jié)構(gòu)體List_t如下

typedef struct xLIST

{

listFIRST_LIST_INTEGRITY_CHECK_VALUE

configLIST_VOLATILE UBaseType_t uxNumberOfItems;

ListItem_t * configLIST_VOLATILE pxIndex;

MiniListItem_t xListEnd;

listSECOND_LIST_INTEGRITY_CHECK_VALUE

} List_t;

第一行和第五行都是用來(lái)檢查列表完整性,需要將宏
configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES設(shè)置為1。

uxNumberOfItems用來(lái)記錄列表中列表項(xiàng)的數(shù)量。

pxIndex用來(lái)記錄當(dāng)前列表項(xiàng)索引號(hào),用于遍歷列表。

xListEnd表示列表中最后一個(gè)列表項(xiàng),用來(lái)表示列表結(jié)束。

列表項(xiàng)就是存放在列表中的項(xiàng)目,其定義如下

struct xLIST_ITEM

{

listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE

configLIST_VOLATILE TickType_t xItemValue;

struct xLIST_ITEM * configLIST_VOLATILE pxNext;

struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;

void * pvOwner;

void * configLIST_VOLATILE pvContainer;

listSECOND_LIST_ITEM_INTEGRITY_CHECK_VALUE

};

typedef struct xLIST_ITEM ListItem_t;

第一行和第七行同列表一樣,都是用來(lái)檢查列表項(xiàng)完整性。

xItemValue為列表項(xiàng)值。

pxNext指向下一個(gè)列表項(xiàng)。

pxPrevious指向前一個(gè)列表項(xiàng),與pxNext相配合。

pvOwner記錄此列表項(xiàng)歸誰(shuí)擁有,通常是任務(wù)控制塊。

pvContainer用來(lái)記錄此列表項(xiàng)歸哪個(gè)列表。

另外還有一種迷你列表項(xiàng),其定義如下

struct xMINI_LIST_ITEM

{

listFIRST_LIST_ITEM_INTEGRITY_CHECK_VALUE

configLIST_VOLATILE TickType_t xItemValue;

struct xLIST_ITEM * configLIST_VOLATILE pxNext;

struct xLIST_ITEM * configLIST_VOLATILE pxPrevious;

};

typedef struct xMINI_LIST_ITEM MiniListItem_t;

第一行同樣用于檢查迷你列表項(xiàng)的完整性。

xItemValue記錄列表項(xiàng)值。

pxNext指向下一個(gè)列表項(xiàng)。

pxPrevious指向前一個(gè)列表項(xiàng)。

在這里之所以弄個(gè)迷你列表項(xiàng),是因?yàn)橛行┣闆r下,我們不需要列表項(xiàng)那么全的功能,可能只需要其中的某幾個(gè)成員變量,此時(shí)用列表項(xiàng)的話可能會(huì)造成內(nèi)存浪費(fèi)。

2.2列表與列表項(xiàng)函數(shù)

2.2.1列表與列表項(xiàng)初始化

新創(chuàng)建或者定義的列表都需要對(duì)其做初始化處理,對(duì)列表的初始化函數(shù)為vListInitialise(),其函數(shù)原型如下:

void vListInitialise ( List* const pxList)

參數(shù):

pxList: 要進(jìn)行初始化的列表。

返回值:無(wú)

對(duì)列表項(xiàng)的初始化函數(shù)為vListInitialiseItem(),其函數(shù)原型如下:

void vListInitialiseItem ( ListItem_t * const pxItem)

參數(shù):

pxItem: 要進(jìn)行初始化的列表。

返回值:無(wú)

在此不對(duì)初始化函數(shù)的具體代碼做描述了,有興趣的可以去list.c文件中查看。

2.2.2 列表項(xiàng)插入

列表項(xiàng)的插入函數(shù)為vListInsert(),其函數(shù)原型如下:

void vListInsert( List* const pxList, ListItem_t * const pxNewListItem)

參數(shù):

pxList: 列表項(xiàng)要插入的列表。

pxNewListItem: 要插入的列表項(xiàng)。

返回值:無(wú)

2.2.3列表項(xiàng)末尾插入

列表在末尾插入列表項(xiàng)的函數(shù)為vListInsertEnd(),其函數(shù)原型如下:

void vListInsertEnd( List * const pxList, ListItem_t * const pxNewListItem)

參數(shù):

pxList: 列表項(xiàng)要插入的列表。

pxNewListItem: 要插入的列表項(xiàng)。

返回值:無(wú)


2.2.4 列表項(xiàng)刪除

有插入那么必然有刪除,列表項(xiàng)的刪除函數(shù)為uxListRemove(),其函數(shù)原型如下:

UBaseType_t uxListRemove( ListItem_t * const pxItemToRemove )

參數(shù):

pxItemToRemove: 要?jiǎng)h除的列表項(xiàng)。

返回值:

返回刪除列表項(xiàng)以后的列表剩余列表項(xiàng)數(shù)目。

列表項(xiàng)的刪除只是將指定的列表項(xiàng)從列表中刪除掉,并不會(huì)將列表項(xiàng)的內(nèi)存給釋放掉。

2.3操作實(shí)驗(yàn)

2.3.1實(shí)驗(yàn)設(shè)計(jì)

本次設(shè)計(jì)中創(chuàng)建了一個(gè)列表以及三個(gè)列表項(xiàng),通過(guò)中斷采集按鍵狀態(tài),當(dāng)KEY1按下時(shí),依次將三個(gè)列表項(xiàng)添加到列表中,當(dāng)KEY2按下時(shí),刪除第2條列表項(xiàng),當(dāng)KEY3按下時(shí),再將第2條列表項(xiàng)從末尾插入。

可參考12.3.2章節(jié)進(jìn)行導(dǎo)入已有工程,工程存放路徑【華清遠(yuǎn)見(jiàn)-FS-MP1A開發(fā)資料\02-程序源碼\ARM體系結(jié)構(gòu)與接口技術(shù)\FreeRTOS\7_MP1A-FreeRTOS-List】

任務(wù)及其功能如下:

StartTask02(): 進(jìn)行列表與列表項(xiàng)的初始化并打印,然后采集按鍵狀態(tài),根據(jù)不同的按鍵結(jié)果進(jìn)行不同處理。

StartDefaultTask(): 讓LED3循環(huán)閃爍,提示系統(tǒng)正常運(yùn)行。

2.3.2實(shí)驗(yàn)過(guò)程與分析

首先,根據(jù)之前幾章內(nèi)容配置好CubeMX,按照上一節(jié)配置“FREERTOS”,完成后生成代碼。 在StartDefaultTask() 與StartTask02()中添加代碼如下。

void?StartDefaultTask(void?*argument)

{

/* USER CODE BEGIN 5 */

/* Infinite loop */

for(;;)

{

LED_3_TOG();

osDelay(1000);

}

/* USER CODE END 5 */

}

void?StartTask02(void?*argument)

{

/* USER CODE BEGIN StartTask02 */

/* Infinite loop */

//初始化列表和列表項(xiàng)

vListInitialise(&TestList);

vListInitialiseItem(&ListItem1);

vListInitialiseItem(&ListItem2);

vListInitialiseItem(&ListItem3);

ListItem1.xItemValue=40;?//ListItem1列表項(xiàng)值為40

ListItem2.xItemValue=60;?//ListItem2列表項(xiàng)值為60

ListItem3.xItemValue=50;?//ListItem3列表項(xiàng)值為50

//打印列表和其他列表項(xiàng)的地址

printf("project address \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);

for(;;)

{

if(key == EVENTBIT_1)

{

//向列表TestList添加列表項(xiàng)ListItem1,并通過(guò)串口打印所有

//列表項(xiàng)中成員變量pxNext和pxPrevious的值,通過(guò)這兩個(gè)值觀察列表

//項(xiàng)在列表中的連接情況。

vListInsert(&TestList,&ListItem1);?//插入列表項(xiàng)ListItem1

printf("project address \r\n");

printf("TestList->xListEnd->pxNext %#x \r\n",(int)(TestList.xListEnd.pxNext));

printf("ListItem1->pxNext %#x \r\n",(int)(ListItem1.pxNext));

printf("/***********Connect the divider front and back 1************/\r\n");

printf("TestList->xListEnd->pxPrevious %#x

\r\n",(int)(TestList.xListEnd.pxPrevious));

printf("ListItem1->pxPrevious %#x \r\n",(int)(ListItem1.pxPrevious));

printf("/**************************end****************************/\r\n");

//向列表TestList添加列表項(xiàng)ListItem2,并通過(guò)串口打印所有

//列表項(xiàng)中成員變量pxNext和pxPrevious的值,通過(guò)這兩個(gè)值觀察列表

//項(xiàng)在列表中的連接情況。

vListInsert(&TestList,&ListItem2);?//插入列表項(xiàng)ListItem2

printf("project address \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("/***********Connect the divider front and back 2************/\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("/***************************end*****************************/\r\n");

//向列表TestList添加列表項(xiàng)ListItem3,并通過(guò)串口打印所有

//列表項(xiàng)中成員變量pxNext和pxPrevious的值,通過(guò)這兩個(gè)值觀察列表

//項(xiàng)在列表中的連接情況。

vListInsert(&TestList,&ListItem3);?//插入列表項(xiàng)ListItem3

printf("project address \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("/************Connect the divider front and back 3************/\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("/***************************end*****************************/\r\n");

}

if(key == EVENTBIT_2)

{

//刪除ListItem2,并通過(guò)串口打印所有列表項(xiàng)中成員變量pxNext和Previous的值,通過(guò)這兩個(gè)值觀察列表項(xiàng)在列表中的連接情況。

uxListRemove(&ListItem2);?//刪除ListItem2

printf("/**************Delete list items ListItem2*************/\r\n");

printf("project address \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("/***********Connect the divider front and back 2************/\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("/*************************end****************************/\r\n");

}

if(key == EVENTBIT_3)

{

//末尾添加ListItem2,并通過(guò)串口打印所有列表項(xiàng)中成員變量pxNext和Previous的值,

//通過(guò)這兩個(gè)值觀察列表項(xiàng)在列表中的連接情況。

TestList.pxIndex=TestList.pxIndex->pxNext;?//Index向后移一項(xiàng),這樣pxIndex就會(huì)指向ListItem1。

vListInsertEnd(&TestList,&ListItem2);?//列表末尾添加列表項(xiàng)ListItem2

printf("/***********Add the list at the end of ListItem2***********/\r\n");

printf("project address \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("/************Connect the divider front and back 2*************/\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("/***************************end*****************************/\r\n");

}

key = 0;

osDelay(100);

}

/* USER CODE END StartTask02 */

}

編寫按鍵中斷回調(diào)函數(shù)如下

void?HAL_GPIO_EXTI_Rising_Callback(uint16_t?GPIO_Pin)

{

switch(GPIO_Pin)

{

case?GPIO_PIN_8:

if(HAL_GPIO_ReadPin(GPIOF,GPIO_PIN_8) ==?GPIO_PIN_SET)?/* read KEY3 PF8 state */

key = EVENTBIT_3;

break;

case?GPIO_PIN_7:

if(HAL_GPIO_ReadPin(GPIOF,GPIO_PIN_7) ==?GPIO_PIN_SET)?/* read KEY2 PF7 state */

key = EVENTBIT_2;

break;

case?GPIO_PIN_9:

if(HAL_GPIO_ReadPin(GPIOF,GPIO_PIN_9) ==?GPIO_PIN_SET)?/* read KEY1 PF9 state */

key = EVENTBIT_1;

break;

}

}

燒錄程序以后,打開串口,可以發(fā)現(xiàn)顯示內(nèi)容如下


當(dāng)按下KEY1鍵時(shí),將列表項(xiàng)添加到列表中,串口顯示如下


當(dāng)KEY2鍵按下時(shí),刪除第2條列表項(xiàng),剩余結(jié)果如下


此時(shí)按下KEY3鍵,將第2條列表項(xiàng)從末尾插入,最終結(jié)果如下



硬件平臺(tái):華清遠(yuǎn)見(jiàn)FS-MP1A開發(fā)板(STM32MP157)

部分開發(fā)教程下載:加QQ群459754978,群文件里有。

淘寶購(gòu)買鏈接:
https://item.taobao.com/item.htm?id=622457259672

手機(jī)淘寶分享碼:復(fù)制本行文字打開手淘?T4FPXn3YYJ2?


【教程】STM32 FreeRTOS實(shí)時(shí)系統(tǒng)移植系列6:FreeRTOS 列表和列表項(xiàng)的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
勐海县| 克什克腾旗| 虎林市| 正安县| 炎陵县| 洪江市| 富民县| 西林县| 车险| 百色市| 措勤县| 高尔夫| 新泰市| 元江| 筠连县| 鄯善县| 乳山市| 四子王旗| 杭锦后旗| 田阳县| 工布江达县| 顺义区| 积石山| 黄石市| 松阳县| 鄱阳县| 额济纳旗| 禹城市| 河西区| 长丰县| 桐庐县| 隆林| 新野县| 阿拉善左旗| 行唐县| 通州市| 化德县| 抚松县| 开化县| 金平| 谢通门县|