飞道的博客

嵌入式C语言中数据缓冲技术的应用实现

426人阅读  评论(0)

在嵌入式项目开发中,经常会涉及到数据的交互。比如汽车电子产品中的CAN通信,数据的收发经常是偶发的,一般有事件产生,就会回触发一些网络数据,这些网络数据在总线上往往是偶尔产生的,而且可能会集中触发。但是对于单个处理器,是不能及时处理多个集中触发的任务的,因此必须要借助数据缓冲技术。当然首先需要硬件资源支持,再才能通过软件依次处理这些缓冲数据。

我们先来看一下CAN总线系统:

 

我们还是以实际项目举例,比如选用NXP KEA128的单片机,其CAN接收、发送缓冲区特性描述如下:

• 采用FIFO 存储方案的5个接收缓冲区

• 3 个发送缓冲区,采用“本地优先级”概念进行内部排序

这里相当于接收有5个缓冲区,发送有3个缓冲区。接收一般多于发送,因为发送是主动的,可控的;而接收是被动的,不可控的。

接收报文缓冲采用如下的结构:

 

从Rx0到Rx4,采用FIFO也就是先进先出的原则。硬件接收缓冲器有5个,也就是说这款处理器,在一个处理周期内,底层最多存放5个数据帧,也就是说同一时间内只能接收5个数据帧,多了就会被覆盖掉。

接收报文中断函数


  
  1. void MSCAN_RX_Handler( void)
  2. {
  3. stMsgBuf * pBuf;
  4. ......
  5. pBuf = &(RxMsgBuf[RMB_i]);
  6. pBuf->Dat[ 0] = MSCAN_REDSR0;
  7. pBuf->Dat[ 1] = MSCAN_REDSR1;
  8. pBuf->Dat[ 2] = MSCAN_REDSR2;
  9. pBuf->Dat[ 3] = MSCAN_REDSR3;
  10. pBuf->Dat[ 4] = MSCAN_REDSR4;
  11. pBuf->Dat[ 5] = MSCAN_REDSR5;
  12. pBuf->Dat[ 6] = MSCAN_REDSR6;
  13. pBuf->Dat[ 7] = MSCAN_REDSR7;
  14. pBuf->DatLen = (MSCAN_RDLR & 0x0F);
  15. pBuf->IDReg[ 0] = MSCAN_RSIDR0;
  16. pBuf->IDReg[ 1] = MSCAN_RSIDR1;
  17. RMB_i++;
  18. if (RMB_i >= 5)
  19. {
  20. RMB_i = 0;
  21. }
  22. ......
  23. }

依靠中断函数接收到的所有报文,尽量要在一个时间片里全部处理完成。如果处理不完,就必须用到二级缓存,二级缓存的空间可以比实际硬件缓存空间定义得大一点。比如这里的RxMsgBuf[RMB_i],可以定义8到16个缓冲空间。那么接收中断函数就可以改成:


  
  1. void MSCAN_RX_Handler( void)
  2. {
  3. stMsgBuf * p2Buf;
  4. ......
  5. p2Buf = &(RxMsg2Buf[RM2B_i]);
  6. p2Buf->Dat[ 0] = MSCAN_REDSR0;
  7. p2Buf->Dat[ 1] = MSCAN_REDSR1;
  8. p2Buf->Dat[ 2] = MSCAN_REDSR2;
  9. p2Buf->Dat[ 3] = MSCAN_REDSR3;
  10. p2Buf->Dat[ 4] = MSCAN_REDSR4;
  11. p2Buf->Dat[ 5] = MSCAN_REDSR5;
  12. p2Buf->Dat[ 6] = MSCAN_REDSR6;
  13. p2Buf->Dat[ 7] = MSCAN_REDSR7;
  14. p2Buf->DatLen = (MSCAN_RDLR & 0x0F);
  15. p2Buf->IDReg[ 0] = MSCAN_RSIDR0;
  16. p2Buf->IDReg[ 1] = MSCAN_RSIDR1;
  17. RM2B_i++;
  18. if (RM2B_i >= 16)
  19. {
  20. RM2B_i = 0;
  21. }
  22. ......
  23. }

这里的“二级缓存”,实际上是一个纯软件概念。就是为了解决如果一个时间片处理不完当前收到的所有报文,是可以累积到下个时间片再处理的。中断函数只负责把收到的报文往二级缓存里放,当然这里放满了16个的话,也会产生二级缓存溢出,所以应用层的处理函数也需要及时去提取报文做处理。

与之相对应的发送报文缓冲采用如下的结构:

 

其实和接收报文的缓冲原理上差不多,只是优先级可以自己配置。相对接收实现起来会比较简单,也不需要建立二级缓存,因为完全可以自己控制发送流量。

 

原文:https://www.toutiao.com/i6951918761750315553/


转载:https://blog.csdn.net/daocaokafei/article/details/116245767
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场