日B视频 亚洲,啪啪啪网站一区二区,91色情精品久久,日日噜狠狠色综合久,超碰人妻少妇97在线,999青青视频,亚洲一区二卡,让本一区二区视频,日韩网站推荐

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

在STM32中為什么要引入鏈表?

GReq_mcu168 ? 來源:知曉編程 ? 作者:知曉編程 ? 2021-05-03 10:30 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

1、為何引入鏈表

在程序中經(jīng)常面臨一個問題,我們需要保存一定數(shù)量的對象,但是對象數(shù)目是不確定的,或者說是隨時增加或減少的。這時候最簡單的方法是創(chuàng)建一個足夠大的數(shù)組,用來存儲這些對象。我最近開發(fā)一個項目就遇到類似的問題,下面我把問題簡化一下。

需求:通過PC下發(fā)一些矩形的坐標和寬高信息,每個區(qū)域有個ID編號,并在這些矩形內(nèi)填充一定的數(shù)據(jù)。

通常情況下,最簡單易懂的做法是,限制最多5個區(qū)域,每個區(qū)域存儲1K數(shù)據(jù)。因此設置了這樣的一個結構體(類似于面向?qū)ο笳Z言里說的成員屬性)。

typedef struct Area_Inf{ uint8_t ID; uint8_t X; uint8_t Y; uint8_t Width; uint8_t Height; uint8_t data_len;}Area_Inf_Typedef;

然后定義結構體的實體。

#define Area_Num 5#define Area_cache 1024

Area_Inf_Typedef Area_Info[Area_Num];uint8_t Area_Data[Area_Num*Area_cache];//存儲區(qū)域的數(shù)據(jù)

/*找到ID為5的區(qū)域,并將數(shù)據(jù)拷貝出去*/void main(){ uint8_t i; uint8_t data[1024]; for(i = 0;i 《 Area_Num;i++) { if(Area_Info[i].ID == 5) { memcpy(data,&Area_Data[i*Area_cache ],Area_Info[i].data_len); } }}

上面這種做法是最簡單易懂的,但不靈活,比如有客戶要求10個區(qū)域,但是每個區(qū)域存儲的數(shù)據(jù)很少,根本用不到1K。雖然上面的程序已經(jīng)使用了宏定義,只需要修改宏定義就能實現(xiàn)要求。但這意味著不同的客戶,需要編譯不同的固件。

#define Area_Num 10#define Area_cache 512

這樣的程序存在的問題:

1、在內(nèi)存資源很緊缺的單片機程序中,當區(qū)域數(shù)據(jù)很少時,這種程序的處理方法浪費了大量的內(nèi)存空間。

2、數(shù)值固定,需要存儲更多區(qū)域,即使還有內(nèi)存,還是需要修改宏定義,重新編譯固件,不靈活。

這時需要引入鏈表來解決這個問題。

2、鏈表實現(xiàn)

鏈表實際上是線性表的鏈式存儲結構,與數(shù)組不同的是,它是用一組任意的存儲單元來存儲線性表中的數(shù)據(jù),存儲單元不一定是連續(xù)的,且鏈表的長度不是固定的,鏈表數(shù)據(jù)的這一特點使其可以非常的方便地實現(xiàn)節(jié)點的插入和刪除操作。鏈表的每個元素稱為一個節(jié)點,每個節(jié)點都可以存儲在內(nèi)存中的不同的位置,為了表示每個元素與后繼元素的邏輯關系,以便構成“一個節(jié)點鏈著一個節(jié)點”的鏈式存儲結構,除了存儲元素本身的信息外,還要存儲其直接后繼信息,因此,每個節(jié)點都包含兩個部分,第一部分稱為鏈表的數(shù)據(jù)區(qū)域,用于存儲元素本身的數(shù)據(jù)信息。

6ee7ead4-9e2c-11eb-8b86-12bb97331649.png

