基于链表的串口接收缓存

通过链表节点存储接收到的数据,每次查询链表头结点,如果有数据则进行处理,处理后头链表指针指向下一个节点。

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 轮询节点数据

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值