通过链表节点存储接收到的数据,每次查询链表头结点,如果有数据则进行处理,处理后头链表指针指向下一个节点。
1.链表结构体
typedef struct
{
uint8_t data_len;
uint8_t* RecvBuf;
}Recv_Inf_Typedef;
typedef struct Recv_List_Inf
{
Recv_Inf_Typedef *Recv_Inf;
struct Recv_List_Inf *next_Recv_List_Inf; //用于指向下一个
}Recv_List_Inf_Typedef;
2.链接使用到的一些函数 :初始化、节点添加
volatile Recv_List_Inf_Typedef *g_pHead_List=NULL; //链表的头指针
/**
* @brief 动态区链表初始化
* @return int
*/
u8 Recv_List_Init(void)
{
// //申请链表类型大小的空间,并让头指针指向它
// g_pHead_List = (Recv_List_Inf_Typedef*)mymalloc(SRAM_H,sizeof(Recv_List_Inf_Typedef));
// if(g_pHead_List == NULL)
// return false;
// //同时要标记下一个信息为空
// g_pHead_List->Recv_Inf->data_len=0;
// g_pHead_List->Recv_Inf->RecvBuf=NULL;
// g_pHead_List->next_Recv_List_Inf = NULL;
return true;
}
/**
* @brief 在链表末尾增加一个区域参数
* @param nDataLen 数据长度 pBuf数据缓存
* @return int
*/
u8 Add_Area_ToList(u8 nDataLen,u8 *pBuf)
{
Recv_List_Inf_Typedef *p = (Recv_List_Inf_Typedef*)g_pHead_List;
if(g_pHead_List!=NULL)//不是第一次加数据
{
//查找最后一个节点
while(p->next_Recv_List_Inf!=NULL)
{
p = p->next_Recv_List_Inf;
}
//(1)-->申请链表空间,因为后续还要继续增加
p->next_Recv_List_Inf = (Recv_List_Inf_Typedef*)mymalloc(SRAM_H,sizeof(Recv_List_Inf_Typedef));
if(p->next_Recv_List_Inf == NULL)
return false;//申请不到内存,返回失败
//指向刚刚申请的空间,并为需要存放的动态区信息申请对应的内存
p = p->next_Recv_List_Inf;
}
else
{
//申请链表类型大小的空间,并让头指针指向它
g_pHead_List = (Recv_List_Inf_Typedef*)mymalloc(SRAM_H,sizeof(Recv_List_Inf_Typedef));
if(g_pHead_List == NULL)
return false;
p = (Recv_List_Inf_Typedef*)g_pHead_List;
}
//(2)-->申请链表结构体内结构体变量的空间
p->Recv_Inf = (Recv_Inf_Typedef*)mymalloc(SRAM_H,sizeof(Recv_Inf_Typedef));
if(p->Recv_Inf == NULL)
{
myfree(SRAM_H,p);//由于申请失败,先前申请的链表空间也要释放
return false;
}
p->Recv_Inf->data_len = nDataLen;
//memcpy(p->Recv_Inf,Recv_Inf,sizeof(Recv_Inf_Typedef));
//(3)-->申请链表结构体内结构体内接收数据的缓存空间
p->Recv_Inf->RecvBuf = (uint8_t*)mymalloc(SRAM_H,nDataLen);
if(p->Recv_Inf->RecvBuf == NULL)
{
myfree(SRAM_H,p->Recv_Inf);
myfree(SRAM_H,p);
return false;
}
/*拷贝数据*/
memcpy(p->Recv_Inf->RecvBuf,pBuf,nDataLen);
//标记这个链表的尾部
p->next_Recv_List_Inf=NULL;
//添加成功
return true;
}
/**
* @brief 删除当前节点并移动到下一个节点
* @param
* @return u8
*/
u8 DeleteCurList_And_MoveNextList(void)
{
int res = false;
Recv_List_Inf_Typedef *p = (Recv_List_Inf_Typedef*)g_pHead_List;
if(p==NULL)return true;
if(p->next_Recv_List_Inf==NULL)
{
//释放当前节点
myfree(SRAM_H,p->Recv_Inf->RecvBuf);//释放结构体内数组空间
myfree(SRAM_H,p->Recv_Inf);//释放链表内结构体空间
myfree(SRAM_H,p);//释放当前链表
g_pHead_List = NULL;
return true;
}
else
{
//存在下一个节点
//指向下一个节点
Recv_List_Inf_Typedef *temp = p->next_Recv_List_Inf;
//释放当前节点
myfree(SRAM_H,p->Recv_Inf->RecvBuf);//释放结构体内数组空间
myfree(SRAM_H,p->Recv_Inf);//释放链表内结构体空间
myfree(SRAM_H,p);//释放当前链表
//更新当前节点
p=temp;
res = true;
}
return res;
}
使用示例:伪代码
1.串口接收完一包数据后调用该函数 添加到数据加点
Add_Area_ToList(m_u16RxLen,(u8*)g_arrUart1RecvBuf);
2.查询当前节点数据长度 不为0说明有数据需要处理
u16 UART1_GetRecvDataLen(void)
{
if(g_pHead_List!=NULL)
{
return g_pHead_List->Recv_Inf->data_len;
}
return 0;
}
3.获取当前节点数据
int16 SP1_GetListBufPos(UINT16 nCurPos)
{
int16 nResult = -1;
if(g_pHead_List!=NULL)
{
return g_pHead_List->Recv_Inf->RecvBuf[nCurPos];
}
return nResult;
}
4.处理完一包数据后 删除当前节点数据,并移动到下一个节点
DeleteCurList_And_MoveNextList();
5.重复步骤2 轮询节点数据