国产精品久久久久影院,成人午夜福利视频,国产精品久久久久高潮,国产精品 欧美 亚洲 制服,国产精品白浆无码流出

STM32使用FreeRTOS中的鏈表創(chuàng)建節(jié)點(diǎn)與列表項(xiàng)

發(fā)布者:星塵散落最新更新時(shí)間:2019-07-18 來(lái)源: eefocus關(guān)鍵字:STM32  FreeRTOS  鏈表  創(chuàng)建節(jié)點(diǎn)  列表項(xiàng) 手機(jī)看文章 掃描二維碼
隨時(shí)隨地手機(jī)看文章

使用了STM32F103FreeRTOS庫(kù)來(lái)創(chuàng)建一個(gè)列表,其實(shí)FreeRTOS的list中鏈表是雙向的循環(huán)鏈表,為了簡(jiǎn)單介紹,我直接說(shuō)是列表了。 

芯片使用的是GD32F103CBT6,該芯片兼容ST的庫(kù),不影響使用效果。 

以下代碼不全,僅提供思路,如有不足,請(qǐng)給我留言。


第一步


先定義變量,初始化列表及列表項(xiàng)


nodeDevice node_t; //節(jié)點(diǎn)數(shù)據(jù)

nodeDevice * pNode; //節(jié)點(diǎn)指針

 

xList list_t; //列表

#define pList ((xList *) &list_t) //列表指針

 

xListItem item_t; //列表項(xiàng)

xListItem * pItem;  //列表項(xiàng)指針

 

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

vListInitialise((xList *) &list_t);

vListInitialiseItem(pItem);

第二步


根據(jù)條件判斷是否需要增加列表項(xiàng)與節(jié)點(diǎn)(每一個(gè)節(jié)點(diǎn)指針掛載在對(duì)應(yīng)列表項(xiàng)的空指針上)。 

我的節(jié)點(diǎn)數(shù)據(jù)是通過(guò)CAN數(shù)據(jù)來(lái)獲取的,其實(shí)通過(guò)其它總線也可以,但CAN總線可以掛載多個(gè)設(shè)備(收發(fā)器),就是現(xiàn)成的多個(gè)節(jié)點(diǎn)了。 

這部分代碼是我是否創(chuàng)建新節(jié)點(diǎn)的邏輯代碼。


/*****************************************************************************

**Name: DealAddressReq

**Function: 處理設(shè)備地址

**Args:

**Return:

******************************************************************************/

void DealAddressReq(CanRxMsgTypeDef * const pCAN_RxData, void * const pBaseInfo)

{

uint32_t NodeAddress;

nodeDevice *goalCurrentNode = NULL;//當(dāng)前節(jié)點(diǎn)指針

 

/*獲取設(shè)備ID*/

NodeAddress = (pCAN_RxData->Data[0]<<24)|(pCAN_RxData->Data[1]<<16)|(pCAN_RxData->Data[2]<<8)|(pCAN_RxData->Data[3]);

 

if(NodeAddress == NULLDEVICE)return;//地址為空則退出

 

/*如果列表為空*/

if(listLIST_IS_EMPTY(pList))

{

CreateNode(pCAN_RxData, pBaseInfo, NodeAddress);//加載第一項(xiàng),創(chuàng)建第一個(gè)節(jié)點(diǎn)

}

else/*如果列表不為空*/

{

goalCurrentNode = GetNodeByUidOrCHID(NodeAddress, 0);//根據(jù)UID獲取節(jié)點(diǎn)

 

/*如果不是地址池中的地址,則創(chuàng)建新的節(jié)點(diǎn)*/

if(goalCurrentNode == NULLNODE)

{

CreateNode(pCAN_RxData, pBaseInfo, NodeAddress);//創(chuàng)建新節(jié)點(diǎn)

}

else

{

return;

}

}

}

 

其中遍歷列表,查找當(dāng)前節(jié)點(diǎn)的函數(shù)


/*****************************************************************************

**Name: GetNodeByUid

**Function: 根據(jù)UID獲取節(jié)點(diǎn),或根據(jù)數(shù)據(jù)上下行通道獲取節(jié)點(diǎn)

**Args: NodeAddress != 0: 使用UID獲取節(jié)點(diǎn)

nodeChannelID != 0: 使用數(shù)據(jù)上下行通道獲取節(jié)點(diǎn)

**Return:

******************************************************************************/

