浅析STM32H7 FDCAN(二)

一,认识 Message RAM

消息 RAM 是 FDCAN 里面非常重要的一个点,这也是和之前的 STM32 bxCAN 最大的不同。
STM32H7 自带了 10K 的消息 RAM,消息 RAM 的配置用来实现以下功能:

  1. 过滤器
  2. 接收 FIFO
  3. 接收 BUFF
  4. 发送事件 FIFO
  5. 发送 BUFF
  6. TTCAN

系统 不会 对 Message RAM 配置进行检查。Message RAM 在 FDCAN1 和 FDCAN2 模块之间共用,,用户在配置的时候需要注意,如果配置错误将会导致发生异常情况。
在这里插入图片描述

寄存器功能元素大小描述
SIDFC.FLSSA最大支持128个元素最多占用 128个 word11 bit 标准帧滤波器设置
XIDFC.FLESA最大支持64个元素最多占用 128 个 word29 bit 扩展帧滤波器设置
RXF0C.F0SA最大支持64个元素最多占用 1152 个 wordRX FIFO0 的设置
RXF1C.F1SA最大支持64个元素最多占用 1152 个 wordRX FIFO1 的设置
RXBC.RBSA最大支持64个元素最多占用 1152 个 wordRX BUFF 的设置
TXEFC.EFSA最大支持32个元素最多占用 64 个 wordTX EVENT FIFO 的设置
TXBC.TBSA最大支持32个元素最多占用 576 个 wordTX BUFF 的设置
TMC.TMSA最大支持64个元素最多占用 128 个 wordTT CAN 的设置

二,配置 Message RAM

Message RAM 的大小是 10K Bytes,也就是 2560 个 word。如果都按照最大的配置去计算则会超出 Message RAM 的可配置范围。
128 + 128 + 1152 + 1152 + 1152 + 64 + 576 + 128 = 4480
在未开启 FDCAN2 的情况下,4480 word 已经远远超过了 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 配置表中的对应关系:

Message RAM 配置STM32 FDCAN 结构体成员配置举例RAM 占用(word)
SIDFC.FLSSA(11 bit 标准帧滤波器配置)StdFiltersNbr1(设置 1 个标准帧滤波器)1
XIDFC.FLESA(29 bit 标准帧滤波器配置)ExtFiltersNbr1(设置 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 的设置)TxEventsNbr12
TXBC.TBSA (TX BUFF 的设置)TxBuffersNbr * TxElmtSize + TxFifoQueueElmtsNbr * TxElmtSize5 * 18(每帧长度是 64 个字节)+ 5 * 18180
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);

上面的计算公式很好理解,就是每个 word 是 4 个字节,SRAMCAN_BASE 是 Message RAM 的起始地址。
MessageRAMOffset 在 FDCAN1 的时候一定要设置为 0 ,在 FDCAN2 的时候需要根据配置来进行计算,ST 这里很贴心的帮忙做了一个 EndAddress ,这样 FDCAN2 的 MessageRAMOffset 可以直接设置为 FDCAN1 的 EndAddress - SRAMCAN_BASE 。

以下的例子展示一个 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 的占用情况:

  1. MessageRAMOffset = 0
  2. StdFiltersNbr 占用 10 word
  3. ExtFiltersNbr 占用 10 * 2 word
  4. RxFifo0ElmtsNbr * RxFifo0ElmtSize 占用 10 * 18 word
  5. RxFifo1ElmtsNbr * RxFifo1ElmtSize 占用 0 * 18 word
  6. RxBuffersNbr * RxBufferSize 占用 0 * 18 word
  7. TxEventsNbr 占用 0 * 2 word
  8. TxBuffersNbr 占用 0 * 18 word
  9. TxFifoQueueElmtsNbr * TxElmtSize 占用 10 * 18 word

共计占用:10 + 20 + 180 + 180 = 390 word = 390 * 4 = 1560 byte = EndAddress = FDCAN2 的 MessageRAMOffset
有兴趣的可以在调试的时候看下手动计算的是否有误。

三,总结

  1. Message RAM 很灵活,为了保证正确 HAL 库做了很多检查,有兴趣的可以去看一下
  2. Message RAM 会影响到滤波器,接收模式,发送模式,后续章节将逐一讲解
  3. 距离第一篇鸽的时间有点久,以后不要再鸽了。
  • 4
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
STM32F429的时钟树是指单片机内部的各个时钟信号的分配和配置。根据引用\[2\]中提到的,STM32F429的时钟树是由RCC(复位和时钟控制)模块控制的。在时钟树中,SYSCLK是系统时钟,它是由PLL(锁相环)倍频后的时钟信号提供的,最高可达180MHz。引用\[3\]中提到,如果只使用外部晶体振荡器(HSE)作为时钟源,系统运行速度会很慢,为了加快运行速度,需要使用PLL进行倍频。需要注意的是,如果使用内部振荡器(HSI)作为时钟源,PLL将失去作用。因此,通过配置RCC模块,可以选择合适的时钟源和倍频因子来配置STM32F429的时钟树。 #### 引用[.reference_title] - *1* *3* [【STM32】F429单片机的时钟系统浅析](https://blog.csdn.net/weixin_43414694/article/details/109682528)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [STM32F429--RCC时钟树](https://blog.csdn.net/ABCisCOOL/article/details/106209406)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值