Linux-485收发切换延迟的解决方法

【前言】

  1. 本文引用各种资料甚多,而引用出处标明并不详细,若有侵权,请联系删除。
  2. 转载请注明出处:https://www.cnblogs.com/leisure_chn/p/10381616.html

一、问题描述

RS-485(亦称TIA-485, EIA-485)作为一种半双工总线,其收发过程不能同时进行。
RS-485通信的具体硬件原理可查阅其他资料,此处不详述。本文仅描述其控制方法及相关问题。

通常由CPU引出三根管脚:两个UART管脚(记作PIN_RX、PIN_TX)和一个485收发方向控制管脚(记作PIN_DIR)。
这三根管脚会接在板上的485芯片上,485芯片再向板外引出“D+、D-”两根差分信号总线(差分信号具有搞干扰、传输距离远的优势)。

应用程序编写时,在原来的普通串口通信基础上,加上485收发方向控制即可。
具体说来,UART发送过程中,将PIN_DIR脚拉高,发送完毕再将PIN_DIR脚拉低,使485总线可以接收数据。
对于无操作系统的裸机程序来说,485通信非常简单。
但在Linux应用程序编写中,这个方向切换存在延迟问题。

Linux应用层485控制接口伪代码如下:

// 初始化串口  
fd = open("/dev/ttyS1", O_RDWR | O_NOCTTY);
init_serial(fd, 9600, 8, 1, 'N');
set_485_dir(LOW);   // 默认为接收状态  

// 发送数据
set_485_dir(HIGH);
write(fd, buf, sizeof(buf));
tcdrain(fd);        // 此句判断时刻不准,延时约10-20ms  
set_485_dir(LOW);

// 接收数据  
read();

经测试,set_485_dir()改变PIN_DIR脚的延迟很小,可忽略不计。tcdrain()却总是存在10-20ms的延迟。
tcdrain()是等待fd所引用的串口设备数据传输完毕。在物理上数据已传输完毕时,因为操作系统延迟原因,导致tcdrain()多停留了10-20ms,从而导致数据发送完后,PIN_DIR不能及时切换。
如果对接的485设备,接收和应答的延迟小于20ms,那方向切换不及时将导致数据接收丢失。这就是问题所在。

二、解决方法

1. 解决思路

关于收发方向延迟问题,解决思路有如下几种:

  • 由硬件自动控制收发方向的切换,这种方式不需要软件参与,硬件实现也很简单,推荐使用
  • 尝试将操作系统HZ由默认的100改为1000,经测,tcdrain()延迟降为几个ms,实际仍然不能满足要求,而且比较影响系统性能
  • 应用层控制方向切换,应用程序里使用ioctl()方法,利用Linux串口驱动里自带的485功能。此方法需要全串口里的RTS管脚作为方向脚。时间所限,此方法未研究明白
  • 驱动层控制方向切换,修改串口驱动使支持485方向切换,此方法验证可行

最后一种方法就是本文要描述的方法。

2. 知识储备

解决此问题,需要有如下知识储备:

  • 了解485通信原理
  • 了解Linux终端设备驱动架构,搞清楚板上串口对应的实际驱动源文件
  • 掌握Linux设备驱动中的中断处理机制:顶半部、底半部(tasklet、工作队列、软中断)

3. 实现方法

本应用中对应的串口设备驱动文件为linux/drivers/tty/serial/8250/8250_core.c

3.1 由应用程序控制是否打开串口设备的485功能

在串口驱动里切换485方向对性能有一些影响。
而某些应用可能只需要标准串口,不需要支持485模式。
因此最好由应用程序来控制,是使用标准串口还是支持485模式的串口。
这主要利用ioctl()实现。

应用程序在初始化打开串口时,禁用/使能串口的485模式

fd = open(...);
init_serial(fd, ...);

struct serial_rs485 rs485conf;
rs485conf.flags |= SER_RS485_ENABLED;   // 使能本串口485模式,默认禁用
ioctl(fd, TIOCSRS485, &rs485conf);

驱动程序中对使能了485模式的串口作特殊处理。
利用struct uart_8250_port结构体中的struct serial_rs485 rs485成员判断串口是否支持485模式。
在serial_8250.h中有定义rs485数据成员,以及设置此数据成员的成员函数rs485_config

// noted by xx@xx: in serial_8250.h
/*
 * This should be 
  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值