【通信协议】STM32 bxCAN —— 邮箱自动重发机制
1. 引言
在配置 STM32 的 bxCAN 的时候,一开始没有接总线节点,故没有应答。在打印处看到:初始化后 bxCAN 先将三个发送邮箱占满后,然后打印邮箱占满日志(这也是正常的,毕竟都满了)。
于是就搜索了一下到底是为什么:简单来说,就是打开自动重发后,不会自动释放邮箱,某个邮箱发送失败后就会一直占用这个邮箱重发;关闭自动重发后,某个邮箱发送失败后就会自动释放此邮箱,故一般来说只会占用邮箱 0 来发送/重发。
2. 关闭自动重发
如果总线上没有 ACK:
第 1 次调用:
报文 A → 邮箱 0
尝试发送一次
发送失败
邮箱 0 释放
第 2 次调用:
报文 B → 邮箱 0
尝试发送一次
发送失败
邮箱 0 释放
所以通常会反复看到:Mailbox: 0x01,但是邮箱释放 ≠ 发送成功。
关闭自动重发时,邮箱释放可能是因为:
- 报文发送成功;
- 报文发送失败;
- 仲裁丢失或其他错误导致本次请求结束。
3. 打开自动重发
假设总线上没有其他节点返回 ACK:
第 1 次调用:
报文 A → 邮箱 0
邮箱 0 持续自动重发,保持占用
第 2 次调用:
报文 B → 邮箱 1
邮箱 1 持续自动重发,保持占用
第 3 次调用:
报文 C → 邮箱 2
邮箱 2 持续自动重发,保持占用
第 4 次调用:
三个邮箱都被占用,无法添加报文
同一条发送请求只会一直留在它被分配到的那个邮箱里,不会从邮箱 0 移动到邮箱 1、2。
邮箱 0:报文 A,持续重发
邮箱 1:报文 B,持续重发
邮箱 2:报文 C,持续重发
由于三个报文都没有成功发送并收到 ACK,邮箱一直处于挂起状态,最终:
HAL_CAN_AddTxMessage() → HAL_ERROR
4. 对比
| 配置 | 当前报文发送成功 | 当前报文发送失败 |
|---|---|---|
| 自动重发开启 | 成功后邮箱释放 | 持续重发,邮箱保持占用 |
| 自动重发关闭 | 成功后邮箱释放 | 本次发送结束,邮箱释放 |
自动重发开启时,发送失败的报文会一直占用原来的邮箱;后续新报文再占用其他空闲邮箱,三个邮箱最终被占满。自动重发关闭时,发送失败的请求结束,邮箱自动释放,下一次循环通常又会使用邮箱 0。
博客导航
本文来自博客园,作者:膝盖中箭卫兵,转载请注明原文链接:https://www.cnblogs.com/hai-feng-dev/p/23530609

浙公网安备 33010602011771号
https://orcid.org/0000-0001-5102-772X