【通信协议】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。

博客导航

博客导航

posted @ 2026-11-03 08:40  膝盖中箭卫兵  阅读(2)  评论(0)    收藏  举报
ORCID iD icon https://orcid.org/0000-0001-5102-772X