李慧燕,费 鹏,沈昱明
(1.上海理工大学 光电信息与计算机工程学院,上海 200093;2.上海自动化仪表股份有限公司,上海 200233)
所谓工业以太网,是根据国际标准IEEE802.3,设计应用于工业控制系统现场的需要,它的特点主要有系统安全性高和数据实时性强等。近年来,工业以太网控制技术和网络协议设计技术快速发展,协议设计也有了突破性的进展,工业以太网技术得以迅速发展。
Modbus-IDA 组织是由施耐德公司成立的,就是为了专门对Modbus协议进行研究和开发的。在国内,Modbus TCP/IP协议已经处于比较成熟的阶段,并对其广泛应用。为了让Modbus广泛有效地使用,提出了一种支持多线程实时应用的方案,即基于AT91R40008的微处理器,在实时操作系统uC/OS-II和ARM7内核的软硬件平台上,通过移植TCP/IP 协议栈[1]LwIP 到ARM 开发平台并结合Modbus/TCP协议实现通信处理器模块通信的功能。
Modbus/TCP协议[2-3]是在TCP/IP标准中,应用层采用工业领域事实标准Modbus实现的。经过国际公认,502端口被专门用于Modbus TCP/IP应用层,且其串行总线方式支持各种介质的rs-232、rs-422、rs-485接口,网络通信模式如图1所示。
在一个客户端与服务器的以太网TCP/IP协议为基础的网络上,Modbus报文传输服务提供商的设备之间可以进行相互的通信,且支持Modbus请求、响应、指示和证实这4 种类型的客户端/服务器模式报文。Modbus/TCP客户端首先要通过启动事务报文处理,并在网络上发送一个Modbus请求,服务器端接收到该报文请求,产生Modbus指示信号,当服务器收到该请求时,会自动产生一个Modbus响应,并向客户端发送此响应,当客户端接收到信息时,也会做出响应的反应,即产生Modbus证实来确认已经将Modbus请求发送完毕。
Modbus TCP/IP的通信系统可以包括不同类型的嵌入式设备,例如TCP/IP 网络可以通过网桥或交换机与串行链路子网相连,且客户端串行链路和服务器端串行链路通过TCP/IP网关连接到MODBUS TCP/IP 上,最终可以相互之间进行通信,其通信结构如图2所示。
Modbus/TCP功能组件结构模型[4]主要由四个层次组成,由下到上是TCP/IP栈、TCP管理层、通信应用层和用户应用程序。其中,在Modbus/TCP 通信的应用层中包含了Modbus客户端、Modbus服务器、Modbus客户端接口和Modbus服务器接口四个部分,是系统的核心所在。Modbus设备可以提供客户端/服务器Modbus接口和Modbus后台接口,而后台接口包括四种数据类型:离散输入Discrete Input、离散输出Coil、寄存器输入Input Register和寄存器输出Holding Register。
Modbus客户端完成对用户的远程控制和设备间的交换信息,用户发送一个Modbus请求到客户端接口,然后调用一个Modbus等待,最后再确认该事务处理。Modbus客户端接口允许用户应用程序生成,并通过提供的Modbus服务请求接口访问Modbus应用对象。Modbus服务器的主要功能是等待接收一个Modbus请求来读取和写入,然后生成Modbus响应。Modbus的后台接口仅仅是一个Modbus服务器的应用程序对象之间的接口。
图1 Modbus/TCP的网络通信模式Fig.1 The network communication mode of Modbus/TCP
图2 Modbus/TCP通信结构Fig.2 Modbus/TCP communication structure
考虑到网络协议软件和实时操作系统与嵌入式工控产品的应用发展需求,硬件平台采用了美国Atmel公司提供的AT91R40008微控制器和台湾Asix公司推出的一款基于AX88796 网卡的以太网接口芯片。硬件开发平台框图如图3所示。
AT91R40008是一款主要面向嵌入式应用的高性能32位微处理器,目前在很多嵌入式设备上已经被大量的使用,工作频率为66 MHz,且集成256kB的片内ARM,支持嵌入式ICE 内电路仿真以及调试通信接口,不需要外扩RAM 就可以满足一般的嵌入式系统的开发。
AX88796是一款内部集成有10/100Mbps自适应的介质访问控制层(MAC)[5]和物理层收发器(PHY)的以太网控制器,与NE2000快速兼容。AX88796与AT91R40008的接口电路如图4所示。
图3 系统硬件开发平台框图Fig.3 The block diagram of system hardware development platform
图4 AX88796与AT91R40008的接口电路Fig.4 The interface circuit of AX88796and AT91R40008
片外Flash扩展选用SST39VF160,是一个1 MB 16位的CMOS多功能Flash(MPF)器件,由SST特有的高性能SuperFlash技术制造而成。调试工具JTAG 是一种国际标准测试协议,主要用于芯片内部测试及对系统进行仿真、调试,AT91R40008 的JTAG 接口共有5 条信号线:NRST、TMS、TCK、TDI、TDO 分别为测试复位输入信号、模式选择、时钟、数据输入和数据输出线。为了拓展本通信模块的适用范围,还应该具有能够下载配置文件的串口,故本通信模块除了以太网和RS485 接口外,另外还增加了RS232接口。
考虑到系统的实时可靠性和代码公开的问题,采用代码开放的低成本的实时嵌入式操作系统uC/OS-II和TCP/IP协议栈LwIP,并结合采用Modbus协议的应用层来设计该系统的软件结构,其软件架构如图5所示。
为了使实时操作系统uC/OS-II能够在ARM7的硬件开发平台AT91R40008上正确地运行,因此就要先将操作系统移植到该ARM 处理器上。须知的是,在编写与处理器硬件相关的代码时要用汇编语言来完成,而操作系统uC/OS-II的大部分代码还是要用C 语言来编写的。在进行操作系统的移植过程中,最主要的是实现与处理器息息相关的代码部分,具体的有使用C语言编写的头文件OS_CPU.H、使用汇编程序语言编写的源文件OS_CPU_A.S和需要C 程序语言编写的源文件OS_CPU_C.C。
LwIP的含义是轻型(Light weight)TCP/IP协议栈,既可以移植到操作系统上,又可以在无操作系统的情况下独立运行。它是一种源代码开放的协议栈,可方便的用于嵌入式系统,它的成本较低,是用户使用的理想选择。它尽可能少的减少内存的使用率和缩小代码容量,这样就可以让LwIP适用于资源有限的小型平台,典型的如嵌入式系统。为了简化处理过程和内存要求,LwIP对API进行了裁减,可以不复制一些数据。
在/include/arch文件下的cc.h等头文件中存放这一些与处理器相关的数据长度和位顺序,它们的定义都与移植操作系统uC/OS-II时定义的数据参数是相符合的。通常在C语言的结构体中,struct遵循四字节对齐结构。
操作系统模拟层的存在主要是为LwIP协议栈的移植提供便利条件,具体的移植涉及到的函数主要包括信号量操作函数、邮箱操作函数、实现sys_arch_timeouts()函数和实现sys_thread_new()函数这四个部分。
图5 嵌入式TCP/IP协议栈软件架构Fig.5 The software architecture of embedded TCP/IP protocol stack
根据Modbus/TCP规范提供的参考组件模型,采用分层式软件设计方法。其中,在通信应用层软件设计过程中,通过创建多个线程函数来实现客户端/服务器之间数据的传送。
通信控制器模块发送定值信号到定值模块SP 卡上的线程函数sndto_sp_card_thread();通过调用sp_copy_modreg_to_485buf()函数,将Modbus协议对应地址中(Coils,Holding Reg)的数据拷贝到要发送的数据缓冲485buf中,然后通过38译码器选择通道,最后调用sndto_sp_card()函数,通过485发送数据到SP卡上。
通信控制器模块接收来自定值模块SP卡的定值状态信号的线程函数recvfrom_sp_card_thread();通过调用sp_recvfrom_fpga_to_485buf()函数,从相应fpga(该芯片通过RS485接口进行m 序列的发送和接收)内存中读取数据数据放入485buf中,然后调用sp_copy_485buf_to_modreg()函数,将接收到定值卡SP卡数据拷贝到Modbus协议对应的地址中。
通信控制器模块接收来自调理模块AD 卡的调理信号的线程函数recvfrom_ad_card_thread();通过调用ad_recvfrom_fpga_to_485buf()函数,从相应fpga内存中读取数据放入缓冲485buf中,然后调用ad_copy_485buf_to_modreg()函数,将接收到调理卡AD 卡数据拷贝到Modbus协议对应的地址中。
Modbus/TCP客户端线程函数client_thread();通过调用conn_netconn()和服务器建立连接。连接一旦建立,客户和服务器之间就可以通过调用函数netconn_write()来进行Modbus/TCP事务报文的传输,然后调用netconn_recv()读应答报文,并根据事务响应情况给用户应用发送证实信息。最后待数据传输结束以后,双方调用函数mbserver_close()关闭TCP连接。
Modbus/TCP服务器主线程函数mbserver_thread();通过调用函数netconn_new()创建一个套接字,然后调用函数netconn_bind()将该套接字和本地网络地址绑定在一起,再调用函数netconn_listen()监听TCP 502端口的连接请求,最后调用函数mbserver_accept()接收并产生一个新的线程处理连接,然后分析netconn_recv()读取的报头并处理请求,等待请求成功或关闭连接。
介绍了在实时嵌入式操作系统uC/OS-II和ARM7内核的软硬件平台上,结合Modbus/TCP协议实现通信处理器模块信号传输的方法。将uC/OS-II实时操作系统移植到ARM7AT91R40008系列的处理器内核上,再将嵌入式TCP/IP协议栈LwIP移植到该操作系统,实现了一种多线程的实时应用协议栈。在通讯应用层上,则在将Modbus信息帧嵌入到TCP帧中,分析研究Modbus/TCP协议通信结构模型,最终简单可靠地实现了嵌入式Modbus/TCP客户端/服务器端之间的通信。
[1] 王海,张娟,朱晓阳,等.TCP/IP协议族[M].4版.北京:清华大学出版社,2011:300-319.
[2] 王可鹏.基于Modbus TCP/IP通信的实现[J].电脑知识与技术,2008,4(3):553-555.
[3] 司马莉萍,贺贵明,陈明榜.基于Modbus/TCP协议的工业控制通信[J].计算机应用,2005,25(S1):29-31.
[4] 金青,戴胜华,欧阳劲松.基于Modbus/TCP的工业以太网通信[J].仪器仪表标准化与计量,2006(1):22-24.
[5] 宋玉贵,康婷颋.基于ZigBee的天幕靶信号处理装置的设计与研究[J].光学仪器,2012,34(1):55-58.
[6] 王晓鸣,王树新,张宏伟.实时操作系统uC_OS_II在ARM 上的移植[J].机电一体化,2007,13(1):56-58.
[7] 阙大顺,王近涛.LwIP协议在uC/OS-II系统上的移植与实现[J].舰船电子工程,2006,26(4):89-91.
[8] DUNKELS A.TCP/IP协议栈LwIP的设计与实现[M].焦海波,译.北京:北京航空航天大学出版社,2006:1-12.