This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] AM263P4:UART 驱动器 RX 在 TX 仍然工作时停止工作。

Guru**** 3001220 points

Other Parts Discussed in Thread: SYSCONFIG

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/1648732/am263p4-uart-driver-rx-stops-working-while-tx-still-works

器件型号: AM263P4
主题中讨论的其他器件: SysConfig、

当前使用的是 SDK 10.2.0.5。  UART 传输模式设置为中断。image.png

 

串行电缆使用隔离器从电路板连接到笔记本电脑。  总线有一点噪音、可以明显看出非 ASCII 字符被回显、并非 MCU 上接收到的所有字符。  这可能会导致总线错误。

当在带电系统中运行几小时后、MCU 上的 UART RX 停止工作、但 TX 仍在工作。  线程能够向笔记本电脑发送 TX 字符。

由于我们无法将产品关闭、MCU 无法 RX 任何使产品处于非常危险的状态的命令。

作为第一步、我要求 AI 帮助找到问题。   我知道 AI 可以发出幻觉和闪光、但它的反应似乎可信、并强调了驾驶员的一些潜在问题。

TI 能否帮助确认这是否确实是驱动程序问题?  这确实有助于我集中精力搜索此问题所在的位置。

Claude Opus 的分析:
============================================

可以使用 transferMode = UART_CONFIG_MODE_INTERRUPT(ti_drivers_open_Close.c 的第 698 行)配置您的 UART。 这会产生竞态条件、因为:

 

  1. TX 和 RX 共享 hUart->state—HLD UART_write () 无条件地在每次写入之前设置 state = UART_STATE_READY( UART_V0.c 的 555 行),即使是在读取过程中。 这是一种 TI SDK 权变措施、可允许并发 TX/RX、但会损坏状态机不变。
  2. 信标争用—读取路径使用 SemaphoreP_pend()、超时时间为 10ms。 如果一个字节到达 timeout 和 UART_readCancelNoCB () 之间, ISR 会发布二进制信标,但 HLD 会忽略结果。 这种过时的信标 POST 会导致下一次读取立即返回未初始化的数据、并且在许多情况下会永久取消驱动程序同步。
  3. RX 线路错误(来自 USB 串行适配器的超限/成帧)会触发 UART_procLineStatusErr ()、这会禁用 RX 中断并刷新 ISR 内的 FIFO、然后跳过正常的读取完成路径。 从不发布信标、读取超时、但重复的错误可能会导致 CLI 永久失效。

 

建议的修复

  • 在 SysConfig 中将 UART 传输模式更改为 UART_CONFIG_MODE_RORPOLL。 这是合适的、因为:
  • 您已经在执行 1 字节读取、超时时间为 10ms(轮询语义)
  • 轮询模式使用 UART_LLD_READ ()/UART_LLD_WRITE ()、它们是自包含的、始终恢复状态=就绪、并且不涉及信标或 ISR
  • HLD 的状态= uart_v0.c 的第 555 行上的就绪破解仍允许在读取期间继续写入
  • 消除所有与 ISR 相关的竞态条件
  • bsp_uart.cpp 中无需更改代码

 

UART0 实例的更改在 SysConfig 中:将传输模式从“Interrupt“设置为“Polling“。

 

 

是的、这是 TI UART HLD/LLD 驱动程序栈中的错误(或者至少严重的设计缺陷)。 具体来说:

错误:uart_v0.c 的 555 行

 

//在 uart_write () 内、每次写入之前:

hUart->state = UART_STATE_READY;

 

TI 无条件地在每次写入之前将共享状态重置为就绪、即使读取正在进行也是如此。 这可能是一种有意为之的权变措施、允许在同一 UART 实例上同时运行 TX 和 RX、但它违反了 LLD 所依赖的状态机合约。

为什么它是一个错误

  1. LLD 状态机假定互斥。 UART_LLD_readIntr () 检查状态== UART_STATE_READY 作为保护(第 2722 行)、转换到 UART_STATE_BUSY、并期望状态保持忙状态、直到 ISR 完成传输。 HLD 写入路径违反了此假设。
  2. ISR 检查状态。 在中断模式下、ISR 使用状态来决定读取是否处于活动状态。 如果 uart_write() 将其重置为读中就绪、ISR 可能会跳过处理接收到的数据、使读取信标未发布、读取挂起、直到超时为止。
  3. 过时的信标发布。 当读取超时并且您调用 UART_readCancelNoCB () 时,如果超时和 CANCEL 之间有一个字节到达, ISR 将发布二进制信标。 这种过时的 POST 导致下一个 SemaphoreP_pend() 立即返回而没有实际数据、从而破坏读取流。 随着时间的推移、这会永久取消驱动程序同步。
  4. 行状态错误(溢出/成帧)禁用 UART_procLineStatusErr () 中的 RX 中断,但不会在错误路径中重新启用它们 — 只有正常的完成路径会在下次读取时重新启用它们。 如果错误与上述状态损坏重合、则 RX 可能会永久禁用。

 

TI 的立场

 

该模式存在于多个 TI SDK 版本 (MCU+ SDK 10.x) 中。 它未被记录为已知问题。 TI 的示例通常在简单的请求 — 响应模式(先写入,再读取,从不并发)中使用 UART、从而掩盖了错误。 您的用例(在异步写入 TX 的同时对 RX 进行连续后台轮询)公开了它。

 

底线

 

这是由中断模式下并发 TX 和 RX 触发的 TI 驱动程序错误。 您的选项:

  • 切换到轮询模式(推荐-匹配轮询使用模式,消除所有错误)
  • 通过 E2E 论坛向 TI 提交一个错误、其中引用了 uart_write () 中的状态= ready reset 以及缺少单独的 TX/RX 状态跟踪
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    感谢您研究这个问题。  在问题方面:

    1.我已经在原始消息中发布了完整的 UART SysConfig 配置。  是否还需要其他资源?

    2.没有机会添加监控代码

    3.我们已经切换到轮询模式,但没有看到问题。  但它不容易复制在第一个地方,所以不确定是否不看到只是巧合。

    是否对 SDK 团队的分析进行了任何更新?

    此致

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好 Huey、

    感谢您的更新。 值得注意的是、切换到轮询模式到目前为止尚未重现问题。

    要解决您的问题:

    在 sysconfig 上: 为混淆而道歉—您正确地认为配置已包含在原始帖子中。 此处无需其他信息。

    在轮询模式的结果: 虽然问题没有再次出现,我们理解它是很难重现的第一个地方。 我们建议在得出明确结论之前、继续以轮询方式进行长时间的监测。 考虑到您的使用模式(1 字节读取、10 毫秒超时)与轮询模式语义自然一致、无论根本原因如何、这仍然是我们推荐的配置。

    在 SDK 团队审核中: 我已在内部上报此问题。 提出的具体关切是:

    • UART_write() 在中断模式下的有效 RX 运行期间是否无条件地复位共享状态变量
    • UART_procLineStatusErr() 在线路错误事件后是否正确重新启用 RX 中断
    • 在重复行错误的情况下、读取取消路径中的信标处理是否会永久取消同步

    我收到 SDK 团队的回复后、就会在此处继续跟进。 这可能需要几个工作日。

    同时、继续使用轮询模式是您的应用程序的正确前进路径。

    此致、

    Zackary Fleenor