IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 嵌入式 -> STM32H743 FDCAN FIFO接收管理分析 -> 正文阅读

[嵌入式]STM32H743 FDCAN FIFO接收管理分析

MCU:H743野火挑战者
其他文章:
STM32H743 FDCAN通信 接收中断如何实现
如何计算并设置CAN外设的波特率(基于STM32H7和HAL库)

在这里插入图片描述

前言

H743具备两个接收FIFO,分别是FIFO 0和FIFO 1,功能相同;H743提供的是FDCAN,FDCAN扩展帧允许单个消息中发送64个数据字节,而CAN 2.0有效负载数据最多可以发送8个字节。

当FDCAN接收到报文,经过过滤器过滤后,会将报文存储到FIFO或RX buffer中(可选,本文仅分析进入FIFO)。对于标准帧,H7提供了128个过滤器;对于扩展帧,H7提供了64个过滤器,每个过滤器都有一个自己的编号。各个过滤器处于并联关系,即只要通过一个过滤器就可以进入FIFO。那进入FIFO后,H7是如何保存这些报文,又是如何读取这些报文,并辨析报文对应何内容?这是本文想要探索的问题。

RAM过滤区

FDCAN外设可以配置两套验收滤波器:一套用于标准标识符,一种是扩展标识符,用于存储或拒绝接收到的消息。针对标准帧有128个元素,扩展帧则有64个元素。而滤波器的元素保存的是滤波器的基本设定,比如过滤的模式、ID等信息。
在这里插入图片描述
滤波器相当于审核的大门,这个大门可以设定在某个接收区域,比如FIFO 0或FIFO 1或RX buffer。如下图的代码, 则将标准滤波器0号安排给RXFIFO0守大门。
在这里插入图片描述
每个接收区域都可能不止一个滤波器,一般会从编号比较小的开始审核,如果通过了,就不再进行后面的审核。

接收区

下图是FDCAN外设对应消息RAM。图上显示FIFO0区域最多64个元素。在FDCAN中,消息的接收和发送意味着在RAM级别存储“元素”。 这个“元素”仅包含标识符,DLC,控制位(ESI,XTD,RTR,BRS,FDF),数据字段和特定的发送/接收位字段进行控制。就是一些信息+数据段。
在这里插入图片描述
一个FIFO元素,包含前面2个字(32位)的标识符内容,还有后面部分真正的数据段。
介绍部分标识符:
XTD:标准帧还是扩展帧;
RTR:数据帧还是扩展帧;
ID:标准帧的话11位ID,扩展帧的话29位ID;
FIDX:过滤器索引,代表这条报文是经过了哪条过滤器审核才进来的。加入一个过滤器只通过一个ID,那么我们就可以通过读取这个过滤器索引得知这个报文属于哪个ID。虽然说读索引效率比读ID效率高那么一丢丢,但是直接读ID不香吗?
在这里插入图片描述
每个元素的数据段都是可以设置的,最多64字节。前面两个固定2个字,后面数据x个字,x主要取决于接收的数据到底有多长。如果数据8个字节,则每个元素为数据分配2个字,再加上前面2个字,一共就是4个字,对应下表第一行。下表详细介绍了必要的“元素”大小,具体取决于数据字段范围。
在这里插入图片描述
而FIFO 0 包含64个这样的元素,理论上是可以同时保存64个报文。收到的报文通过滤波器后就会被整合成一个元素,放在FIFO 0这片区域。如果Rx FIFO已满(即传入超过64个报文且不读取),则可以根据两种不同模式来处理新到达的元素:

(1)阻塞模式:这是Rx FIFO的默认操作模式,没有其他元素写入RxFIFO,直到至少一个元素已被读出。
(2)覆盖模式:Rx FIFO中接受的新元素将覆盖Rx FIFO中最旧(最先接收的数据)的元素并且FIFO的put和get索引加1。

