嵌入式C语言中CAN报文字节序问题的处理方法

友情提示:本期内容讨论的内容有烧脑,请大家做好心理准备 。【思想】隐隐感觉本文观看人数会是新低 。
1.什么是字节
使用CANdb++ 的小伙伴们肯定会注意到创建报文的时候有一个让我们选Intel或 。

嵌入式C语言中CAN报文字节序问题的处理方法

文章插图
这个问题在编程中叫做字节序问题,用来描述一个多字节数据【FLOAT/INT/结构体】是高字节在前还是低字节在前 。假设一个使用16进制表示的32位数据,需要将这个数据存放在内存地址从起的四个内存空间中
在低位的内存地址存放高有效字节的模式称为:大端序(big )
在低位的内存地址存放低有效字节的模式称为:小端序( )
这个问题的由来牵涉到两大CPU门派,的系列CPU和Intel的x86系列CPU 。系列采用big 方式存储数据,而Intel的x86系列则采用 方式存储数据 。也是DBC ++为什么使用/Intel来表述这个问题 。如果看完上述内容还在蒙圈的小伙伴我推荐下《总线架构29讲,一文彻底讲清CAN总线的intel和编码》,我相信同样的知识经不同人的表述会有不一样的传递效果 。
【嵌入式C语言中CAN报文字节序问题的处理方法】2.字节序对嵌入式CAN总线通讯的影响
由于集成电路处理小端序的效率比较高,所以大部分嵌入式芯片都采用小端序,这对CAN报文矩阵读取有不小的影响 。在《CAN总线(J1939)速成指南【1】》介绍了总线数据帧的结构中有一个8字节组成的数据域 。报文数据通过单片机的CAN接收中断函数获取,将数据存放对应的协议栈的数据数组中,通过共同体读取对应的数据,具体如何操作请温习下《嵌入式C语言环境下的CAN总线通讯协议》
无影响的完美矩阵
嵌入式C语言中CAN报文字节序问题的处理方法

文章插图
如果8字节的数据与只用来传输以1字节对齐的1字节数据,如下图
嵌入式C语言中CAN报文字节序问题的处理方法

文章插图
这样的报文矩阵非常整齐,每一个字节就对应一个字节的有效数据,这种情况是不会受到字节序问题的影响,直接通过共同体访问数据即可 。
稍微有点复杂
实际应用过程中像上面这种极端完美的结构式非常少见的,更多的是报文中会有16位或32位的数据类型,如下图
嵌入式C语言中CAN报文字节序问题的处理方法

文章插图
这样的结构存在8位、16位、32位的数据类型,但是数据都以1字节对齐 。遇到这样的报文不能通过共同体直接访问 。例如:需要把1、2字节放入一个16位的内存空间来表示的数据,这里就会收到字节序的影响 。处理这个问题最简单的办法就是接收数据后,调整报文数组的帧顺序 。
基于小端序的原则,将1、2字节对调,3、7字节对调并且4、5字节对调,调整过帧顺序后就能通过共同体变量进行数据访问 。
令人头疼的
《嵌入式C语言环境下的CAN总线通讯协议》也介绍过了实际开发中的报文矩阵可能更复杂,存在空位、数据长度也不是常见的8位、16位、32位、又不以1字节对齐,如下图:
嵌入式C语言中CAN报文字节序问题的处理方法

文章插图

嵌入式C语言中CAN报文字节序问题的处理方法

文章插图
该例子为之前《嵌入式C语言环境下的CAN总线通讯协议》使用的例子,这里我们就以1字节对齐划分最小的数据BLOCK,每个BLOCK的位长度均为8的整数倍 。
嵌入式C语言中CAN报文字节序问题的处理方法

文章插图
将0、1字节看作一个Block,将0、1字节进行对调;将2、3、4字节看作一个Block,将2、4字节进行对调,调整过帧顺序后就能通过共同体变量进行数据访问 。