贾海航,赵霞
(同济大学 电子与信息工程学院,上海 201804)
摘要:RS485总线经常被用做主从系统各节点间的通信方式,系统中主从机的通信状态是整个系统正常工作的前提。文章设计了一种基于RS485总线的从机故障检测方法。首先根据需求设计了一套稳定的网络通信协议和接口函数,并提出了一种基于RS485网络通信协议的轮询方法,可实现一个主机可靠、稳定地轮询访问多个从机。主机能够检测各个从机的通信状况,并及时将从机通信故障信息上报到上位机。文章提出的在轮询基础上进行故障检测的方法,大大提高了系统的实时性。
关键词:RS485;轮询;故障检测
中图分类号:TP29文献标识码:ADOI: 10.19358/j.issn.1674-7720.2017.07.001
引用格式:贾海航,赵霞.基于RS485总线的GSM-R从机故障检测设计及实现[J].微型机与应用,2017,36(7):1-4,8.
0引言
图1GSM-R铁路无线数字通信系统随着铁路列车运行速度的不断提升,通信系统对于铁路的安全运行越来越重要。铁路综合数字移动通信系统(Global System for Mobile Communications-Railway,GSM-R)是一种基于当前世界最成熟、最通用的公共无线通信系统GSM平台,专为满足铁路应用而设计开发的无线数字通信系统[1]。图1为GSM-R铁路无线数字通信系统结构示意图,该系统包括远端机和近端机两部分。近端机由时间分布控制单元 (Time Distributed Master Unit,TDMU)及射频模块组成,远端机由射频拉远单元(Radio Remote Unit,RRU)和射频模块组成。TDMU和RRU不仅需要获取各自射频模块的实时信息,以了解各个射频模块的运行状态,同时还需将各个射频模块的故障信息及时上报到上位机,使射频模块得到及时的维护。因此,TDMU和RRU与各自的射频模块之间稳定可靠的通信是非常重要的。
常用的串口通信方式包括RS232和RS485。RS232串行通信总线属于全双工工作方式,数据的收发可以同时进行,但传输距离短,且只适合点对点的通信方式。RS485串行通信总线采用半双工工作方式,数据的收发不能同时进行,任何时刻只能有一个主机处于主动发送状态,其他所有从机处于被动接收状态,非常适用于一主多从的通信要求[2]。RS485作为一种构造简单、技术成熟、传输距离远的通信方式,得到了广泛的应用。
在本系统中,要求TDMU和RRU可以主动访问射频模块,而射频模块只能被动接收并响应。根据上述需求,采用RS485串行总线作为TDMU和RRU访问射频模块的通信方式。将TDMU和RRU作为主机,射频模块作为从机,构成RS485主从通信系统。上位机通过TDMU来监控整个系统。
在一些相关文献中关于RS485总线通信方式的设计都只提到了RS485轮询过程的实现,但均未考虑从机故障的处理问题。本文针对在轮询过程中的从机故障检测问题,提出了RS485总线轮询与从机故障检测相结合的实现方法。在本文的设计中,主机通过RS485总线轮询各个从机,获取从机信息,同时实时检测从机故障状态。
1RS485通信协议和接口函数的设计
1.1通信协议
RS485接口标准通信协议需要用户自己根据实际情况而设计[3]。设计一套结构简单、功能完备,并且尽量标准化的通信协议是RS485通信最基本的通信要求。
RS485通信协议的设计主要包括物理层和数据链路层[4]。本文使用的VxWorks操作系统通过串口驱动程序已经实现了物理层的所有功能[5]。只需调用操作系统提供的发送和接收函数就可以实现数据通信。本文设计的RS485总线通信协议主要完成数据链路层的功能。
数据链路层的通信协议[5 6]包括开始结束标志、设备的类型及地址、数据校验等。设置一个开始、结束标志来表明每一段数据帧的开头和结尾。设置一个标志来标识数据帧是请求数据帧还是应答数据帧。用设备类型和设备地址两个标志位来区分不同的从机。数据校验位用来保证数据帧的正确性。除上述单元,通信协议还应包括命令标识、数据长度等。
根据以上描述,设计的通信协议如图2所示。
开始标志、结束标志:表示一帧数据的开始和结束,本文均用0x7f表示。
设备类型:本文中用0x01表示功放,用0x02表示低噪放。
设备地址:对于同一种从机类型,用设备地址区分不同设备类型下的不同从机。例如:对于4个功放(设备类型为0x01),设备地址分别为0x00、0x01、0x02、0x03。
命令标识:表示主机对从机发送的命令类型。
响应标识:主机主动向从机发送数据用0xff表示,从机被动响应主机用0x00来表示。
数据长度:表示具体数据的长度。
数据校验:为保证数据传输的正确性和完整性,本文采用CRC校验码。CRC校验码具有唯一性。若发送端与接收端的校验码不一致,则表明数据帧的传输有误[7]。
1.2接口函数
数据链路层需为高层提供统一的RS485接口函数,而接口函数的设计需要按照上述的网络通信协议组包,调用底层串口驱动将数据发送到目的从机并等待接收响应消息。对接收到的数据解析,若此响应数据完整无误,则将需要的数据从中解析出来。在接口函数的设计中需要考虑数据帧的转义、数据帧发送和接收、接口函数的保护三方面的内容。
(1)在数据接收端,若具体数据中出现0x7f的数据,在接收端就会影响对完整一帧数据的判断。因此,在数据发送端要对发送数据进行转义处理。本文的方法是用0x5f和0x7d两个字节的数据来代替0x7f,用0x5f和0x5d两个字节的数据来代替0x5f;在数据接收端进行反转义处理,与转义处理相反。
(2)接口函数中最重要的就是数据的发送和接收,本文使用的VxWorks操作系统已经完成了底层RS485串口的配置,只需要调用操作系统提供的发送和接收函数就可以实现数据通信。数据的发送函数Tx485就是将组包好的数据发送到RS485总线上。RS485接收任务一直监听总线上的数据,通过监听数据帧中的开始和结束标志来接收一条完整的RS485数据。将一帧完整数据发送到消息队列,msgQReceive则从消息队列中接收数据。RS485接口函数如下:
STATUS Port485Send (……)
{
semTake(sem485RdDone,WAIT_FOREVER);
//根据自定义的数据结构进行组包
……;
//进行转义处理
Escape(SendBuf,OutBuf);
//发送数据
Tx485(OutBuf);
//接收响应数据
msgQReceive (Rx485QId, (char *)RespBuf, LEN_MAX , timeout);
//处理响应数据
Port485_Handle(RespBuf, MsgLen);
semGive(sem485RdDone);
return OK;
}
(3)在RS485总线通信中,同一时刻,只能有一个主机处于发送状态,其他所有从机处于被动接收状态,并且从机之间不能相互通信,否则将会引起总线冲突,无法正常工作[7]。RS485总线属于半双工的通信方式,数据的收发不能同时进行,数据的发送必须等到上一次数据接收完成之后才能进行。为了满足上述RS485总线通信的特点,本文需要对RS485接口函数进行保护。
①RS485是一主多从的串行总线,每一时刻只能有一个主机发送数据,也即每一时刻RS485接口函数只能被调用一次。为了防止接口函数被同时调用,在接口函数中增加了信号量的保护。主机在调用接口函数时,必须首先获取信号量。如果没能获取信号量,说明此刻有其他任务在调用接口函数。主机必须等到发送数据结束释放信号量后,才能获取信号量,调用接口函数来发送数据。
②RS485通信属于半双工的通信方式,数据的收发不能同时进行。在实际的需求中,除了主机不断轮询从机之外,上位机也会通过主机向目标从机发送一些查询从机数据或配置从机参数的数据帧。主机的轮询是一直进行的,而上位机下发的数据帧是随机的。为了避免轮询数据和上位机下发的数据帧在485总线上冲突,本文设置一个全局变量作为主机轮询的开关。在上位机下发RS485数据帧时,关闭轮询开关,主机轮询从机暂时停止。当目标从机响应了上位机之后,打开轮询开关,主机继续轮询从机。
2基于轮询机制的从机故障检测的设计
2.1从机故障检测的流程
图3是基于轮询机制的从机故障检测的设计流程图。主机每隔800 ms调用一次RS485接口函数轮询从机设备。若800 ms内未收到从机的响应,则认为此从机通信异常。若连续异常次数达到上限,则主机需要将此从机通信故障信息上报到上位机。
2.2从机故障检测的实现
为了实现主机在轮询从机过程中检测从机通信状况,本文将轮询机制嵌套于故障检测任务中。从机故障检测任务包括轮询时间间隔的设计、故障上报设计、轮询过程中的从机故障检测设计。其中,轮询过程中的从机故障检测是本文的重点。
(1)轮询时间间隔的设计。通过看门狗定时器和信号量来实现800 ms的主机轮询从机的时间间隔。在一个800 ms的看门狗定时器中,每隔800 ms释放一次信号量。
(2)故障上报设计。在故障检测任务中,Rs485AlmReport是根据当前状态和同步状态进行故障上报的函数。当前状态表示从机当前的状态,而同步状态表示从机的历史状态。若某一从机的当前状态是故障状态,同步状态是正常状态,则主机就会向上位机上报此从机故障。故障检测任务部分代码如下:
LOCAL void Rs485AlarmManTask(void)
{
wdStart(TimerId, (int) Timer, (FUNCPTR) Rs485TimerFun, 0); //轮询时间间隔
While(1){
semTake(semAlmSampleT, WAIT_FOREVER) ;
if(RS485UseSwitch == 0){
Rs485AlmCheck( );}//从机故障检测
Rs485AlmReport( );}//故障上报
}
(3)轮询过程中的从机故障检测设计。在故障检测任务中,Rs485AlmCheck函数调用RS485接口访问从机设备。为了便于管理所有从机设备,建立如下从机设备信息的数据结构:
typedef struct alarm_info{
UINT8 AlmIndex;/* index of the device */
UINT8 AlarmEna;/* device enable */
UINT8 CurAlmState;/* current alarm state */
UINT8 SyncAlmState;/* synced alarm state */
UINT8(*CommChk) (void); /*detect function */
UINT8 AlmRaiseCnt;/* device raise counter */
UINT8 AlmIdleCnt;/* device clear counter */
} ALARM_INFO;
从机设备信息包括从机序列号、故障检测使能、当前状态、同步状态、故障检测函数(轮询函数)、故障统计、正常统计等。根据从机设备信息数据结构建立ALARM_INFO Rs485Devices[MAX_DEV_NUM]所有从机的信息。每隔800 ms执行一次从机故障检测函数,并统计故障的次数。若故障次数达到上限,则等待Rs485AlmReport故障上报函数将信息上报到上位机。
3故障检测的优化及结果
在实际情况中,一次从机通信异常不能认为此从机通信故障。在本文中,规定某从机连续4次通信异常,才能认为此从机通信故障。当从机数量较多时,若某一从机通信故障,主机需要将所有的从机设备轮询4次后,才能将从机通信故障检测出来并上报到上位机。在这种情况下,主机不能及时将从机通信故障上报到上位机,造成上位机获取从机通信状况非常滞后,系统实时性较差。主机为了能够及时将从机发生故障上报到上位机,在轮询下一设备前需做如下判定条件:当主机访问某一从机时,如果从机通信异常,则继续访问此从机,而不是访问下一个从机设备;当连续4次通信异常,主机将此从机的当前状态改为故障状态,继续访问下一个从机设备。轮询条件代码如下:
void Rs485AlmCheck(void)
{
//保持不变
……
//轮询条件
if(TmpState==Rs485Devices[DevOrder].CurAlmState)
DevOrder+=1;
}
在从机故障检测函数中,如果实际状态与当前状态一致,表明主机已将从机的实际状态反馈到从机的当前状态,则继续轮询下一个从机设备。
为了说明基于轮询的从机故障检测的轮询条件的优化效果,作如下假设:某一主机下共有7个从机,最坏的情况下,这7个从机同时发生了通信故障。在不加轮询条件的从机故障检测中,检测出第一个从机故障需要0.8×7×3+0.8=17.6 s,在加上轮询条件后的从机故障检测中,检测出第一个从机故障需要0.8×4=3.2 s。如图4是在7个从机同时故障的情况下,加上轮询条件前后,主机检测出这7个从机故障所需要的时间对比。加上轮询条件后的检测方法大大减少了从机故障检测所需的时间。
4结论
基于RS485总线的通信协议和接口函数的设计保证了主机稳定可靠地访问从机。从机故障检测的轮询机制一方面可以不断地获取各个从机的设备信息,另一方面可以检测从机通信故障。但是,当从机数量较多时,轮询周期就会变长,从机的通信故障不能被及时检测出来,系统实时性变差。加上了轮询条件优化后的轮询机制相比传统的轮询机制,实现了快速检测从机通信故障。上位机可以及时获取各个从机的通信状况,提高了系统的实时性。
参考文献
[1] 胡威.基于GSM-R的列车无线定位方法探索 [J].铁路通信信号工程技术,2016,13(5):21-23.
[2] 胡文涛. 一种基于协议的提高RS485实时性的方法 [J].现代电子技术,2013,36(18):10-12.
[3] 周鹏,李艳艳. 提高RS485总线主从通信效率的软件设计[J].单片机与嵌入式系统应用,2008,8(8):70-73.