nodeDevice * GetNodeByUidOrCHID(uint32_t NodeAddress, uint32_t nodeChannelID)

{

int index;

nodeDevice *getCurrentNode = NULL;//當(dāng)前節(jié)點(diǎn)指針

 

for(index = 0; index < LIST_LENGTH; index++)

{

/*遍歷列表,返回的是列表中列表項(xiàng)的pxOwner成員*/

listGET_OWNER_OF_NEXT_ENTRY(getCurrentNode, pList);

 

//根據(jù)MAC查找結(jié)點(diǎn)

if(NodeAddress == (getCurrentNode->nodeAddress))

{

return getCurrentNode;

}

//地址應(yīng)答幀ID是否與該節(jié)點(diǎn)的數(shù)據(jù)下行通道相配對(duì)

else if(nodeChannelID == (getCurrentNode->nodeChannelID_Low|0x01))

{

return getCurrentNode;

}

else

{

getCurrentNode = NULLNODE;

}

}

 

return getCurrentNode;

}

 

第三步


申請(qǐng)內(nèi)存,創(chuàng)建節(jié)點(diǎn)與列表項(xiàng),插入列表(鏈表) 

這一部分為重點(diǎn),其實(shí)思路與網(wǎng)上大部分創(chuàng)建插入鏈表相同,只是更改了一些函數(shù)名與變量。


/*****************************************************************************

**Name: CreateNode

**Function: 創(chuàng)建列表項(xiàng)與節(jié)點(diǎn)

**Args:

**Return:

******************************************************************************/

void CreateNode(CanRxMsgTypeDef * const pCAN_RxData, void * const pBaseInfo, uint32_t UidAddress)

{

/*執(zhí)行一次,則創(chuàng)建一個(gè)列表項(xiàng)與節(jié)點(diǎn)結(jié)構(gòu)體*/

pItem = pvPortMalloc(sizeof(ListItem_t));//申請(qǐng)列表項(xiàng)內(nèi)存

pNode = pvPortMalloc(sizeof(nodeDevice));//申請(qǐng)結(jié)構(gòu)體內(nèi)存

memset(pNode, 0, sizeof(nodeDevice));

 

pItem->xItemValue = GetNodePosition();//獲取占位地址大小

vListInsert(pList, pItem);//插入列表項(xiàng)

 

pItem->pvOwner = pNode;//給列表項(xiàng)的空指針掛上我們的數(shù)據(jù)地址

 

/*發(fā)送通道ID(大端)*/

NodeDataInstall( pCAN_RxData, pBaseInfo, UidAddress, pNode);//數(shù)據(jù)加載

}

因?yàn)樾枰獎(jiǎng)討B(tài)增加節(jié)點(diǎn),所以pItem->xItemValue的值是需要在可控范圍內(nèi)獲取的,并不一定是0~0xFFFFFFFFU的值,需要根據(jù)節(jié)點(diǎn)索引的數(shù)據(jù)類(lèi)型來(lái)。 

這里有一個(gè)問(wèn)題,比如定義了一個(gè)char型,就只能取0~255的數(shù),若是超過(guò)了255怎么辦吶?或者我是“整十”地定義索引,就只有25個(gè)數(shù)可取了.

之前說(shuō)過(guò)了是“動(dòng)態(tài)增加節(jié)點(diǎn)”,也就是說(shuō)不只是增加,我們也可以刪除,刪除數(shù)據(jù)之后我們需要還原一些數(shù)據(jù),并釋放內(nèi)存,當(dāng)我們下一次增加新節(jié)點(diǎn)時(shí)使用的就是之前釋放掉的內(nèi)存,那么問(wèn)題還是那個(gè)——我們的xItemValue值和節(jié)點(diǎn)定義的索引怎么辦?

先來(lái)說(shuō)一下列表項(xiàng)的xItemValue值,它是FreeRTOS中l(wèi)ist.h定義的一個(gè)列表項(xiàng)結(jié)構(gòu)體的一個(gè)變量,目地是為了插入列表項(xiàng)的時(shí)候,更據(jù)它的大小比較進(jìn)行排序后插入列表對(duì)應(yīng)的位置,所以它很重要。為了不要讓我們插入的位置沖突,最好初始化一個(gè)新的列表項(xiàng)的時(shí)候把它賦一個(gè)不同的值。 

