嵌入式实时系统架构简介和优势
正运动的ZMC系列控制器全部是独立式控制器,可以脱离上位机像PLC一样独立工作的。自带嵌入式实时系统,可以像PLC一样实现高速的逻辑响应和IO响应,这样的架构是进口运动控制器的标准架构。
进口控制器这么设计是因为这样的架构有多种好处:
1)任务调度更简单,实时性更好
Windows是属于GPOS(General Purpose OS),考虑多种用户需求,调度策略(dispatch algorithm)非常复杂,既要考虑前台响应速度又要顾及后台响应能力,既要考虑复杂任务的计算效率,又要考虑简单任务的响应速度,所以尽管Windows非常强大,可以运行复杂的算法,可以运行复杂的语言和函数,但很多时候不适合用来处理需要实时响应的任务(打开任务管理器,看看Windows上有多少进程、多少线程,就可以想象Windows调度有多么复杂了)。所以在高实时性场合一般会使用实时系统(RTOS),而不用GPOS。(IOS和Android都属于RTOS,并且严格限制后台进程,来保证和用户交互的响应速度。Windows CE也属于RTOS)。
正运动控制器通过使用更简单的调度策略(分时调度,牺牲一些计算效率),使用精简指令(不使用复杂的带类的面向对象的语言),实时性能就比Windows好很多,而且很容易实现多任务(Task)并行处理,所以,在需要实时响应的场合就不再需要运动控制器+PLC的组合方式,一个控制器搞定全部,没有数据通讯的麻烦,简单高效。
2)减轻PC计算压力,在消耗大量计算资源的应用例如缺陷检测中优势更明显。
把逻辑控制和运动控制全部使用Basic语言下载入控制器内,视觉处理留在PC,最大化减轻PC计算压力。
3)开发调试更简便。
Basic指令更简洁、更清晰,开发速度更快。
即使不使用Basic写程序,在PC上写程序,通过Zdevelop开发调试工具也可以通过“轴参数”或者“在线命令”方便的查看当前各个参数状态;可以通过“在线命令”实时修改参数;可以通过“示波器”查看速度曲线.......
(关于Zdevelop的详细内容可以参考光盘资料中的入门文档或者教学视频。)
Basic程序简单介绍
正运动控制器内部运行的程序主要是Basic程序,语法和VB一致,但比VB更简单,对于软件工程师来说非常友好。并且为了让客户使用更简单,不需要定义数据类型,任意赋值自动判断。甚至文件内变量和局部变量都不需要定义(只有全局变量需要),编译器自动判断,最终的结果是,非常容易上手,开发更快,不容易出错。
Zdevelop开发工具可以进入调试模式,单步运行,观察任务状态、全局变量和局部变量。程序中可以方便的插入Print(等同于?操作符)指令把字符串或者变量输出到终端方便Debug(相当于C语言中的printf)。
正运动控制器支持多任务(多线程),但创建多线程要比Windows程序简单的多,可以非常方便的实现多任务并行运行。
可以通过ticks或者timer等方式实现恒定频率扫描程序。
(更多详细内容请参考ZBasic帮助手册。)
这样的架构,使正运动控制器不仅支持像其他国产控制器一样完全在PC上调用函数来控制,也支持完全把运动控制和逻辑控制用Basic写在控制器里,也支持部分程序写在控制器里,部分程序写在PC上,充分发挥各自的优势,非常消耗CPU计算能力的复杂算法放在PC上,简单的对响应速度要求很高的放在控制器上,两者可以通过全局变量、Table、VR变量等方式来交换数据,Basic程序也可以向PC程序主动上报信息(PC程序中需要部署回调函数,不熟悉GC回收的话不建议这样使用)。
和PC程序的互动方式
下面就是因为使用这种独特架构带来的其他国产控制器厂商所没有的交互方式和独有的函数:
控制器上的Basic程序可以通过指定一个自动运行号,让这个任务上电自动运行,并且适当的时候调用其它任务(调用其他程序文件或者sub子程序)。也可以在合适的时机由PC程序发送Basic字符串指令来运行某个任务,例如控制器上有一个文件叫“BasicInit.bas ”,那么可以调用ZAux_Execute函数发送字符串(run “BasicInit ”)来运行起来这个文件,让它以一个任务(线程)的方式运行起来。
Table是控制器上的超大一维数组,VR也是一维数组,但VR变量是掉电保存的,是存在电池备份内存上的,访问速度又快,用不用担心掉电丢失。具体的介绍可以参考ZBasic帮助文档的第一章。
一方面不论控制器上Basic还是PC上的函数(如ZAux_Direct_SetTable)都可以共同访问修改Table和VR变量,把table等作为控制器和PC共享buffer,实现大量数据异步交换,实现最大计算效率。另一方面PC还同时可以访问用户在Basic中定义的全局变量(例如global UsrVar),例如使用ZAux_Direct_GetVariableInt,但如果想要修改自定义全局变量的话就需要调用函数ZAux_DirectCommand发送(”UsrVar= 0 ”)这样的字符串。
Basic程序运行完毕后,如果想要主动通知PC程序,而不是等待PC查询,可以在PC程序中部署回调函数,PC不再需要轮询查询(如果不熟悉GC回收,不建议使用回调函数)。
目前PC上的函数已经很丰富了,但如果还是想要访问控制器Basic支持的,而PC函数暂时不支持的轴参数(例如AXIS_STOPREASON)可以ZAux_Direct_SetParam和ZAux_Direct_GetParam来访问。
如果想要一次读取或者设置大量的IO变量、大量的位置状态,可以使用输入输出函数中带modbus前缀的函数,如GetModbusIn,这样命名是因为在控制器内部有些modbus寄存器映射到这些地址上了(GetModbusIn只反应IO的真实状态,反转指令无效。如果需要反转之后的状态,需要使用ZAux_Direct_GetInMulti)。
备注1, 具体某个型号的控制器有多少Table和VR变量,支持多少任务(Task),都可以使用ZDevelop在“在线命令”中输入?*max来查看。)
备注2, PC函数中DirectCommand和Execute的用法一致,都是通过PC发送一个控制器支持的Basic字符串指令,但DirectCommand运行速度更快,尽量使用DirectCommand,经测试,DirectCommand大多没有返回字符串,所以参数中的最后一个返回的字符串长度可以设置为0,Execute发送的指令出错后,第三个参数可以返回错误信息,想要显示的话可以用System.Text.Encoding.ASCII.GetString把byte数组转化为字符串(可以参考C#例程“例程8-功能测试”)。DirectCommand和Execute函数本身返回数值,正常运行则为0,不正常则返回非零值,所以在多数场合可能只要判断返回值就可以了,不需要去查看返回字符串。
Basic程序的扫描频率和如何实现恒定频率扫描
用过PLC的客户往往对正运动控制器嵌入式系统的扫描频率有疑问,正运动控制器和PLC不一样的地方是没有标准的任务可供客户使用来实现恒定频率扫描,但可以自己写程序使用多种方式让控制器内的Basic任务实现恒定频率扫描。
正运动控制器自带的嵌入式实时系统运行方式和Windows程序比较相似的是如果没有人为约束,没有恒定的扫描频率,CPU有空闲就去运行用户程序,最大化利用CPU资源,所以除去固件运行所占用的时间和EtherCAT主站计算所占用的时间,剩下的全是用户程序的运行时间。用户的程序越短,扫描频率越高。所以,虽然系统的中断周期一般为1ms或者0.5ms,但如果程序足够短,它在一个中断周期内会运行很多次(具体数量取决于客户程序),可能超过大多数客户的需求(不同系列控制器CPU速度不一样)。
当一个任务需要很高的实时性时,推荐把这部分任务单独放入一个Task内,代码行数尽量短,那么它的扫描频率就非常高。对实时性要求不高的就和其它一起合并放入一个大的任务(Task)。
如何计算当前任务的扫描时间?
使用Ticks,赋予Ticks一个初始化值,每过1ms系统就会减一,可以用于计算扫描时间,例如:
(注意,ticks是属于单个任务的变量,不是全局变量)
如何以恒定频率扫描程序?
1)使用Ticks:
2)使用硬件时钟Timer:
需要注意的是所有硬件时钟中断任务的处理任务(Task)只有1个,所以如果使用了多个硬件时钟中断,并且执行时间比较长,推荐把相关代码放入另外一个程序文件里,run这个程序文件,不要让中断程序独占当前task。
备注:
1)关于程序(Program)和任务(Task),任务和PC上的线程比较相似,并行运行,可以共享全局变量。一个程序文件(Program)可以被run起来多个Task(多个instance),所以在上面的示例注释中写着要小心不要run起来多个Task,把Timer_Start放入中断程序结尾。(可以在调试模式下观察现在有几个task在运行)
2)因为控制器使用了实时系统,所以要使用循环扫描,可以很安全的使用while 1,这个Task的时间片用完后就会切换任务,不用担心控制器资源都被锁死在当前任务。
666~更多学习方法可以到这个网站看下!上海会通自动化科技发展有限公司 http://www.shhuitong.net/companyfile/2/