嵌入式 Linux 设备在启动期间阻塞 RS485 总线

Posted

技术标签:

【中文标题】嵌入式 Linux 设备在启动期间阻塞 RS485 总线【英文标题】:Embedded Linux device blocking RS485 bus during startup 【发布时间】:2016-07-23 15:28:10 【问题描述】:

我正在使用一台工业 Linux 计算机来实现通过 RS485 总线与多个连接的设备进行通信时遇到问题。我遇到的是 RS485 USART 驱动程序使用的 IO 引脚在启动时设置为不同的电平,而不是进入 RS485 空闲/三态。结果,总线上的其他设备在设备启动时被阻塞超过 30 秒,引发各种外部问题。事件过程可以在附图中查看,我在启动期间用示波器测量了输出电压。

我的猜测是,实际驱动程序在电压水平达到其三态水平之前不会启动(例如,此设备约为 2.2V)。之后一切都按预期工作。

我试图找到任何配置文件来设置引导时引脚的默认 IO 级别(认为这可能由引导加载程序设置)无济于事。

另外,我已经尝试应用启动脚本来“足够早”运行以将 DATA 设置为高电平,但据我所知,相关设备没有提供任何接口来控制这些引脚作为常规 GPIO .

任何帮助、提示或见解将不胜感激!

编辑:我不是一位经验丰富的 Linux 开发人员,所以如果我遗漏了任何重要的细节,请强调一下。

一些规格:

ARM920T rev 0 (v41) CPU Linux 2.6 的专有发行版 使用 Busybox Atmel USART 驱动程序

从引导日志中提取:

Linux 版本 2.6.28.10 (root@) (gcc 版本 4.1.2) #94 PREEMPT Tue Oct 29 10:22:19 CET 2013 CPU:ARM920T [41129200] 修订版 0 (ARMv4T),cr=c0003177 /... .../ 端口 /dev/ttyS3 的 RS485 模式已启用 /... ...(我猜这里大约需要 30 秒) .../ atmel_usart.3:MMIO 0xfffcc000 (irq = 9) 处的 ttyS3 是 ATMEL_SERIAL atmel_serial.3:放下 RS485 RTS 引脚 /... ... .../

完整的启动日志: https://drive.google.com/file/d/0B2XYl1mNCa8jNUZ5V0Nic1hkU0U/view

类似问题:

这里可能讨论了类似的问题:UART initialisation: Prevent UART to pull RTS high 但我不确定如何继续使用建议的解决方案。

【问题讨论】:

您使用的是哪个驱动程序?是否有运行总线的外部控制器/收发器?有关硬件的更多信息会有所帮助。 嗨!我在 OP 中添加了一些规范。我在文件系统中找到了 Atmel 驱动程序,但我不确定硬件驱动程序(收发器)。我可以打开外壳四处看看,但我宁愿不要,因为它是密封的。我真希望我有一个示意图,但它不是由制造商提供的。 您可以从 SoC 串行调试端口获得更多信息(例如启动日志),因此连接到串行控制台对于进一步推进 IMO 至关重要。串行端口通常在内核启动的早期初始化,因此您需要将 RS485 状态与系统启动活动相关联。您可能需要识别所使用的 RS-485 收发器芯片,以便了解其控制输入的正确逻辑(例如,将 DE 驱动为低电平和 RE- 高电平)。 Atmel 没有太多使用 ARM920T 的 SoC;你可能有一个 AT91RM9200。 你能提供更多的启动日志吗?我不确定在内核初始化期间或任何用户空间程序采取的此操作。 您对“这里经过~30 秒” 的猜测是不合理的。内核应该没有理由花那么长时间来完成初始化的那个阶段。这 30 秒延迟的起点是什么?与此起点相对应的控制台输出在哪里? (例如内核启动之前?)您需要将'范围和计算机监视器放在一起以关联事件。 【参考方案1】:

这不过是胡乱猜测,但可能值得在启动期间尽早添加一个向设备(例如 /dev/ttyS1 或其他)回显 NULL 字符的启动脚本。这可能足以让驱动程序初始化硬件。

您也可以尝试在 Linux 源代码中找到驱动程序以查看它是如何启动的。

【讨论】:

感谢您的建议。但是,我想不出一种足够早的方法(从例如 rcs 启动脚本中尝试过) 这些东西在内核启动后也会起作用,意思是 10-20 秒 @SamratDas 看来你在这里是正确的。查看我插入 Q 的 bot 日志 - 表明一切都在启动期间发生。【参考方案2】:

您可能有权访问源代码,因此您可以调查谁以及何时弄乱了该 GPIO。只需 grep atmel gpio 控制器端口地址的内核源代码即可了解发生了什么。如果幸运的话,可能会有内核命令行选项,您可以从引导加载程序中传递该选项以提前将行设置为您需要的内容。

【讨论】:

【参考方案3】:

如果您可以找到下面提到的所需内容,此答案可能会起作用 你的董事会!

曾经我在 PWM 上也遇到过同样的问题。在那里我发现我的引导加载程序负责同样的事情,我改变了引导加载程序配置并且它开始正常工作。

检查您的板供应商或第三方提供的 BSP(如果您有源代码),如果您的引导加载程序是 U-boot,您可以在 U-boot-(source)/include/configs/(your-board).h 中找到它,您可以在那里找到 RS484 的配置。根据您的电路板数据表,您可以检查在同一引脚上复用的其他内容,如果启动时间不需要,则禁用这些内容并启用 RS485。

enabling/disabling 可以通过根据您的配置更改值 0, 1 or 2 来完成,您也可以通过注释 // 来简单地禁用任何内容。

【讨论】:

不幸的是,我似乎没有 U-boot(但我不知道我到底有什么)。没有这样的目录,我已经 grep'd *.h-files 无济于事。感谢您的建议和坚持帮助我!

以上是关于嵌入式 Linux 设备在启动期间阻塞 RS485 总线的主要内容,如果未能解决你的问题,请参考以下文章

转载:常用的嵌入式硬件通信接口协议(UARTIICSPIRS-232RS-485RS-422CANUSBIRDA)

转载:常用的嵌入式硬件通信接口协议(UARTIICSPIRS-232RS-485RS-422CANUSBIRDA)

UART和RS232/RS485的关系是什么?

UART和RS232/RS485的关系是什么?

UART和RS232/RS485的关系是什么?

RS485 Modbus-RTU设备给出的错误是什么?