基于STM32的PROFINET IO协议栈框架的实现

2019-08-21 06:06张哲睿
沈阳理工大学学报 2019年3期
关键词:缓冲区线程队列

周 侗,张哲睿,于 洋

(沈阳理工大学 自动化与电气工程学院,沈阳 110159)

PROFINET是应用最为广泛,最有前景的工业以太网技术之一[1]。可以为工业自动化领域提供完整的网络解决方案,将整个工厂从管理层、控制层,到现场层使用同一种网络连接起来,实现一网到底[2]。PROFINET IO是PROFINET标准中实现模块化、分布式应用的技术。

PROFINET经过近20年的发展,成为国际市场上领先的工业以太网标准,自身技术也在不断革新,引领着工控网络的发展方向。其产品涵盖领域广阔,技术成熟。在中国市场,PROFINET在官方推广下取得了长足发展,但仍处于技术研究和应用开发不成熟的阶段,产品多为在集成了协议栈的设备上进行上层开发,底层设备往往价格昂贵,对协议栈本身配置和开发的难度较大。

考虑到国内缺少易学易用,开放灵活的PROFINET方案,本文基于应用广泛、性价比高的STM32F407VET6主控芯片,设计了PROFINET IO协议栈,可接入PROFINET网络平台中,作为IO设备实现数据收发与诊断报警功能,并能够根据用户的需要进行灵活的配置和移植。该协议栈对处理芯片性能无过高要求,可在非运动控制的工业领域替代市场主流的ERTEC系列PROFINET解决方案,对PROFINET技术在国内的应用与普及起到积极作用。

1 协议栈结构设计

1.1 PROFINET IO通信类别

依据不同的响应时间,PROFINET IO实现的通信方式可划分为三种,分别为

非实时(NRT)通信:通过使用基于UDP/IP的标准IT服务完成,具有100ms级的响应时间。

实时(RT)通信:用于循环数据交换,精简了通信通道,与UDP/IP通道并行,响应时间5~10ms[3]。

硬实时(IRT)通信:用于运动控制,需要专用设备的硬件支持。响应时间小于1ms。

图1为典型的PROFINET IO网络结构图。

图1 PROFINET IO网络结构图

1.2 协议栈模块结构设计

基于STM32硬件平台的硬件特性,设计了以RT通信为最高标准的PROFINET IO协议栈框架结构,如图2所示。

图2 PROFINET IO协议栈框架结构图

系统适配集成部分起到内存管理、任务管理、进程间通信与时钟等作用[4],通过操作系统抽象层实现;LLDP通过与邻居交换信息起到无组态工具情况下进行设备替换的作用[5];DCP协议用于对所有组态的IO设备进行地址解析和名称分配[6];CM用于设备和主站建立应用关系,通过基于UDP协议的RPC发起连接请求并参数化通信模块。框架预留了上层应用接口,可供进一步开发。

2 通信通道设计

NRT信道的主体是UDP/IP协议,一般用于非循环传输,如出错日志、设备参数化、I&M数据、详细诊断、信息功能等[7]。出于节约内存的考虑,通过移植LwIP协议栈来实现。非实时数据收发时,分别调用udp_sendto()和udp_recv()。

RT信道主要调用LLDP、CM、DCP、DIM、ACP、IOM等模块。下文将分别介绍实时通信处理相关模块的功能与设计。

2.1 DIM模块设计

DIM(数据交互状态机)模块是多个模块的集合体,通过这些模块建立与MAC层的映射,对外实现数据的发送调度和接收转发,对内将有效信息送入相应的上层模块中处理。本设计中,DIM可看作由两个子模块构成,SAC模块负责发送调度,检查待发送数据,并维护队列,确保可持续使用。RTX模块负责接收转发,实现队列中数据实际的收发流程。

2.1.1 SAC模块设计