我們節(jié)點(diǎn)的索引應(yīng)該也一樣具有唯一性,就和總線上的設(shè)備地址一樣。所以值的設(shè)置我們使用占位法,思路與STM32的寄存器一樣—— 一個(gè)功能占一個(gè)BIT,使用時(shí)將該位“置1”,使用完后將該位“清0”,等待下一次使用。 

當(dāng)使用到一位時(shí),將它“置1”后將它的實(shí)際大小返回,賦值給xItemValue。

例如:從小到大占位“0000 0000”,現(xiàn)在都是空的, 現(xiàn)在占用第1位后“0000 0001”,當(dāng)前列表項(xiàng)xItemValue = 1; 

從小到大占位“0001 1111”,現(xiàn)在使用了5個(gè)位置,當(dāng)前列表項(xiàng)xItemValue = 5,現(xiàn)在還原第3位后“0001 1011”,下次可繼續(xù)使用第3位; 

注:位的運(yùn)算方法推薦使用STM32庫(kù)中對(duì)寄存器的運(yùn)算!

第四步


自己設(shè)計(jì)刪除節(jié)點(diǎn)的條件


    //......

    

//還原位置數(shù)據(jù)

RestoreNodePosition(bxCurrentNode->nodeChannelID_Low);

 

pxCurrentItem = pList->pxIndex;//當(dāng)前列表項(xiàng)

uxListRemove( pxCurrentItem); //刪除列表項(xiàng)

vPortFree(bxCurrentNode); //釋放內(nèi)存

vPortFree(pxCurrentItem);

    //......


關(guān)鍵字:STM32  FreeRTOS  鏈表  創(chuàng)建節(jié)點(diǎn)  列表項(xiàng) 引用地址:STM32使用FreeRTOS中的鏈表創(chuàng)建節(jié)點(diǎn)與列表項(xiàng)

上一篇:FreeRTOS學(xué)習(xí)筆記——基礎(chǔ)知識(shí)與移植(STM32F103)
下一篇:幾張圖對(duì)比STM32各系列產(chǎn)品特性和外設(shè)兼容性

推薦閱讀最新更新時(shí)間:2025-06-28 06:14

