Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
CANFD_fdcan
浅析STM32H7 FDCAN(二)
发布于 2021-12-19 22:44:01 浏览:2623
订阅该版
[tocm] # 一,认识 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 模块之间共用,,用户在配置的时候需要注意,如果配置错误将会导致发生异常情况。 ![image.png](https://oss-club.rt-thread.org/uploads/20211219/4dfcbe270639c0ae6bf2a9860c2df10a.png.webp) |寄存器 | 功能 | 元素大小 | 描述 | |----|----|----|----| | SIDFC.FLSSA | 最大支持128个元素 | 最多占用 128个 word| 11 bit 标准帧滤波器设置| | XIDFC.FLESA | 最大支持64个元素 | 最多占用 128 个 word | 29 bit 扩展帧滤波器设置 | | RXF0C.F0SA | 最大支持64个元素 | 最多占用 1152 个 word | RX FIFO0 的设置 | | RXF1C.F1SA | 最大支持64个元素 | 最多占用 1152 个 word | RX FIFO1 的设置 | | RXBC.RBSA | 最大支持64个元素 | 最多占用 1152 个 word | RX BUFF 的设置 | | TXEFC.EFSA | 最大支持32个元素 | 最多占用 64 个 word | TX EVENT FIFO 的设置 | | TXBC.TBSA | 最大支持32个元素 | 最多占用 576 个 word | TX BUFF 的设置 | | TMC.TMSA | 最大支持64个元素 | 最多占用 128 个 word | TT 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 标准帧滤波器配置) | StdFiltersNbr | 1(设置 1 个标准帧滤波器) | 1 | | XIDFC.FLESA(29 bit 标准帧滤波器配置) | ExtFiltersNbr| 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); ``` 上面的计算公式很好理解,就是每个 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. 距离第一篇鸽的时间有点久,以后不要再鸽了。
1
条评论
默认排序
按发布时间排序
登录
注册新账号
关于作者
whj467467222
开源,分享,交流,共同进步
文章
32
回答
1222
被采纳
149
关注TA
发私信
相关文章
1
ARTPi 的FDCAN使用官方工程如何发送数据?
2
STM32H750 FDCAN通信异常
3
ART-PI 的FDCAN功能使用
4
ART-PI FDCAN使用卡在rt_completion_wait处
5
ART PI FDCAN 死在rt_device_write
6
Art Pi FDCAN 到底能不能用呀?
7
CAN.c 与drv_fdcan.c兼容么?
8
出现这样的异常如何解决
9
能否有偿指导一下art-pi的hdcan使用
10
FDCAN报错 FDCAN报错
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
DMA
USB
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
I2C_IIC
ESP8266
UART
WIZnet_W5500
ota在线升级
cubemx
PWM
BSP
flash
freemodbus
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
编译报错
中断
Debug
rt_mq_消息队列_msg_queue
keil_MDK
ulog
SFUD
msh
C++_cpp
MicroPython
本月问答贡献
RTT_逍遥
7
个答案
2
次被采纳
三世执戟
7
个答案
1
次被采纳
KunYi
6
个答案
1
次被采纳
winfeng
2
个答案
1
次被采纳
chenyaxing
2
个答案
1
次被采纳
本月文章贡献
出出啊
1
篇文章
4
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
3
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
2
次点赞
回到
顶部
发布
问题
投诉
建议
回到
底部