根据数据帧类型不同,SAC模块提供三组缓冲队列作为不同数据帧类型的入口,分别是非循环非实时队列NRT,非循环实时队列ART,循环实时队列RT。NRT队列服务于UDP/IP帧,由LwIP协议栈实现收发;ART队列主要服务于DCP及报警、诊断报文;RT队列服务于RT通信所传输的IO数据。此外,SAC线程还负责管理DSC(数据送达确认)信号量和QDS(待发送数据)队列。线程工作时,首先初始化各个队列和信号量缓存,然后检测队列中有无待发送数据。接收到数据帧后,交由RTX模块处理发送过程。发送完成,收到队列清空信号后,线程回到检测状态继续运行。图3描述了SAC模块待发送队列处理流程。

图3 SAC模块待发送队列处理流程图

2.1.2 RTX模块设计

RTX主要通过映射访问与MAC层进行数据交换。数据的接收转发由RTX_ Snd和RTX_ Rec实现。由于硬件平台不能实现等时同步发送,因此RTX_ Snd仅实现了固定优先级的软实时发送调度。该函数将依优先级次序发送ART,RT,NRT队列中的数据。

其中,RTX_Rec接收函数的作用是把收到的PROFINET IO帧发送至DSC队列之中。为了让接收到的数据可以得到及时的传递,接收到数据帧的第一个中断会立即调用RTX_ Rec函数,用于快速唤醒SAC、DCP等线程,用于下一步处理。该函数可识别RT帧,并根据Frame_ ID进行处理。RT帧处理部分程序流程见图4。

图4 RT帧处理部分程序流程图

2.2 IO通信模块设计

IO模块用于IO数据在设备内部的传输。数据交换按照生产者/消费者模式进行[8]。IO模块包含了三个长度相同的缓冲区,分别是数据传递(D)缓冲区、用户处理(U)缓冲区和Next(N)缓冲区。其中,D缓冲区用于存放模块待接收或待发送的数据;U缓冲区用于存放可供等待用户读取或修改的数据;N缓冲区中存放的是在D状态和U状态间,等待进一步处理的数据,该缓冲区可避免数据在等待过程中被覆盖或破坏,保证传递的安全。IO设备建立起用于IO数据交换的数据缓冲区后,通过槽和子槽进行寻址[9]。IO数据交换模块提供了一组函数用于读取更新缓冲区函数。其中Get_Input_IOCS()函数用于读取数据对应模块的消费者状态,Set_Output_IOPS()用于设置生产者数据状态;Set_Input与Get_Output都通过槽和子槽寻址,从对应模块找到待处理数据,Set_Input用于设置输入数据,Get_Output用于读取输出数据;New_Output函数为输出回调函数,用于在IO模块中有待输出数据时通知用户处理。

New_Output_APDU_Data_Status()用于通知用户输出数据的APDU状态发生改变;Buffer_Snd函数负责判断信息的正确性,并将输入缓冲区的有效数据封装成实时帧,交由DIM模块进行发送,程序流程见图5。

2.3 ACP模块设计

PROFINET系统中,报警是非循环数据事件,需要发送报警信息时,会在收集诊断相关报文后,交给ACP模块处理[10]。Alarm_Now()函数将报警帧添加到报警请求队列中,Alarm_ Process线程依照优先级将该报文从队列中取出发送,同时将其存放到报警应答队列,通过Alarm_Status()函数查询警报处理状态以及来自主站的报警应答事件。应答队列中找到对应的回复报文,即可确认该条报警请求处理完成。如果模块在预设时间内未能等到主站的应答,或接收到处理警报方发送的错误消息,则发送错误消息到CM线程。

3 通信测试

测试环境的搭建通过测试设备的安装和系统组态实现。测试平台包含搭载了协议栈的STM32设备板,S7-1500 PLC和SCALANCE X208交换机。系统组态采用TIA Portal v14软件。

图5 IO通信模块Buffer_Snd程序流程图