STM32 FreeRTOS 外部中斷服務(wù)函數(shù)注意事項(xiàng)
移植正點(diǎn)原子的FreeRTOS操作系統(tǒng)到我們自己的工程,發(fā)現(xiàn)的一個(gè)注意事項(xiàng); 看下面代碼,帶FreeRTOS的外部中斷服務(wù)函數(shù),實(shí)現(xiàn)按鍵消抖,不能用delay_ms()或者和vTaskDelay(),會(huì)導(dǎo)致系統(tǒng)奔潰; 原因是delay_ms()其實(shí)就是對(duì) FreeRTOS 中的延時(shí)函數(shù) vTaskDelay()的簡(jiǎn)單封裝,所以在使用 delay_ms()的時(shí)候就會(huì)導(dǎo)致任務(wù)切換,即不會(huì)導(dǎo)致這個(gè)外部中斷延時(shí)阻塞,而切換到其他任務(wù),導(dǎo)致外部中斷出錯(cuò); 這里我們可以使用delay_xms(),其不會(huì)引起任務(wù)調(diào)度,是真的延時(shí);(僅針對(duì)外部中斷函數(shù),因?yàn)槲野l(fā)現(xiàn)在按鍵掃描函數(shù)里面,可以使用delay_ms();) //提供框架-
[單片機(jī)]
基于STM32FREERTOS應(yīng)用的幾個(gè)常見(jiàn)問(wèn)題
1、怎樣將 FreeRTOS 移植到不同的Cortex-M 內(nèi)核? 答:若需將 FreeRTOS 移植到正確的Cortex-M 產(chǎn)品,您必須從正確的目錄導(dǎo)入 “port.c”文件。例如,若微控制器是帶有IAR 工具的 Cortex-M0 內(nèi)核,則您必須從“FreeRTOS\Source\portable\IAR\ARM_CM0” 獲取 port.c。 2、FreeRTOS 使用需要ROM/RAM? 答:這取決于您的編譯器、代碼架構(gòu),以及RTOS 內(nèi)核配置。一般來(lái)說(shuō), RTOS 內(nèi)核本身需要大約 5到 10 K 字節(jié) ROM 空間。 如果創(chuàng)建的線程或隊(duì)列數(shù)增加,RAM 使用量就會(huì)上升。 3、怎樣設(shè)置 CPU 時(shí)鐘? 答:CPU 時(shí)鐘
[單片機(jī)]
[單片機(jī)框架][os層] freertos 中間件 公共函數(shù)
重新封裝freertos函數(shù),以便適配RTX4 /RTX5 / FREERTOS_NRF_RTC。 FreeRTOS 是一類(lèi) RTOS,設(shè)計(jì)得足夠小以在微控制器上運(yùn)行——盡管它的使用不限于微控制器應(yīng)用。 微控制器是一種小型且資源受限的處理器,它在單個(gè)芯片上集成了處理器本身、只讀存儲(chǔ)器(ROM 或閃存)以保存要執(zhí)行的程序,以及程序所需的隨機(jī)存取存儲(chǔ)器 (RAM)執(zhí)行。通常,程序直接從只讀存儲(chǔ)器中執(zhí)行。 微控制器用于深度嵌入式應(yīng)用程序(那些您從未真正看到處理器本身或其運(yùn)行的軟件的應(yīng)用程序),這些應(yīng)用程序通常有非常具體和專(zhuān)門(mén)的工作要做。大小限制和專(zhuān)用終端應(yīng)用程序性質(zhì)很少保證使用完整的 RTOS 實(shí)現(xiàn) - 或者確實(shí)使使用完整的
[單片機(jī)]
嵌入式學(xué)習(xí)⑥——FreeRTOS入門(mén)
一、準(zhǔn)備工作 所用器件:STM32 MINI、下載線ST–Link 所用編程軟件:MDK5.33 二、操作目的 在STM32下完成一個(gè)基于FreeRTOS的多任務(wù)程序,執(zhí)行3個(gè)周期性task。 task1,每間隔500ms閃爍(變化)一次LED; task2,每間隔2000ms,向串口發(fā)送一次指令數(shù)據(jù)“helloworld! ; task3,每間隔5000ms,從AHT20采集一次溫濕度數(shù)據(jù)(不考慮硬件情況,僅寫(xiě)出整個(gè)多任務(wù)框架模擬代碼)。 三、實(shí)驗(yàn)操作 1.實(shí)驗(yàn)所需代碼 #include FreeRTOS.h #include task.h #include bsp_led.h #include bsp_usa
[單片機(jī)]
嵌入式學(xué)習(xí)⑥——<font color='red'>FreeRTOS</font>入門(mén)
基于STM32的(NB-IOT(BC26))溫濕度監(jiān)測(cè)系統(tǒng)
閑來(lái)無(wú)事,用手頭STM32做個(gè)項(xiàng)目。 成品功能:STM32采集溫度、濕度數(shù)據(jù),顯示在屏幕上,通過(guò)NB-IOT(BC26)模塊連接阿里云物聯(lián)網(wǎng)平臺(tái)接受數(shù)據(jù)并實(shí)時(shí)監(jiān)控。 材料 STM32ZET6開(kāi)發(fā)板(戰(zhàn)艦V3) TFT顯示屏(戰(zhàn)艦有我用的2.7寸的) NB-IOT(BC26)模塊 DHT11溫濕度模塊 杜邦線 用keil5進(jìn)行開(kāi)發(fā) 開(kāi)始制作。 制作過(guò)程 首先從板子測(cè)溫濕度開(kāi)始 DHT11溫濕度模塊 原子哥有DHT11例程,所以直接在此基礎(chǔ)上進(jìn)行開(kāi)發(fā) 下載上之后這是效果。 阿里云物聯(lián)網(wǎng)平臺(tái) 先到阿里云物聯(lián)網(wǎng)平臺(tái)注冊(cè)一個(gè)設(shè)備。 進(jìn)入阿里云官網(wǎng)搜索物聯(lián)網(wǎng)平臺(tái),現(xiàn)在可以免費(fèi)注冊(cè)一個(gè)。 點(diǎn)擊設(shè)備接入服務(wù) 在這
[單片機(jī)]
基于<font color='red'>STM32</font>的(NB-IOT(BC26))溫濕度監(jiān)測(cè)系統(tǒng)
STM32的ISP方式和IAP方式下載程序有什么區(qū)別
都可以通過(guò)串口來(lái)下載啊 ISP方式:需要將BOOT管腳配置成上電從System Memory啟動(dòng),System Memory中有一段BOOTLOADER來(lái)接收串口來(lái)的數(shù)據(jù),把它們燒寫(xiě)到FLASH中。 IAP方式:是用戶(hù)自己寫(xiě)一段燒寫(xiě)程序,通過(guò)ISP或者仿真器事先燒寫(xiě)到用戶(hù)FLASH中,使用時(shí)通過(guò)某種方式觸發(fā)這段程序,再來(lái)從串口接收數(shù)據(jù),然后燒到相應(yīng)的FLASH中,不需要改變BOOT管腳配置。
[單片機(jī)]
stm32庫(kù)函數(shù)FSMC_NORSRAMInit()解析
這是一段對(duì)nor存儲(chǔ)器的時(shí)序進(jìn)行編程的函數(shù),函數(shù)形式為void FSMC_NORSRAMInit(FSMC_NORSRAMInitTypeDef* FSMC_NORSRAMInitStruct),里面只有一個(gè)參數(shù),這個(gè)參數(shù)為指針類(lèi)型,指向一段數(shù)據(jù)結(jié)構(gòu),這個(gè)數(shù)據(jù)結(jié)構(gòu)就保存著對(duì)時(shí)序進(jìn)行配置的的各個(gè)參數(shù),這個(gè)結(jié)構(gòu)的詳細(xì)內(nèi)容為 typedef struct { uint32_t FSMC_Bank;//nor被分為四塊,其中這個(gè)參數(shù)是說(shuō)明對(duì)那個(gè)塊編程 uint32_t FSMC_DataAddressMux;//地址數(shù)據(jù)是否復(fù)用 uint32_t FSMC_MemoryType;//存儲(chǔ)器類(lèi)型 uint3
[單片機(jī)]
STM32的12位ADC過(guò)采樣實(shí)現(xiàn)16位分辨率
1.什么是過(guò)采樣 過(guò)采樣技術(shù)是一種以犧牲采樣速度來(lái)提高ADC分辨率的技術(shù)。部分STM32單片機(jī)是支持硬件過(guò)采樣的,如STM32G0系列。通過(guò)過(guò)采樣,可以將12位的ADC提升到16位,非常實(shí)用。 根據(jù)過(guò)采樣技術(shù),每提高1位ADC分辨率,需要增加4倍的采樣率。也就是說(shuō)1次采樣是12Bit,4次是13Bit,16次是14Bit,64次是15Bit,256次是16Bit,如果要更高分辨率,那么STM32的硬件過(guò)采樣就無(wú)能為力了。 過(guò)采樣主要通過(guò)配置ADC_SMPR寄存器的下面幾位即可實(shí)現(xiàn),配置移位位數(shù)、過(guò)采樣倍數(shù)以及使能位。如下: 最大可配置為256倍過(guò)采樣,實(shí)現(xiàn)16位分辨率。當(dāng)采用256倍過(guò)采樣時(shí),得到的結(jié)果是20位的,但ADC
[單片機(jī)]
<font color='red'>STM32</font>的12位ADC過(guò)采樣實(shí)現(xiàn)16位分辨率
小廣播
設(shè)計(jì)資源 培訓(xùn) 開(kāi)發(fā)板 精華推薦

最新單片機(jī)文章
隨便看看

 
EEWorld訂閱號(hào)

 
EEWorld服務(wù)號(hào)

 
汽車(chē)開(kāi)發(fā)圈

 
機(jī)器人開(kāi)發(fā)圈

電子工程世界版權(quán)所有 京B2-20211791 京ICP備10001474號(hào)-1 電信業(yè)務(wù)審批[2006]字第258號(hào)函 京公網(wǎng)安備 11010802033920號(hào) Copyright ? 2005-2025 EEWORLD.com.cn, Inc. All rights reserved