基于STM32 的解释型下位机PLC 设计

2022-05-24 11:44张礼杰殷建军
电子设计工程 2022年10期
关键词:堆栈触点指令

张礼杰,殷建军

(1.浙江正泰仪器仪表有限责任公司量测技术研究院,浙江 杭州 310000;2.浙江工业大学机械工程学院,浙江 杭州 310000)

随着微电子技术的快速发展,PLC 已由最初的一位机发展到了现在的以16位或者32位微处理器构成的微化PC,PLC 技术也越来越成熟、控制功能越来越强大、上位机功能越来越丰富,功耗和体积减小,模块化程度越来越高,成本下降,故障检测也更为灵活方便,使PLC 向连续生产过程发展,成为实现工业生产自动化的一大支持。当前,PLC 编辑的程序解析运行方式主要有编译型和解释性两类,这两类各有各的优缺点,编译型PLC 是上位机嵌入编译链的工具,将用户编写的程序编译为PLC 处理器可以运行的二进制代码,其优点是程序运行速度快、执行效率高,但可移植性差,在上位机上实现仿真/监控功能的难度大。解释型PLC 是将用户编写的程序逐句转化成相应的中间过程语言,再用通信的方式把中间过程语言下发给PLC 处理器,PLC 处理器对收到的中间过程语言逐句进行解释和执行。其优点是移植性强,由于中间过程语言是设计者能识别的语言,所以可以出现像其他编程软件一样的各种仿真界面,包括单步、全速仿真,可设置断点,人为修改仿真变量、监控仿真值,大大方便了产品的开发和问题查寻。但是由于中间过程语言是逐句解释执行的,所以程序执行速度相对较慢,随着PLC 处理器的运行速度越来越高,解释型PLC 的运行速度也越来越高,单个PLC 梯形图的执行速度可以在1 μs以下。文中采用解释型PLC的设计方法。

1 整体架构

文中采用的处理器平台为STM32F446 的ARM处理器,时钟频率设为180 MHz,flash 为256 K,其中64 K 用于存储上位机下发的中间过程语言,SRAM为128 K,其中64 K 用于放置供解释器解析的中间过程语言。上位机下发的中间过程语言采用IAP 方式存放到flash 中,然后系统把flash 里的中间过程语言搬到SRAM 里供解释器解释。

2 中间过程语言解释的设计

中间过程语言是上位机与下位机内部协议规定的,与指令表是一一对应的关系。表1 为指令表与中间过程语言的一一对应关系,上位机与下位机各存一份一样的表格,上位机通过该表格逐句把指令表转化成中间过程语言发给PLC 下位机。下位机通过该表格,可以把中间过程语言翻译成上位机真实的指令表,并对指令表进行逐句解释。

表1 指令表与中间过程语言的对应关系

指令表分为操作码和操作数,操作码代表具体的指令表类型,操作数代表实际要读写的数据或者地址,每类指令表操作码的类型和长度是固定的(2字节),操作数的类型和长度也是固定的(每类操作码都有对应长度的操作数),这就为指令表转化为中间过程语言提供了可行性。解释型下位机架构如图1 所示。

图1 解释型下位机架构

程序指针指向中间过程语言存放的首地址时开始解析,取两个字节操作码,通过查表格得出该操作码是哪类指令表,获取该指令表对应操作数的个数和长度,把操作数取出来解释后放到共享内存里。

为了高效解释中间过程语言,设计了一种函数指针跳转的方式,具体做法是把所有指令表做成一个个独立的单元函数,把所有的单元函数名作为指针统一存放在调用的单元函数指针表格里。解释器解释完该句的操作码和操作数后,通过操作码取出单元函数指针表格里的单元函数指针,跳转到相应的单元函数入口地址,单元函数从共享内存处取操作数,执行自身的函数功能,执行完后跳转回解释器处。因为指令表个数至少有几百种,传统的解释器大多使用if-else 和switch-case 的方式进行调用,需要消耗几百条单指令周期。而使用函数指针跳转的方式,则仅仅会消耗掉指针跳转的单条指令周期。

解释器高效执行方案如图2 所示。

图2 解释器高效执行方案

执行完后根据上一条指令表的长度,程序指针往下跳转到第二条指令表的地址,再取两个字节操作码……这样逐条解释,当遇到END 指令表时,表明程序解释完成,再把程序指针指向首地址继续解释。

3 单元函数设计

