Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to use linked list in STM32

2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >

Share

Shulou(Shulou.com)06/01 Report--

This article mainly shows you "how to use linked list in STM32". The content is simple and easy to understand, and the organization is clear. I hope it can help you solve your doubts. Let Xiaobian lead you to study and learn "how to use linked list in STM32" this article.

1. Why introduce a linked list

In programs, we often face the problem that we need to save a certain number of objects, but the number of objects is uncertain, or it can increase or decrease at any time. The easiest way to do this is to create an array large enough to store these objects. I recently had a similar problem developing a project, so let me simplify it.

Requirements: Send coordinates and width and height information of some rectangles through PC, each area has an ID number, and fill certain data in these rectangles.

In general, the easiest thing to do is to limit yourself to a maximum of five regions, each storing 1K of data. So a struct like this is set up (similar to what object-oriented languages say about member properties).

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;

Then define the entity of the structure.

#define Area_Num 5#define Area_cache 1024 Area_Inf_Typedef Area_Info[Area_Num];uint8_t Area_Data[Area_Num*Area_cache];//Store area data/* Find area ID 5 and copy data out */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个区域,但是每个区域存储的数据很少,根本用不到1K。虽然上面的程序已经使用了宏定义,只需要修改宏定义就能实现要求。但这意味着不同的客户,需要编译不同的固件。 #define Area_Num 10#define Area_cache 512 这样的程序存在的问题: 1、在内存资源很紧缺的单片机程序中,当区域数据很少时,这种程序的处理方法浪费了大量的内存空间。 2、数值固定,需要存储更多区域,即使还有内存,还是需要修改宏定义,重新编译固件,不灵活。 这时需要引入链表来解决这个问题。 2、链表实现 链表实际上是线性表的链式存储结构,与数组不同的是,它是用一组任意的存储单元来存储线性表中的数据,存储单元不一定是连续的,且链表的长度不是固定的,链表数据的这一特点使其可以非常的方便地实现节点的插入和删除操作。链表的每个元素称为一个节点,每个节点都可以存储在内存中的不同的位置,为了表示每个元素与后继元素的逻辑关系,以便构成"一个节点链着一个节点"的链式存储结构,除了存储元素本身的信息外,还要存储其直接后继信息,因此,每个节点都包含两个部分,第一部分称为链表的数据区域,用于存储元素本身的数据信息。

对于上面的问题,我们使用链表解决,需要配合内存管理才能实现。内存管理这一块,大家可以自己编写内存管理驱动,也可以使用C库的malloc和free函数。如何字节编写内存管理驱动不是本文的重点,下文将使用C库的malloc和free函数进行内存管理。

使用链表的方式,在原有的成员属性结构体的前提上,还要再封装多一层链表管理。以单向链表为例:

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也就是链表结构体的指针,同样没有内存空间,在没有创建新增链表之前,它是一个野指针。

所以,在具体应用之前,需要先执行一个初始化操作,也就是申请空间给链表管理结构体,然后头指针指向这个空间。

/*** @brief 动态区链表初始化* @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下发一个新的区域信息后,增加新区域到链表末尾。

/*** @brief 在链表末尾增加一个区域参数* @param Area_Inf 增加的区域区参数指针* @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; } //先申请链表结构体的空间,因为后续还要继续增加 p->next_Area_Inf = (Area_List_Inf_Typedef*)malloc(sizeof(Area_List_Inf_Typedef)); if(p->next_Area_Inf == NULL) return false;//申请不到内存,返回失败 //指向刚刚申请的空间,并为需要存放的动态区信息申请对应的内存 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)); /*拷贝数据*/ 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下发一个删除指定ID的区域命令。

/*** @brief 根据区域ID删除动态区* @param num 区域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; //释放内存空间 free(p->Area_Inf->Area_Data); free(p->Area_Inf); free(p); p=temp; res = true; } } return res;}

看了上面的驱动函数,相信大家已经明白,大家可以自行编写一些驱动,下面我实现的三个简单函数。

/*** @brief 根据区域ID找到链表* @param data_p 链表指针* @param num 区域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 删除所有区域* */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; //释放内存空间 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("list ID X Y Width Height Area_Data\r\n"); while(p->next_Area_Inf!=NULL) { p = p->next_Area_Inf; printf(">3、测试函数

下面编写一个测试函数,可以测试,链表的初始化,增加一个区域,删除指定区域,根据ID返回区域信息,删除所有区域接口。

/*** @brief 链表测试函数* */void list_main(){ int i,j; Area_Inf_Typedef temp; Area_Inf_Typedef **data_p; data_p = NULL; printf("------------------List test---------------------\r\n"); if(!Area_List_Init( )) { printf("Memory fail..\r\n"); } for(i=0;i

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Internet Technology

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report