You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Allwinner A40i平台UART4(RS485)发送后挂死问题?

硬件与环境信息
  • UART4
    • 串口驱动:dw-apb-uart
    • 仅包含Rx、Tx两路
      使用Linux内核v6.5.8,Allwinner A40i处理器,UART4连接RS485收发器,通过GPIO PH13模拟RTS引脚实现半双工传输。
DTS配置
&uart4 {
    pinctrl-names = "default";
    compatible = "snps,dw-apb-uart";
    pinctrl-0 = <&uart4_ph_pins>;
    rts-gpios = <&pio 7 13 GPIO_ACTIVE_HIGH>; //PH13
    //rs485-rts-delay = <0 200>;
    linux,rs485-enabled-at-boot-time;  
    status = "okay";
};
问题现象

使用screen工具打开端口后接收正常,但发送首个字符/行后端口立即挂死(发送内容已成功送达),RTS引脚保持高电平,端口无法再收发。更换9600~115200波特率无改善。

调试情况

调试dw8250_dw.c驱动时发现,在spin_lock_irqsave(&port->lock, flags);前添加dev_err()/dev_info()输出后,端口恢复正常,但控制台会收到端口消息;若在该锁之后添加则无效,端口出现死锁,uart_unlock_and_check_sysrq_irqrestore(port, flags);无法解锁。

问题询问
  1. 如何让UART4正常工作且不向控制台输出端口消息?
  2. 该问题是否由驱动导致?

问题分析与解决方案

根源判断

从调试现象来看,这大概率是dw-apb-uart驱动(dw8250_dw.c)在模拟RTS引脚的RS485半双工场景下存在时序或锁竞争问题。添加日志打印本质上是引入了微小延迟,刚好规避了锁死的时序窗口,并非真正解决问题。

解决方案

1. 替换日志打印为无输出延迟

在spin_lock_irqsave前添加无输出的微延迟操作,既打破死锁时序,又不会向控制台输出信息:

// 在dw8250_dw.c对应位置添加
#include <linux/delay.h> // 需先引入头文件
udelay(1);
spin_lock_irqsave(&port->lock, flags);

2. 启用RS485时序配置

尝试开启DTS中的RS485 RTS延迟参数,匹配RS485收发器的电平切换时序要求:

&uart4 {
    pinctrl-names = "default";
    compatible = "snps,dw-apb-uart";
    pinctrl-0 = <&uart4_ph_pins>;
    rts-gpios = <&pio 7 13 GPIO_ACTIVE_HIGH>; //PH13
    rs485-rts-delay = <0 200>; // 发送前延迟0us,发送后延迟200us,可根据收发器手册调整
    linux,rs485-enabled-at-boot-time;  
    status = "okay";
};

3. 升级内核或应用补丁

检查Linux内核社区是否有针对dw-apb-uart RS485模拟RTS的修复补丁,可尝试升级到v6.6.x系列内核,这类较新内核通常会修复v6.5.x版本中的边角问题。

总结

问题核心是驱动在特定时序下的锁竞争或状态同步异常,添加微延迟或调整DTS时序可临时解决,长期建议关注官方驱动的修复更新。

内容的提问来源于stack exchange,提问作者Rarebeast

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 13:42:53