昨天与同事讨论JavaScript 的异步编程,异步(Asynchronous, async)是与同步(Synchronous, sync)相对的概念。在计算机传统单线程编程中,程序的运行是同步的,这里的同步不意味着所有步骤同时运行,而是指步骤在一个控制流序列中按顺序执行,而一个异步过程的执行将不再与原有的序列有顺序关系,通俗地讲异步就是从主线程发射一个子线程来完成任务。那么PLC中有没有同步和异步的概念呢?可能很多工程师一直在使用PLC,但是并没有注意到,其实PLC也是有同步和异步概念的,下面就简单介绍一下PLC中的同步和异步。
对于PLC的同步和异步,都是相对于PLC的主循环的,例如OB1或者OB35,这里需要注意OB35是中断而不是异步执行,中断的是主循环,然后运行OB35程序,运行完了再返回到OB1,OB1+OB35运行的程序还是主循环。程序的同步执行是按照顺序执行一个个的功能(感觉这里不能叫做指令,虽然有异步操作指令,但是在每一个PLC扫描周期都是运行的,否则不知道异步操作的结果了),如图1所示。
图1
异步执行是与主循环同时执行的,如图2所示。异步执行的时间可能是多个主CPU的扫描周期,也就是说在多个主循环后才返回结果。
图2
在编写程序时可能不经意就使用到了异步指令,只是没有注意到,例如使用定时器与计数器指令。按照同步执行的原则,在程序中使用定时器,例如5秒,在程序扫描到定时器指令时开始计时,只有等待5秒以后才能执行后续的程序,这样是不行的。所以定时器是异步执行的,当程序扫描到定时器指令时开始计时,定时器自己按照参数的设定进行计时,这个过程与主CPU扫描是无关的。那么下一个扫描周期主CPU是否还执行定时器指令?这个是肯定的,主要是主CPU还要实时监控定时器的状态,例如是否计时完成、还剩余多长时间等,此外主CPU还可以对计时过程进行干预,例如暂停或者停止计时等。
从定时器可以看到,计时的工作完全由定时器独立完成,这说明定时器本身带有独立的处理器,所以说程序异步执行就是主CPU与各个独立的子CPU间进行的通信(输出:发出命令;输入:返回状态),所以程序才能并行运行,任务的异步执行不占用主CPU的资源。这里可以想一想哪些模块是独立于主CPU运行的?例如高速计数器、通信模块、HF类型的IO模块、DP/PN主站和从站等,这些模块或者子模块都带有独立的处理器,如果主CPU需要访问这些模块就需要调用相应的指令,这些指令通常都是异步指令,例如SFC58/59、SFB52/53以及S7-1500的数据记录读写指令。
既然异步指令相当于通信,所以常常一个扫描周期内不能执行完,所以不能在OB100中调用(我看到有在OB100中调用异步指令的,就是调用后监控返回状态,如果没有完成,跳转到开始,这样编程容易造成死循环)。
同时执行异步指令的个数也是有数量限制的,例如调用SFC58/59,如果不考虑这些因素,可能会造成配置错误,例如S7-300的FM355模块,安装多个模块在分布式I/O站点上就不能正常工作,原因是操作该模块的指令中含有SFC58/59,手册上列出的是安装在中央机架上的数量,想当然理解为只要能配置就没有问题,到现场就会出问题(软件能配置是因为可以实现其它的功能,而不是所有功能)。为什么在中央机架上可以安装更多的模块呢?原因就是不是所有的异步指令都是异步执行的,模块安装在分布式I/O站点上,CPU访问该模块调用的异步指令是异步执行的,而模块安装在主机架上,调用异步指令执行的是半异步操作,就是一个周期可以得到返回状态。所以要注意模块在分布式I/O站点上的安装数量。有个简单方法可以判断模块在分布式I/O站点上的安装数量是否受到限制,如果主CPU与模块是通过I/O地址区交换数据的,则可以不用考虑异步指令的限制,因为实际上没有调用异步指令;如果主CPU与模块是通过程序块通信的,可以在程序块的属性中查看是否包含异步指令,如果没有就是通过I/O地址区通信的(为了便于使用,程序块重新封装用于交换数据),不用考虑个数的限制了,但是还要注意槽号和背板电源的限制。有些限制条件在S7-300/400样本中列出来了,但是在S7-1500的样本中有点没有列出,所以在方案配置时还要留一下心。