目录
CAN总线帧与位
CAN总线中传输信息是以报文为单位的,也就是我们一般的理解是CAN总线上跑的是一帧帧报文。
来源: 汽车CAN总线测试应用(一):总线解码分析_汽车测试技术__汽车测试网 (auto-testing.net)
然而实际传输中,总线上传输的原子/夸克级元素是位信号,也就是我们说的显性电平/隐形电平。而上文提到的报文也就是由这些位组成的。
如上图所示,一帧Classic CAN的报文其数据场中包含了8个字节,即64位数据(此处不考虑实际传输CAN总线的填充位),左侧数字为字节的序号。
CAN报文数据传输的顺序
实际传输中,一帧报文中的64位/8个字节数据是按照什么顺序传输的呢?
不卖官司直接上图:
一帧报文中的数据就是按照图中箭头所指示的路径传输的,看着也蛮简单的,那问题来了,标题中所提到位序和字节序是用来做什么的?
位序和字节序
顾名思义,位序(bit order)就是”位“的顺序,字节序(byte order)就是”字节“的顺序。很多同学可能会有疑问,上文中已经展示了CAN报文中位/字节的传输顺序,是否还有必要继续讨论这两个概念。其实我们思考清楚一个问题,就很容易理解此处讨论的位序和字节序的意义了。
问题:CAN总线数据在接收节点是如何解析的?
我们要从一个比较底层的角度来考虑这个问题,首先CAN上的报文或者说组成CAN报文的位其实是CAN节点实际想传输的信息的载体,CAN节点想传输的数据信息(信号是信息的形式表现)是由某几位或者某几个字节组成并且封装在CAN报文中。CAN信号到达接收节点的收发器处,经历最初的电信号到数字值转换,最终还是需要转化为具体的数据信息的,即还原最初的信号。接收节点如果想还原信号,需要经过如下两步:
- 基于信号的起始位置和终止位置获取原始数据。
- 根据位序或者字节序将原始数据转化为具体的信号值。
举个例子:
如上图所示,IVehOdo由3个字节构成,分别是Byte0,Byte1和Byte2,如果总线传输过来的数据是:
Byte0=0x12;
Byte1=0x34;
Byte3=0x56
那实际IVehOdo是0x123456,还是0x563412 或者又或是其他值呢?这里就需要字节序和位序来定义。我们通常用大端(Big Endian)和小端(Little Endian)来区分不同的字节序或位序。
采用上面的例子来解释一下大端和小端,发送节点发送信号IVehOdo=0x123456,信号是有高字节和低字节之分的,左边是高字节,右边是低字节,即0x12为高字节(MSB),0x56为低字节(LSB),这个可以简单类比数字有高位的万位、千位,低位有十位、个位理解。类似的,每个字节中的8个位也有高位(msb)和低位(lsb)。
信号要打包到报文中,报文的具体位置也有高低之分,一般可以简单理解如下图
基于字节序与位序大小端选择不同就会有4种组合,以下列出两种示意。
- 字节序大端+位序大端
- 字节序小端+位序大端
我们可以对大端和小端做出简单定义,
- 大端:高字节存放在低地址,低字节存放在高地址(大端从左往右)
- 小端:低字节存放在低地址,高字节存放在高地址(低放低,大端的逆序)
上文中的第二点就可以更具体描述为:基于字节序和位序是大端还是小端,将原始数据转化为具体的目标数据(信号值)。
Motorola格式和Intel格式
CAN报文的位序规定使用的是大端模式,作为总线设计者,不能更改设置。
我们工作中经常被提到的CAN的Motorola格式和Intel格式是字节序(Byte Order)的类型。
- Motorola:大端字节序
- Intel:小端字节序
总结
- CAN数据的传输顺序:从上到下,从左到右。
- 字节序和位序分为:大端和小端
大端:高字节存放在低地址,低字节存放在高地址(大端从左往右)
小端:低字节存放在低地址,高字节存放在高地址(低放低,大端的逆序)
- CAN数据的位序为大端
- CAN数据的字节序可以定义
Motorola:大端字节序
Intel:小端字节序