RAM是FDCAN里面非常重要的一个点,这和之前的STM32 bxCAN是最大的不同。STM32H7自带了10K的RAM,RAM的配置使用实现以下功能:
过滤器
接收先进先出
接收BUFF
发送事件 FIFO
发送BUFF
TTCAN
不会对Message RAM配置进行检查。Message RAM1和FDCAN2模块之间使用系统,用户在配置的时候需要注意,如果在配置错误时,会导致发生异常情况。


二,配置消息RAM
128 + 128 + 1152 + 1152 + 1152 + 64 + 576 + 128 = 4480
Message RAM 的大小是 1 Bytes, 也是在 00 个 word 的情况下。 RAM 的可配置去计算最多有 5 个 word 的范围。 Message RAM 的可配置范围是 5 到 5 个 word。 已经有 2560 个 word 的 RAM 已经有 2560 个 word 的范围了。大小,所以只能对 Message RAM 的大小进行合理的配置,保证 FDCAN 的正常工作。
uint32_t MessageRAMOffset; /*!< Specifies the message RAM start address.
This parameter must be a number between 0 and 2560 */
uint32_t StdFiltersNbr; /*!< Specifies the number of standard Message ID filters.
This parameter must be a number between 0 and 128 */
uint32_t ExtFiltersNbr; /*!< Specifies the number of extended Message ID filters.
This parameter must be a number between 0 and 64 */
uint32_t RxFifo0ElmtsNbr; /*!< Specifies the number of Rx FIFO0 Elements.
This parameter must be a number between 0 and 64 */
uint32_t RxFifo0ElmtSize; /*!< Specifies the Data Field Size in an Rx FIFO 0 element.
This parameter can be a value of @ref FDCAN_data_field_size */
uint32_t RxFifo1ElmtsNbr; /*!< Specifies the number of Rx FIFO 1 Elements.
This parameter must be a number between 0 and 64 */
uint32_t RxFifo1ElmtSize; /*!< Specifies the Data Field Size in an Rx FIFO 1 element.
This parameter can be a value of @ref FDCAN_data_field_size */
uint32_t RxBuffersNbr; /*!< Specifies the number of Dedicated Rx Buffer elements.
This parameter must be a number between 0 and 64 */
uint32_t RxBufferSize; /*!< Specifies the Data Field Size in an Rx Buffer element.
This parameter can be a value of @ref FDCAN_data_field_size */
uint32_t TxEventsNbr; /*!< Specifies the number of Tx Event FIFO elements.
This parameter must be a number between 0 and 32 */
uint32_t TxBuffersNbr; /*!< Specifies the number of Dedicated Tx Buffers.
This parameter must be a number between 0 and 32 */
uint32_t TxFifoQueueElmtsNbr; /*!< Specifies the number of Tx Buffers used for Tx FIFO/Queue.
This parameter must be a number between 0 and 32 */
uint32_t TxFifoQueueMode; /*!< Tx FIFO/Queue Mode selection.
This parameter can be a value of @ref FDCAN_txFifoQueue_Mode */
uint32_t TxElmtSize; /*!< Specifies the Data Field Size in a Tx Element.
This parameter can be a value of @ref FDCAN_data_field_size */
} FDCAN_InitTypeDef;
在以上的结构体中描述了 Message RAM 的配置。
与 Message RAM 配置表中的对应关系:
| 消息内存配置 | STM32 FDCAN 结构体成员|配置示例 RAM占用(字)|
|—|—|—|—|
| SIDFC.FLSSA(11位标准帧过滤器配置) | 标准过滤器Nbr | 1(设置1个标准框架) | 1 |
| XIDFC.FLESA(29位标准帧过滤器配置) | 外部过滤器Nbr| 1(设置1个扩展帧框架| 2 |
| RXF0C.F0SA(RX FIFO0的设置) | RxFifo0ElmtsNbr RxFifo0ElmtSize(可设置的大小为 8 ,12,16,20,24,32,48,64)| 10(字节长度为10的RX FIFO0) 18(每帧长度为64个) | 180 |
| RXF1C.F1SA(RX FIFO1的设置) | RxFifo1ElmtsNbr RxFifo1ElmtSize(可设置的大小为 8 ,12,16,20,24,32,48,64)| 10(字节长度为10的RX FIFO0) 18(每帧长度为64个) | 180 |
| RXBC.RBSA(RX BUFF 的设置) | RxBuffersNbr RxBufferSize(可设置的大小为 8 ,12,16,20,24,32,48,64)| 10( 10 个专用RX BUFF) 18(每帧长度为64个字节) | 180 |
|TXEFC.EFSA(TX EVENT FIFO的设置) | TxEventsNbr | 1 | 2 |
|TXBC.TBSA (TX BUFF 的设置) | TxBuffersNbr TxElmtSize + TxFifoQueueElmtsNbr TxElmtSize| 5 18(每帧长度为64个字节)+ 5 18| 180 |
|TMC.TMSA(TT CAN 的设置) | 无 | - | 0 |
STM32H7的HAL库中提供了计算方法:
hfdcan->msgRam.StandardFilterSA = SRAMCAN_BASE + (hfdcan->Init.MessageRAMOffset * 4U);
hfdcan->msgRam.ExtendedFilterSA = hfdcan->msgRam.StandardFilterSA + (hfdcan->Init.StdFiltersNbr * 4U);
hfdcan->msgRam.RxFIFO0SA = hfdcan->msgRam.ExtendedFilterSA + (hfdcan->Init.ExtFiltersNbr * 2U * 4U);
hfdcan->msgRam.RxFIFO1SA = hfdcan->msgRam.RxFIFO0SA + (hfdcan->Init.RxFifo0ElmtsNbr * hfdcan->Init.RxFifo0ElmtSize * 4U);
hfdcan->msgRam.RxBufferSA = hfdcan->msgRam.RxFIFO1SA + (hfdcan->Init.RxFifo1ElmtsNbr * hfdcan->Init.RxFifo1ElmtSize * 4U);
hfdcan->msgRam.TxEventFIFOSA = hfdcan->msgRam.RxBufferSA + (hfdcan->Init.RxBuffersNbr * hfdcan->Init.RxBufferSize * 4U);
hfdcan->msgRam.TxBufferSA = hfdcan->msgRam.TxEventFIFOSA + (hfdcan->Init.TxEventsNbr * 2U * 4U);
hfdcan->msgRam.TxFIFOQSA = hfdcan->msgRam.TxBufferSA + (hfdcan->Init.TxBuffersNbr * hfdcan->Init.TxElmtSize * 4U);
hfdcan->msgRam.EndAddress = hfdcan->msgRam.TxFIFOQSA + (hfdcan->Init.TxFifoQueueElmtsNbr * hfdcan->Init.TxElmtSize * 4U);
上面的公式很好的理解,就是每一个字是4个字节,SRAMCAN_BASE 是Message RAMset FD的计算地址。
MessageRAMOff FDCAN1 FDCAN2 的时候需要设置为0,在进行计算的时候需要根据配置来进行计算,ST可以直接设置一个EndAddress这个BASE的RAMOffset为FDCAN1的EndAddress - SRAM
下面的展示一个 Message RAM 的配置示例:
hfdcan->Init.MessageRAMOffset=0; //FDCAN1 信息RAM偏移为 0
hfdcan->Init.StdFiltersNbr=10; //标准信息ID滤波器个数为10
hfdcan->Init.ExtFiltersNbr=10; //扩展信息ID滤波器个数为10
hfdcan->Init.RxFifo0ElmtsNbr=10; //接收FIFO0元素个数
hfdcan->Init.RxFifo0ElmtSize=FDCAN_DATA_BYTES_64; //接收FIFO0 :64字节
hfdcan->Init.RxFifo1ElmtsNbr=0; //接收FIFO1元素个数
hfdcan->Init.RxFifo1ElmtSize=FDCAN_DATA_BYTES_64; //接收FIFO1:64字节
hfdcan->Init.RxBuffersNbr=0; //接收缓冲区个数
hfdcan->Init.RxBufferSize=FDCAN_DATA_BYTES_64; //接收BUFF:64字节
hfdcan->Init.TxEventsNbr=0; //发送事件个数
hfdcan->Init.TxBuffersNbr=0; //发送缓冲区个数
hfdcan->Init.TxFifoQueueElmtsNbr=10; //发送FIFO个数为10
hfdcan->Init.TxFifoQueueMode=FDCAN_TX_FIFO_OPERATION; //发送FIFO模式
hfdcan->Init.TxElmtSize=FDCAN_DATA_BYTES_64; //发送大小:64字节
可知前面的公司计算可以推导 Message RAM 的占用情况:
MessageRAMOffset = 0
StdFiltersNbr 占用 10 字
ExtFiltersNbr 占用 10 * 2 字
RxFifo0ElmtsNbr RxFifo0ElmtSize 占用 10 18 字
RxFifo1ElmtsNbr RxFifo1ElmtSize 占用 0 18 字
RxBuffersNbr RxBufferSize 占用 0 18 字
TxEventsNbr 占用 0 * 2 字
TxBuffersNbr 占用 0 * 18 字
TxFifoQueueElmtsNbr TxElmtSize 占用 10 18 字
误判0 + 180 = 390 word 390 * = 156 字节 = EndAdd FDCAN2 = MessageRAMOffset
有兴趣的时候可以在调试的时候下手动计算的。
三、总结
Message RAM 很灵活,为了确保正确的 HAL 库做了一些检查,有兴趣的可以去一下
消息RAM会影响到过滤模式,接收模式,发送,使用会逐一讲解
距离第一篇鸽子的时间有点久,以后不要再鸽了。
原作者:whj467467222