所以只要报文接收的速度没那么快,滤波器设置严格一点,读的勤快一点,FIFO还是没那么容易溢出的,毕竟有64个。

要从Rx FIFO读取元素,CPU必须执行以下步骤:
(1)读取寄存器FDCAN_RXF0S(FDCAN 接收 FIFO 0 状态寄存器)以了解FIFO 0的状态。
位24 F0F:0代表接收FIFO 0已满;1代表接收FIFO 0未满;
位21:16 F0PI 接收 FIFO 0 写入索引指针,范围为 0 到 63,即新的报文放在哪个位置;
位13: 8 F0GI 接收 FIFO 0 读取索引指针,范围为 0 到 63,即读取下一个报文从哪里开始读起;
位 6: 0 F0FL 接收 FIFO 0 中存储的元素数,范围为 0 到 64,即装了多少个未读的元素了。

(2)按照以下公式计算RAM中最旧的元素的地址:
Oldest element address = CAN_message_RAM_base_address + FDCAN_RXF0C.F0SA (start address) + FDCAN_RXF0S.F0GI (get Index) x Rx FIFO_element_size.
解释:CAN 消息RAM起始地址+FIFO的起始地址+读取索引指针*元素大小

(3)从计算出的地址中读取元素。

CPU从Rx FIFO读取一个元素或一系列元素后,它必须确认读取。确认后,FDCAN可以将相应的Rx FIFO缓冲区重新用于新元素。为了确认一个或多个元素,则CPU必须将从Rx FIFO读取的最后一个元素的缓冲区索引写入FDCAN_RXF0A(FDCAN 接收 FIFO 0 确认寄存器)。结果,FDCAN更新了FIFO填充级别和get索引。

这个寄存器位5:0为F0AI:主机从接收 FIFO 0 读取消息或消息序列后,必须将从接收 FIFO 0 读取的最后一个元素的
缓冲区索引写入 F0AI 中。此操作会将接收 FIFO 0 获取索引 RXF0S[F0GI] 设为 F0AI + 1,并会更新 FIFO 0 填充级别 RXF0S[F0FL]。通俗点讲,这个寄存器的值会传给上面那个状态寄存器,包括新的获取索引和填充级别。比如读完第4个元素,那获取索引应该是5。

看了这么多,觉得很复杂的朋友不用慌。上述过程HAL库已经整合成了一个函数。需要的时候引用就好,至于获取索引,填充级别之类的,函数内部已经设置好了。
在这里插入图片描述
虽说FIFO 0有64个元素,但不是默认就是使用64个的。需要自己设定使用多少个,多于设定值那就叫满溢。
在这里插入图片描述
下面还可以设置每个元素的数据段多少字节,还有FIFO 1的一些参数。这个在STM32 CubeMX就可以设置,生成的工程自带这些代码。
在这里插入图片描述

通过这篇文章,我们可以了解到FIFO是如何把通过滤波器的报文保存下来的,又是如何读取的。FIFO 1和RX BUFFER是同样的道理。在报文传递速度低的情况下, 只要函数内部保证读取的速度,其实就能保证FIFO不溢出。如果存在溢出,那么就得考虑滤波器的设置和满溢中断函数了。

参考
STM32之CAN—接收管理分析
STM32H7的CAN FD教程笔记

  嵌入式 最新文章
基于高精度单片机开发红外测温仪方案
89C51单片机与DAC0832
基于51单片机宠物自动投料喂食器控制系统仿
《痞子衡嵌入式半月刊》 第 68 期
多思计组实验实验七 简单模型机实验
CSC7720
启明智显分享| ESP32学习笔记参考--PWM(脉冲
STM32初探
STM32 总结
【STM32】CubeMX例程四---定时器中断(附工
上一篇文章      下一篇文章      查看所有文章
加:2021-07-15 16:21:57  更:2021-07-15 16:22:52 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/27 9:56:25-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计