本文内容需结合《CAN接收处理Rx handling》内容阅读旨在结合具体AURIX Rx配置C样例代码进行较为详细的AURIX CAN通信Rx配置。.rxConfig { .rxMode IfxCan_RxMode_dedicatedBuffers, .rxBufferDataFieldSize IfxCan_DataFieldSize_8, .rxFifo0DataFieldSize IfxCan_DataFieldSize_8, .rxFifo1DataFieldSize IfxCan_DataFieldSize_8, .rxFifo0OperatingMode IfxCan_RxFifoMode_blocking, .rxFifo1OperatingMode IfxCan_RxFifoMode_blocking, .rxFifo0WatermarkLevel 0, .rxFifo1WatermarkLevel 0, .rxFifo0Size 0, .rxFifo1Size 0 },在对CAN node进行配置时需要对CAN的Rx进行初始化和配置下面结合Infineon iLLD对CAN Rx的配置进行介绍首先先看Rx配置的结构体typedef struct { IfxCan_RxMode rxMode; /** \brief Rx Buffers or FIFO 0 or combination Mode of reception */ IfxCan_DataFieldSize rxBufferDataFieldSize; /** \brief Rx Buffer Data Field Size */ IfxCan_DataFieldSize rxFifo0DataFieldSize; /** \brief Rx FIFO 0 Data Field Size */ IfxCan_DataFieldSize rxFifo1DataFieldSize; /** \brief Rx FIFO 1 Data Field Size */ IfxCan_RxFifoMode rxFifo0OperatingMode; /** \brief Rx FIFO 0 operating mode */ IfxCan_RxFifoMode rxFifo1OperatingMode; /** \brief Rx FIFO 1 operating mode */ uint8 rxFifo0WatermarkLevel; /** \brief Rx FIFO 0 watermark level */ uint8 rxFifo1WatermarkLevel; /** \brief Rx FIFO 1 watermark level */ uint8 rxFifo0Size; /** \brief Rx FIFO 0 Size */ uint8 rxFifo1Size; /** \brief Rx FIFO 1 Size */ } IfxCan_Can_RxConfig;CPU的MCMCAN Rx配置包括Rx的模式配置、FIFO大小以及操作模式、Buffer大小等。RxModetypedef enum { IfxCan_RxMode_dedicatedBuffers, /** \brief Rx dedicated buffers operation */ IfxCan_RxMode_fifo0, /** \brief Rx FIFO 0 operation */ IfxCan_RxMode_fifo1, /** \brief Rx FIFO 1 operation */ IfxCan_RxMode_sharedFifo0, /** \brief Rx shared dedicated buffers and Rx FIFO 0 operation */ IfxCan_RxMode_sharedFifo1, /** \brief Rx shared dedicated buffers and Rx FIFO 1 operation */ IfxCan_RxMode_sharedAll /** \brief Rx shared dedicated buffers and Rx FIFO 0 and Rx FIFO 1 operation */ } IfxCan_RxMode;RxMode描述的是Rx接收模式的组合IfxCan_RxMode_fifo0、IfxCan_RxMode_fifo1、IfxCan_RxMode_dedicatedBuffers这三个枚举值的含义是只用单个模式接收FIFO0、FIFO1、Buffer单个模式接收。IfxCan_RxMode_sharedFifo0指的是buffer和FIFO0 share即Rx接收到的报文可存储到FIFO0以及Buffer当中IfxCan_RxMode_sharedFifo1指的是buffer和FIFO1 share即Rx接收到的报文可存储到FIFO1以及Buffer当中IfxCan_RxMode_sharedAll指的是全部空间都可以接收包含Buffer以及FIFO0和1。注意rxMode配置非芯片寄存器配置而只用于软件配置逻辑区分如下iLLD配置FIFO和buffer时使用巧妙的取“子集”的方式进行配置如mode是Buffer或share那么一定需要配置Buffer那么buffer就是子集先把buffer相关的数据长度以及地址配置完成如果mode是FIFO0或者share那么FIFO0就是子集再把FIFO0相关的配置项给配好。代码通过检查 rxMode配置值动态选择配置不同的Rx Buffer或Rx FIFO确保适应不同的 CAN 通信需求。所以解释了RxMode 本身是一个软件配置项它不是硬件寄存器中的一个直接属性。IfxCan_DataFieldSize rxBufferDataFieldSize这个字段配置的是RxBuffer内部一个数据元素当中的数据字段的长度分别有如下几个选项typedef enum { IfxCan_DataFieldSize_8, /** \brief 8 byte data field */ IfxCan_DataFieldSize_12, /** \brief 12 byte data field */ IfxCan_DataFieldSize_16, /** \brief 16 byte data field */ IfxCan_DataFieldSize_20, /** \brief 20 byte data field */ IfxCan_DataFieldSize_24, /** \brief 24 byte data field */ IfxCan_DataFieldSize_32, /** \brief 32 byte data field */ IfxCan_DataFieldSize_48, /** \brief 48 byte data field */ IfxCan_DataFieldSize_64 /** \brief 64 byte data field */ } IfxCan_DataFieldSize;IFX_INLINE void IfxCan_Node_setRxBufferDataFieldSize(Ifx_CAN_N *node, IfxCan_DataFieldSize size) { node-RX.ESC.B.RBDS size; }为什么只关心数据字段的长度呢因为除了数据字段之外其他字段的长度都是固定的不需要配置其字段布置基本符合CAN帧的字段分布所以一个FIFO/Buffer element的长度大小基本取决于数据段的大小如上表是RBDS配置值和数据域段的字节数的对应关系以及和FIFO Element Size的对应关系可以看到FIFO Element Size的单位是RAM words一个RAM words是4Byte所以其他字段占据的大小以第一行为例就为4 * 4Byte - 8Byte 8Byte也就是两个RAM words。对比Buffer/FIFO element的域段定义也可知注意该表第一行为bit域段手册表格有所压缩R0 (Rx Buffer / FIFO 元素的第一个字段)ANMF (Acceptance Filter Match Flag)表示该消息是否通过了接收过滤器的匹配。通常用来指示消息是否符合设定的过滤条件。ESI (Error State Indicator)错误状态指示器指示消息是否有错误。XTD (Extended Identifier)扩展标识符标志位标识该消息是标准CAN标识符11 位还是扩展标识符29 位。RTR (Remote Transmission Request)远程传输请求标志表示该消息是否是远程请求帧Remote Frame。ID[28:0] (Identifier)存储消息的标识符ID通常包括标准或扩展帧的标识符。如果是扩展帧会占用更多的位。R1 (Rx Buffer / FIFO 元素的第二个字段)FIDX[6:0](Filter Index)表示该消息的过滤器索引指示是哪一个过滤器匹配了这条消息。FDF(FD Format)表示该消息是否为CAN FD格式。CAN FD允许更大的数据段传输最多64字节。BRS(Bit Rate Switch)指示该消息是否使用了Bit Rate Switching即是否在CAN FD帧中使用不同的波特率传输数据部分。DLC[3:0](Data Length Code)表示数据字段的长度以字节为单位。通常这个字段的值表示数据字段的大小CAN 2.0的最大数据长度为8字节而CAN FD的最大数据长度可以达到64字节。RXTS[15:0] (Receive Timestamp)接收到的消息的时间戳表示消息被接收的时间。R2 (Rx Buffer / FIFO 元素的第三个字段)DB3[7:0] 到 DBm-1[7:0]这些是数据字节字段Data Bytes用于存储实际的数据部分。每个DBx存储8位数据即1字节。消息的实际数据会被依次存储在这些字段中。数据字段的排列方式这个表格将消息的字段按顺序排列每一行代表Message Element中的一个字节段包含标识符、控制信息、数据字段等。由此可得R0和R1为数据段之外的其他字段占据64bit即8个字节2个RAM Words。所以该字段配置要区分是否为CAN FD帧FD帧最大支持64字节的数据段如果这里错配成标准帧的8字节会导致数据丢失。/* set Rx buffers start address in the Message RAM */ IfxCan_Node_setRxBuffersStartAddress(nodeSfr, config-messageRAM.rxBuffersStartAddress);另外对于Rx Buffer的设置除了需要设置数据段大小之外还需要设置Buffer的起始地址这部分寄存器属于message ram的配置组中定义IfxCan_DataFieldSize rxFifo0DataFieldSize该字段配置的是FIFO的元素的数据段大小大体跟RxBuffer是相同的不予赘述需要注意的还是如果实际报文数据段的长度大于我们配置的数据段长度那么多出来的那一部分就会被丢弃。IfxCan_RxFifoMode rxFifo0OperatingMode;uint8 rxFifo0WatermarkLevel;uint8 rxFifo0Size;这三个字段来自RXF0Ci寄存器分别代表FIFO的操作模式、水位线、和FIFO的大小具体释义如下配置代码IFX_INLINE void IfxCan_Node_setRxFifo0OperatingMode(Ifx_CAN_N *node, IfxCan_RxFifoMode mode) { node-RX.F0C.B.F0OM mode; } IFX_INLINE void IfxCan_Node_setRxFifo0Size(Ifx_CAN_N *node, uint8 size) { node-RX.F0C.B.F0S size; } IFX_INLINE void IfxCan_Node_setRxFifo0WatermarkLevel(Ifx_CAN_N *node, uint8 level) { node-RX.F0C.B.F0WM level; }mode就是FIFO的block mode和over write mode各个模式的介绍详见《CAN接收处理Rx handling》。