Motorola、Intel CAN 解析【结构体位域法】

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/m0_37280790/article/details/84197788

                               Motorola、Intel CAN 解析【结构体位域法】

嵌入式软件开发中大多都与CAN打交道,但是不同项目CAN协议以及格式均会有一定的差异,软件如何处理才会更加便捷,更加模块化呢?本文主要是小端格式CAN软件解析  “负负得正,将小端格式CAN转换为大端格式”

一:大端小端DBC文件对比  [修改DBC文件中信号的格式,DBC布局如下]

【左:大端;右:小端】

Compare 文本对比结果如下:【左:大端;右:小端】

 

二:软件解析CAN数据:

        基于结构体位域法解析CAN帧时就相当于大端格式,不需要其他转换操作,所以基于自动化工具生成代码时,只需对起始位及长度判断,即可自动生成自动化代码。【此处不详述自动化工具】如果客户CAN报文时小端格式,软件如何解析呢?【重点分析小端格式】

例:一个信号占3个字节:分别为12 34 56  ;

       如果是大端格式可理解成0x123456;小端格式;如果是小端格式可理解成0x563412;结合本例可以看出大端格式与位分配的格式是一致,而小端格式与位分配还是有一定的差距,那么如何实现软件解析呢?如果就这一个信号而言,小端与大端的区别就是Byte 0   对应 Byte 7 ;Byte 1   对应 Byte 6;Byte 2   对应 Byte 5;Byte 3   对应 Byte 4 ; 那么换句话说在接收帧数据时对CAN报文的Byte 进行调换即可;如果此时使用结构体位域法来解析这个数据,首先按照DBC的定义再次反向,得出Message结构体,从而“负负得正”,将小端格式CAN报文转换为大端格式,方便软件解读以及排查问题;下面主要讲述小端模式的CAN解析,结合上面的DBC布局可以知道:小端信号的起始位始终为Lsb;流程分析如下:

 

1):初始化参数Signal_Index:64

2):按照信号起始位对信号降序排列;并记录起始位及长度

3):逐个信号分析:

信号起始位+长度   = Signal_Index  ,则定义   uint32 信号:长度;

信号起始位+长度 != Signal_Index  ,则定义   uint32  :Signal_Index – 起始位-长度;

 

结合上述的分析方法,可以写个python小工具,从而自动生成代码;具体不细述!

附大端小端CAN解析代码:

1):小端模式下:

/* message CKJ :小端 */

typedef struct {
  uint32 : 3;
  uint32 ckj_5: 10;
  uint32 : 3;
  uint32 ckj_2: 8;
  uint32 : 12;
  uint32 ckj_6: 10;
  uint32 : 8;
  uint32 ckj_1: 10;
} CAN_Msg_CKJ_SIG_t;

typedef union{
    uint8 d_u[8];
        uint32 d_lw[2];
    CAN_Msg_CKJ_SIG_t sig;
}CAN_Msg_CKJ_DATA_t;

2):大端模式下:

/* message CKJ */

typedef struct {
  uint32 ckj_1: 10;
  uint32 : 8;
  uint32 ckj_6: 10;
  uint32 : 12;
  uint32 ckj_2: 8;
  uint32 : 3;
  uint32 ckj_5: 10;
) CAN_Msg_CKJ_SIG_t;

typedef union{
    uint8 d_u[8];   
    CAN_Msg_CKJ_SIG_t sig;
}CAN_Msg_CKJ_DATA_t;

展开阅读全文

没有更多推荐了,返回首页