首先,利用PLC 1500通过SCALANCE X208交换机连接PROFINET IO应用平台,通过TIA Portal安装之前编写的设备GSD文件,并与S7-1500进行组态,完成PROFINET IO通信网络的搭建;然后,设备板通过ENC28J60引出网线连接至PC端,搭建与putty超级终端的连接,实现对PROFINET IO应用平台接收数据的观测。硬件测试环境搭建实物图如图6所示。

图6 硬件测试环境搭建实物图

3.1 数据帧抓包测试

在搭建好的测试环境中,建立PLC与设备板间的循环RT数据收发,通过Wireshark监听,并抓取其中一个报文进行解析,如图7所示。

图7 RT报文结构

从该数据帧解析出的信息中可知,发送端S7-1500的MAC地址为08∶00∶06∶13∶02∶11,接收端PROFINET IO设备板的MAC地址为29∶59∶43∶79∶f3∶f4;MAC地址后是以太网类型Ethertype 0x8892,代表当前通信所用协议为PROFINET RT协议;Frame_ID 0x8000,由PROFINET的编号分配可知,该帧是RT_Class_1通信报文,且APDU状态字段显示,RT通信正常。由测试结果可知,本文设计的协议栈能够在一个时钟周期内完整准确的解析与处理RT_Class_1报文,实现了RT_Class_1通信,满足协议的实时性要求。

3.2 数据接收测试

使用虚拟HMI连接PLC,创建一个简易的界面,并设置PLC收发数据地址关联至HMI。在S7-1500收发数据时转换为十进制,并显示于HMI;设备板收发数据转换为十六进制。为便于观测,64bytes数据只在其中8bytes中填入非0数值,输出数据如表1所示。

表1 输出数据列表

终端(putty)监视到的IO设备中接收到的数据,如图8所示。

图8 putty接收数据结果

Data_ output Slot=1 sub=1 length=64表示槽号1,子槽1,进行的是64字节输出,其中O_byte_0、O_byte_1、O_byte_31、O_byte_32、O_byte_33、O_byte_34、O_byte_62、O_byte_63对应接收的十六进制数据不为0,将这些putty监视应用平台得到的数据换算为十进制后,与S7-1500发送的数据对比,发现数据无误,证明应用平台能够接收PROFINET网络的数据,完成读IO控制器的功能。

3.3 数据发送测试

在应用平台通信程序内指定发送内容。在发送任务中设置一组64字节数据,I_byte_0设为0x10,I_byte_1设为0x11,I_byte_31设为0x12,I_byte_32设为0x13,I_byte_33设为0x14,I_byte_34设为0x15,I_byte_62设为0x16,I_byte_63设为0x17。

应用平台将设置好的数据通过PROFINET IO协议发送给S7-1500,S7-1500将接收到的数据存储到本地过程映像区,并同步到TIA Portal,显示在虚拟HMI上,如图9所示。

图9 控制器端接收数据结果

将发送数据换算为十进制后,对比S7-1500接收的数据,结果一致,证明了应用平台能够实现对IO控制器的写数据功能。

4 结论

基于STM32平台,设计了协议栈框架和用于NRT和RT并行通道数据处理功能的多个模块,实现了PROFINET IO协议栈,能根据不同数据帧选择通信模式,在保留了传统以太网处理IT应用功能的同时,也具备了处理循环实时数据的能力。相比其他的PROFINET IO通信方案,该协议栈可移植,可灵活配置,适应性强,成本低廉,实时性达到了RT_Class_1标准,能适用于不涉及运动控制的各种工控领域。测试验证了该协议栈的实时性和可靠性,在工厂生产控制中具有广泛的应用前景。

猜你喜欢
缓冲区线程队列
基于C#线程实验探究
队列里的小秘密
基于多队列切换的SDN拥塞控制*
基于国产化环境的线程池模型研究与实现
线程池调度对服务器性能影响的研究*
在队列里
基于ARC的闪存数据库缓冲区算法①
丰田加速驶入自动驾驶队列
一类装配支线缓冲区配置的两阶段求解方法研究
初涉缓冲区