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

本文转载在我的微信公众号:古德曼汽车工业。

希望关注本专栏的朋友,也能一并关注微信公众号。

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

友情提示:本期内容讨论的内容有烧脑,请大家做好心理准备。【思想】隐隐感觉本文观看人数会是新低。

1.什么是字节

使用CANdb++ Editor的小伙伴们肯定会注意到创建报文的时候有一个ByterOrder让我们选Intel或Motorola。

嵌入式C语言中CAN报文字节序问题的处理方法_第1张图片

 

这个问题在编程中叫做字节序问题,用来描述一个多字节数据【FLOAT/INT/结构体】是高字节在前还是低字节在前。假设一个使用16进制表示的32位数据0x12345678,需要将这个数据存放在内存地址从0x8000起的四个内存空间中

在低位的内存地址存放高有效字节的模式称为:大端序(big endian)

在低位的内存地址存放低有效字节的模式称为:小端序(little endian)

这个问题的由来牵涉到两大CPU门派,Motorola的PowerPC系列CPU和Intel的x86系列CPU。PowerPC系列采用big endian方式存储数据,而Intel的x86系列则采用little endian方式存储数据。也是DBC Editor++为什么使用Motorola/Intel来表述这个问题。如果看完上述内容还在蒙圈的小伙伴我推荐下《总线架构29讲,一文彻底讲清CAN总线的intel和Motorola编码》,我相信同样的知识经不同人的表述会有不一样的传递效果。

2.字节序对嵌入式CAN总线通讯的影响

由于集成电路处理小端序的效率比较高,所以大部分嵌入式芯片都采用小端序,这对CAN报文矩阵读取有不小的影响。在《CAN总线(J1939)速成指南【1】》介绍了总线数据帧的结构中有一个8字节组成的数据域。报文数据通过单片机的CAN接收中断函数获取,将数据存放对应的协议栈的数据数组中,通过共同体读取对应的数据,具体如何操作请温习下《嵌入式C语言环境下的CAN总线通讯协议》

无影响的完美矩阵

如果8字节的数据与只用来传输以1字节对齐的1字节数据,如下图

嵌入式C语言中CAN报文字节序问题的处理方法_第2张图片

这样的报文矩阵非常整齐,每一个字节就对应一个字节的有效数据,这种情况是不会受到字节序问题的影响,直接通过共同体访问数据即可。

稍微有点复杂

实际应用过程中像上面这种极端完美的结构式非常少见的,更多的是报文中会有16位或32位的数据类型,如下图

嵌入式C语言中CAN报文字节序问题的处理方法_第3张图片

这样的结构存在8位、16位、32位的数据类型,但是数据都以1字节对齐。遇到这样的报文不能通过共同体直接访问。例如:需要把1、2字节放入一个16位的内存空间来表示UINT16的数据,这里就会收到字节序的影响。处理这个问题最简单的办法就是接收数据后,调整报文数组的帧顺序。

嵌入式C语言中CAN报文字节序问题的处理方法_第4张图片

基于小端序的原则,将1、2字节对调,3、7字节对调并且4、5字节对调,调整过帧顺序后就能通过共同体变量进行数据访问。

令人头疼的

《嵌入式C语言环境下的CAN总线通讯协议》也介绍过了实际开发中的报文矩阵可能更复杂,存在空位、数据长度也不是常见的8位、16位、32位、又不以1字节对齐,如下图:

嵌入式C语言中CAN报文字节序问题的处理方法_第5张图片

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

嵌入式C语言中CAN报文字节序问题的处理方法_第6张图片

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

3.实际操作问

实际工程中CAN总线协议报文会非常多,如果仅仅靠人工一个一个调整报文顺序,首先时间成本就会很高,更可怕的是这样会增加误操作的概率,会给后面的开发造成非常【不可思议】的问题。因为高低字节反了,解析出来的数据自然也会有很大的问题。幸亏懒惰是第一生产力,这种操作通常需要运用自动化工具解决,这里分享下【思想】自制偷懒工具的思路。

嵌入式C语言中CAN报文字节序问题的处理方法_第7张图片

首先需要能够解析dbc文件,读取报文的id,设置报文周期

嵌入式C语言中CAN报文字节序问题的处理方法_第8张图片

解析报文矩阵,同时对dbc文件中不存在的空位进行填补,使之成为完整的Block

嵌入式C语言中CAN报文字节序问题的处理方法_第9张图片

生成结构体数据的同时,对Block进行划分,这一步主要是为了后面调试核对方便

嵌入式C语言中CAN报文字节序问题的处理方法_第10张图片

上图中未被模糊的部分就是自动化工具根据划分的Block结果自动生成的报文数组顺序调整的代码。

 

-----=========推荐阅读==========-----

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

■ 嵌入式C语言环境下的CAN总线通讯协议

■ Simulink代码生成提高教程

■ 增程式混合动力系统动力经济性仿真

■ S-Funciton应用实例

■ 汽车工程师眼中的C#

■ 工况路普的采集与数据处理

■ 混合动力节油的秘密-发动机万有特性

■ AVL-CRUISE纯电动仿真策略提高教程

■ AVL-CRUISE纯电动模型仿真策略

■ Simulink代码生成应用教程

■ Sinmulink代码生成基础体验教程

■ 燃料电池车(FCHEV)动力经济性建模与仿真

嵌入式C语言中CAN报文字节序问题的处理方法_第11张图片

你可能感兴趣的:(CAN总线,代码生成,C语言)