各个指令表的函数设计成一个个高内聚无耦合的独立单元函数,供解释器间接进行调用。比如LD函数表示取指定触点的状态,执行时先把累加器左移一位压入堆栈,再从共享内存里读取操作数,放到累加器的最低位。函数实现方法如下:

3.1 MPS、MRD、MPP堆栈函数

MPS 为进栈指令,MRD 为读栈指令,MPP 为出栈指令。执行进栈MPS 指令时,将当前触点值压入堆栈存储器第一级;使用一次MPS 指令时,当前触点值压入堆栈存储器第一级,先压入的数据依次向堆栈的下一级推移。执行出栈MPP 指令时,将存入堆栈存储器的各触点值依次上移,最上级触点值读出后从堆栈内消失。读栈MRD 指令可读出存入堆栈存储器的最上级的触点值,堆栈内的触点值不发生上移和下移,堆栈处理函数如图3 所示。

图3 堆栈处理函数

单元函数编写方法如下:

3.2 软中断设计

解释器在上电初始化时,先把所有中间过程语言扫描一遍,记录下所有中断指令表的指针地址。中断指令表如表2 所示。

表2 中断指令表

当解释器在逐句解释中间过程语言时发生中断,先把共享内存里所有的操作数压入堆栈,把当前正在解释的中间过程语言的指针地址也压入堆栈,再由ARM 判断中断类型,然后根据相应的中断类型跳转到相应的中断函数入口地址,解释器从该地址开始逐句进行解释,当解释到IRET 函数时,从堆栈处取出之前压入堆栈的所有操作数,放回共享内存,取回之前中间过程语言执行的地址,跳转回之前的地址继续解析,如图4 所示。

图4 中断解释处理图

3.3 上升缘NP/下降缘PN触发函数

上升缘NP 的用法是当该条线路上的上一周期的信号为断开时,当前周期的信号为闭合,信号发生上升沿变化,则执行信号后面的动作。梯形图NP 如图5 所示。

图5 梯形图NP

NP 指令前面触点的类型是一个黑盒,串联和并联网络关系是不确定的,这就造成NP 函数没办法用常规的逻辑函数进行编写。文中采用的思路如下:中间过程语言一共有64 K,解释器从第一条开始,根据具体的指令,按照顺序或者跳转的方式进行解析,每解析一句,都会更新当前地址,所以每条中间过程语言在SRAM 里的地址都是确定的并且是可以获得的。开辟一个8 K 的SRAM 空间ACC_BIT_PN[0x2000],每位对应中间过程语言的每个地址。当解释器解释到NP 指令时,读当前解释器解释到的地址,再读出当前累加器(触点)的值,存储到ACC_BIT_PN[0x2000]缓存区里。当下一周期解释器解释到NP 指令时,从ACC_BIT_PN[0x2000]缓存区里取出上一周期累加器的值,再比较当前累加器的值,如果上一周期的值是断开,当前周期的值是闭合,则累加器的值置1,当前触点闭合,执行触点后面的动作;否则当前累加器的值清零,不执行触点后面的动作,并把当前累加器的值存储在缓存区ACC_BIT_PN[0x2000]对应的地址下面。函数编写如下:

4 结论

文中根据指令表的特点,提出用函数指针的方式,高效地对PLC 指令表进行逐句解释。根据PLC堆栈先进后出按序排列的机制,设计堆栈函数的实现。根据中断执行中间过程语言跳转和返回的特点,设计程序实现PLC 的软中断。根据上升缘/下降缘指令的特点,设计实现上升缘/下降缘指令函数的程序。文中提出的方法已经应用到实际开发中,实际应用证明,通过上位机下载的中间过程语言能够

被下位机PLC 解释器正确、高效地解释,只需要一个机器指令周期就可以进入梯形图程序解释接口。

猜你喜欢
堆栈触点指令
中国人民大学新闻学院教授 林升栋:将消费者触点思维融入广告媒体计划
基于行为监测的嵌入式操作系统堆栈溢出测试*
航空电转换器的损伤原因分析及修理
《单一形状固定循环指令G90车外圆仿真》教案设计
接触器辅助触点接触电阻产生原因分析
基于堆栈自编码降维的武器装备体系效能预测
一种航天器软件进程堆栈使用深度的动态检测方法
中断与跳转操作对指令串的影响
可靠性技术在继电器控制中的应用探讨
一种基于滑窗的余度指令判别算法