单片机学习小组
直播中

李宛蔓

7年用户 981经验值
私信 关注

怎样去解决循环队列接收缓冲区出现bug的问题呢

巡检机器人STM32控制板采用串口与工控机通信,循环队列接收缓冲区出现bug,导致循环获取历史数据包,怎么办呢?

回帖(1)

张早

2022-1-18 15:05:07
巡检机器人执行任务中出现bug,往复执行历史命令,排查了好几天,最后检查上位机串口没有发送数据,单片机debug也确认串口没有接收到新数据。最后的最后才debug32的串口数据缓存循环队列,发现代码中Lenght变量出现了问题。

typedef struct
{
uint16_t Head;//头指针
uint16_t Tail;//尾指针
uint16_t Lenght;//长度
uint8_t Ring_Buff[200];//缓冲大小
}RingBuff_t;
extern RingBuff_t ringBuff;
void RingBuff_Init();缓冲区初始化
uint8_t Write_RingBuff(uint8_t data);//入队
uint8_t Read_RingBuff(uint8_t *rData);//出队


void RingBuff_Init(void)
{
ringBuff.Head=0;
ringBuff.Tail=0;
ringBuff.Lenght=0;
}


uint8_t Write_RingBuff(uint8_t data)
{
if(ringBuff.Lenght>=200)
{
  return 1;
}
ringBuff.Ring_Buff[ringBuff.Tail]=data;
ringBuff.Tail=(ringBuff.Tail+1)%200;
ringBuff.Lenght++;
return 0;
}


uint8_t Read_RingBuff(uint8_t *rData)
{
//if(ringBuff.Head==ringBuff.Tail && ringBuff.Lenght==0)//我自己的问题代码在这!!!!
if(ringBuff.Lenght==0)
{
  return 1;
}
*rData=ringBuff.Ring_Buff[ringBuff.Head];
ringBuff.Head=(ringBuff.Head+1)%200;
ringBuff.Lenght--;
return 0;
}
原因分析:
我们采用的队列空判断条件用了两个,之前可能是为了保险,但最后出现了问题!首先刚进该if语句,判断第一个条件,假设队列不为空,则 ringBuff.Head==ringBuff.Tail 为false,刚好此时定时器中断来了,解析了数据,Lenght此时已经变为0,所以代码进入了下面这部分,Lenght-- 后变为很大的一个值,此时便出现了问题。
uint8_t Read_RingBuff(uint8_t *rData)
{
//问题代码!!!下面这个判断语句
if(ringBuff.Head==ringBuff.Tail && ringBuff.Lenght==0)
{
  return 1;
}
*rData=ringBuff.Ring_Buff[ringBuff.Head];
ringBuff.Head=(ringBuff.Head+1)%200;
ringBuff.Lenght--;
return 0;
}
举报

更多回帖

发帖
×
20
完善资料,
赚取积分