對于上面的問題,我們使用鏈表解決,需要配合內(nèi)存管理才能實現(xiàn)。內(nèi)存管理這一塊,大家可以自己編寫內(nèi)存管理驅(qū)動,也可以使用C庫的malloc和free函數(shù)。如何字節(jié)編寫內(nèi)存管理驅(qū)動不是本文的重點,下文將使用C庫的malloc和free函數(shù)進行內(nèi)存管理。

使用鏈表的方式,在原有的成員屬性結構體的前提上,還要再封裝多一層鏈表管理。以單向鏈表為例:

typedef struct Area_Inf{ uint8_t ID; uint8_t X; uint8_t Y; uint8_t Width; uint8_t Height; uint8_t data_len; uint8_t* Area_Data;}Area_Inf_Typedef;

typedef struct Area_List_Inf{ Area_Inf_Typedef *Area_Inf; struct Area_List_Inf *next_Area_Inf; //用于指向下一個}Area_List_Inf_Typedef;

Area_List_Inf_Typedef *Head_Area_List; //鏈表的頭指針

由于在定義的時候,只定義了一個頭指針,那么它也只是個指向了Area_List_Inf_Typedef也就是鏈表結構體的指針,同樣沒有內(nèi)存空間,在沒有創(chuàng)建新增鏈表之前,它是一個野指針。

所以,在具體應用之前,需要先執(zhí)行一個初始化操作,也就是申請空間給鏈表管理結構體,然后頭指針指向這個空間。

/*** @brief 動態(tài)區(qū)鏈表初始化* @return int */int Area_List_Init(void){ //申請鏈表類型大小的空間,并讓頭指針指向它 Head_Area_List = (Area_List_Inf_Typedef*)malloc(sizeof(Area_List_Inf_Typedef)); if(Head_Area_List == NULL) return false; //同時要標記下一個信息為空 Head_Area_List-》next_Area_Inf = NULL; return true;}

通過PC下發(fā)一個新的區(qū)域信息后,增加新區(qū)域到鏈表末尾。

/*** @brief 在鏈表末尾增加一個區(qū)域參數(shù)* @param Area_Inf 增加的區(qū)域區(qū)參數(shù)指針* @return int */int Add_Area_ToList(Area_Inf_Typedef *Area_Inf){ Area_List_Inf_Typedef *p = Head_Area_List; while(p-》next_Area_Inf!=NULL) { p = p-》next_Area_Inf; } //先申請鏈表結構體的空間,因為后續(xù)還要繼續(xù)增加 p-》next_Area_Inf = (Area_List_Inf_Typedef*)malloc(sizeof(Area_List_Inf_Typedef)); if(p-》next_Area_Inf == NULL) return false;//申請不到內(nèi)存,返回失敗 //指向剛剛申請的空間,并為需要存放的動態(tài)區(qū)信息申請對應的內(nèi)存 p = p-》next_Area_Inf; p-》Area_Inf = (Area_Inf_Typedef*)malloc(sizeof(Area_Inf_Typedef)); if(p-》Area_Inf == NULL) { free(p);//由于申請失敗,先前申請的鏈表空間也要釋放 return false; } memcpy(p-》Area_Inf,Area_Inf,sizeof(Area_Inf_Typedef)); /*拷貝數(shù)據(jù)*/ p-》Area_Inf-》Area_Data = (uint8_t*)malloc(Area_Inf-》data_len); if(p-》Area_Inf-》Area_Data == NULL) { free(p-》Area_Inf); free(p); return false; } memcpy(p-》Area_Inf-》Area_Data,Area_Inf-》Area_Data,Area_Inf-》data_len); //標記這個鏈表的尾部 p-》next_Area_Inf=NULL; //添加成功 return true;}

通過PC下發(fā)一個刪除指定ID的區(qū)域命令。

/*** @brief 根據(jù)區(qū)域ID刪除動態(tài)區(qū)* @param num 區(qū)域ID* @return int */int Delete_Area_Accordingn_ID(int num){ int res = false; Area_List_Inf_Typedef *p = Head_Area_List; while(p-》next_Area_Inf!=NULL) { Area_List_Inf_Typedef *temp = p; p = p-》next_Area_Inf; if(p-》Area_Inf-》ID == num)//匹配到對應的值 { temp-》next_Area_Inf = p-》next_Area_Inf; //釋放內(nèi)存空間 free(p-》Area_Inf-》Area_Data); free(p-》Area_Inf); free(p); p=temp; res = true; } } return res;}

看了上面的驅(qū)動函數(shù),相信大家已經(jīng)明白,大家可以自行編寫一些驅(qū)動,下面我實現(xiàn)的三個簡單函數(shù)。

/*** @brief 根據(jù)區(qū)域ID找到鏈表* @param data_p 鏈表指針* @param num 區(qū)域ID編號* @return int */int Find_Area_According_ID(Area_Inf_Typedef **data_p,int num){ Area_List_Inf_Typedef *p = Head_Area_List; while(p-》next_Area_Inf!=NULL) { p = p-》next_Area_Inf; if(p-》Area_Inf-》ID == num)//匹配到對應的值 { *data_p = p-》Area_Inf; return true; } } return false;}/*** @brief 刪除所有區(qū)域* */int Delete_All_Area(void){ int res = false; Area_List_Inf_Typedef *p = Head_Area_List; while(p-》next_Area_Inf!=NULL) { Area_List_Inf_Typedef *temp = p; p = p-》next_Area_Inf; temp-》next_Area_Inf = p-》next_Area_Inf; //釋放內(nèi)存空間 free(p-》Area_Inf-》Area_Data); free(p-》Area_Inf); free(p); p=temp; res = true; } return res;}/*** @brief 打印鏈表信息* */void Printf_Area_Inf(void){ int i=0; Area_List_Inf_Typedef *p = Head_Area_List; printf(“l(fā)ist ID X Y Width Height Area_Data

”); while(p-》next_Area_Inf!=NULL) { p = p-》next_Area_Inf; printf(“ %d %d %d %d %d %d %s

”,i,p-》Area_Inf-》ID,p-》Area_Inf-》X,p-》Area_Inf-》Y,p-》Area_Inf-》Width,p-》Area_Inf-》Height,p-》Area_Inf-》Area_Data); i++; } printf(“----------------------end-----------------------

”);}

3、測試函數(shù)

下面編寫一個測試函數(shù),可以測試,鏈表的初始化,增加一個區(qū)域,刪除指定區(qū)域,根據(jù)ID返回區(qū)域信息,刪除所有區(qū)域接口。

/*** @brief 鏈表測試函數(shù)* */void list_main(){ int i,j; Area_Inf_Typedef temp; Area_Inf_Typedef **data_p; data_p = NULL; printf(“------------------List test---------------------

”); if(!Area_List_Init( )) { printf(“Memory fail.。

”); } for(i=0;i《5;i++) { temp.ID = i; temp.X = 5+i; temp.Y = i; temp.Width = 10+i; temp.Height = 10+i; temp.data_len = i+1; temp.Area_Data = (uint8_t*)malloc(temp.data_len+1); for(j=0;j《temp.data_len;j++) { temp.Area_Data[j] = j+0x30; } temp.Area_Data[j] = 0; if(!Add_Area_ToList(&temp)) { printf(“Add Area %d Area_Info fail

”,i); } } Printf_Area_Inf(); printf(“

-------------Delete ID of Area is 3-------------

”); Delete_Area_Accordingn_ID(3); Printf_Area_Inf(); temp.ID = 9; temp.data_len = 10; temp.Area_Data = (uint8_t*)malloc(temp.data_len+1); for(j=0;j《temp.data_len;j++) { temp.Area_Data[j] = j+0x30; } temp.Area_Data[j] = 0; if(!Add_Area_ToList(&temp)) { printf(“Add Area %d info fail

”,temp.ID); } printf(“

--------------Add ID of Area is 9---------------

”); Printf_Area_Inf(); Find_Area_According_ID(data_p,2); temp.ID = (*data_p)-》ID; Delete_All_Area(); printf(“

--------------Delete All Area-------------------

”); Printf_Area_Inf(); while(1);}

測試結果

6ef62022-9e2c-11eb-8b86-12bb97331649.png

IAR和keil工程代碼開源地址:

https://github.com/strongercjd/STM32_Linklist

(提示:公眾號不支持外鏈接,請復制鏈接到瀏覽器下載)

如果大家手中有板子可以調(diào)試,可以看《一文了解串口打印》文章,使用串口打印。如果臨時沒有板子可以debug,可以模擬測試,IAR設置如下:

選擇Simulator調(diào)試

6eff06a6-9e2c-11eb-8b86-12bb97331649.png

打開View-》TerminalI/O,就可以看到打印信息

6f0adc92-9e2c-11eb-8b86-12bb97331649.png

原文標題:鏈表在STM32中的應用

文章出處:【微信公眾號:玩轉單片機】歡迎添加關注!文章轉載請注明出處。

責任編輯:haq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • STM32
    +關注

    關注

    2313

    文章

    11197

    瀏覽量

    374848
  • 鏈表
    +關注

    關注

    0

    文章

    80

    瀏覽量

    11088
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    米爾MYD-YF13X引入STM32MP135F安全芯!系統(tǒng)、安全、功能三重升級

    MYD-YF135F 本次版本引入STM32MP135F 安全芯片 ,并推出基于該芯片的硬件平臺 MYD-YF135F。該組合提供以下硬件級安全能力: 該設計可以有效提升設備工業(yè)、物聯(lián)網(wǎng)及海外市場應用
    發(fā)表于 04-17 18:35

    引入STM32MP135F安全芯!米爾MYD-YF13X系統(tǒng)、安全、功能三重升級

    米爾電子MYD-YF13X平臺資料及SDK迎來重要更新。本次發(fā)布的V2.0.0版本系統(tǒng)版本、安全能力以及功能支持方面進行了全面升級。本次發(fā)布引入安全芯片STM32MP135F,并推出搭載該芯片
    的頭像 發(fā)表于 04-16 08:06 ?510次閱讀
    <b class='flag-5'>引入</b><b class='flag-5'>STM32</b>MP135F安全芯!米爾MYD-YF13X系統(tǒng)、安全、功能三重升級

    如何在 STM32Cube CMake 工程添加源文件

    STM32CubeMX 能夠很方便的導出 CMake 工程。例如,如下圖所示 STM32CubeMX的 ToolChain/IDE 中選擇 Cmake。CMake 工程可以很容易被
    發(fā)表于 04-15 16:07 ?0次下載

    STM32N6 PSRAM 上運行代碼的調(diào)試

    開發(fā)其產(chǎn)品過程,使用了 STM32N657X0H3Q。客戶的代碼很大,不能放在SRAM 上運行,想放在 PSRAM 上去運行,并咨詢?nèi)绾卧?STM32CubeIDE 上進行調(diào)試。2.2. 重現(xiàn)問題關于如何將用戶代碼放置
    發(fā)表于 04-15 16:02 ?0次下載

    LAT1621_STM32N6 PSRAM 上運行代碼的調(diào)試

    STM32N6 項目中,用戶代碼可能會比較大,此時僅用內(nèi)部 SRAM 并不能滿足用代碼運行需求。那么,將代碼放置到 PSRAM 上運行也是個不錯的選擇。?客戶開發(fā)其產(chǎn)品過程,使用了
    發(fā)表于 03-11 10:44 ?0次下載

    LAT1187+ Keil 中使用 STM32CubeProgrammer應用筆記

    STM32 MCU 新產(chǎn)品的早期用戶有時候會遇見工具鏈還在完善的情形,例如,一部分STM32 工具已經(jīng)支持該產(chǎn)品,而另外一部分 STM32 工具還在更新
    發(fā)表于 01-11 17:27 ?0次下載

    無數(shù)據(jù)域雙向鏈表的代碼

    ); return 0; } 在這個示例,我們定義了一個包含指向前一個節(jié)點和后一個節(jié)點的結構體 Node,以及一個包含整數(shù)數(shù)據(jù)和 Node 結構體的結構體 Data。然后實現(xiàn)了插入和打印鏈表的函數(shù)。在打
    發(fā)表于 12-11 06:56

    標準庫下配置的stm32f103x的spi引入rtthread后收發(fā)的消息就錯了,為什么?

    標準庫下配置的stm32f103x的spi引入rtthread后收發(fā)的消息就錯了,引入之前沒問題,請問這是啥情況
    發(fā)表于 10-13 08:07

    rt_object_get_information獲取到的鏈表為空怎么解決?

    rtt啟動過程,初始化堆的時候,進入rt_object_init,調(diào)用rt_object_get_information獲取到的鏈表為空,導致系統(tǒng)起不來。
    發(fā)表于 10-11 11:44

    rt-thread系統(tǒng),使用stm32,怎樣設置接收中斷字節(jié)數(shù)?

    rt-thread系統(tǒng),使用stm32,怎樣設置接收中斷字節(jié)數(shù)
    發(fā)表于 09-15 06:17

    【留言有獎】2025 STM32研討會,RT-Thread現(xiàn)場期待與你共會!| 活動預告

    2025年9月11日及9月17日,STM32研討會將走進北京和上海,為大家深入解讀STM32的中國戰(zhàn)略,并圍繞STM32不同領域的最新產(chǎn)品布局和生態(tài)展開主題演講,包括邊緣人工智能、電
    的頭像 發(fā)表于 09-07 11:10 ?525次閱讀
    【留言有獎】2025 <b class='flag-5'>STM32</b>研討會,RT-Thread<b class='flag-5'>在</b>現(xiàn)場期待與你共會!| 活動預告

    意法半導體:STM32CubeMX將不再集成到STM32CubeIDE

    從2025年11月發(fā)布的版本開始,我們將僅以 獨立 版本的形式提供 STM32CubeIDE 和 STM32CubeMX 。 STM32CubeMX將不再集成到STM32CubeIDE
    的頭像 發(fā)表于 09-01 17:18 ?3992次閱讀

    德國莫爾利用全新的在線配置器改進了電纜引入裝置設計流程

    MurrplastikSystemtechnik GmbH(德國莫爾系統(tǒng)技術有限公司)總部位于巴登符騰堡州奧本韋勒市,全球范圍內(nèi)開發(fā)、制造和銷售電纜管理系統(tǒng)、電纜標簽及組件。從機器人到食品行業(yè)
    發(fā)表于 08-20 14:29

    對于STM32CubeMx使用FMC的NAND FLASH里面配置這些時間有什么說明嗎?

    對于STM32CubeMx使用FMC的NAND FLASH里面配置這些時間有什么說明嗎?
    發(fā)表于 07-21 07:07

    STM32IDE如何設定代碼到ITCM運行?

    近期使用STM32MUX生成STM32IDE的代碼(MCU是STM32H743),目前希望可以將部分代碼定位到ITCM運行,加快處理速度,關于代碼
    發(fā)表于 06-24 06:45
    海安县| 富民县| 油尖旺区| 乌拉特后旗| 四川省| 旌德县| 锡林浩特市| 乌恰县| 神池县| 吉水县| 皋兰县| 宁陵县| 东丰县| 巨鹿县| 南雄市| 德令哈市| 含山县| 灵川县| 盐源县| 长沙县| 贵阳市| 墨竹工卡县| 沙田区| 名山县| 武山县| 水城县| 道孚县| 寿宁县| 安丘市| 武穴市| 红桥区| 青岛市| 花莲县| 内丘县| 灵璧县| 开化县| 慈溪市| 土默特左旗| 六枝特区| 尼玛县| 吉林省|