概论
当前MCGS嵌入式arm平台在v3.2.5版本开始提供对自定义脚本驱动的支持,能兼容大部分原有wince的脚本驱动函数,但也在原有的wince脚本驱动函数上进行了裁剪、修改与完善,比如:取消了对端口操作的支持,修复了部分wince原有脚本驱动函数的bug,修改了部分脚本函数的功能;当前arm平台提供对网络通信的支持,使用方式与串口脚本驱动一致,区别是需要在窗口设备窗口选择通用TCPIP父设备,配置好网络参数后即可实现TCP/IP网络通信。请您在将wince脚本驱动移植到arm平台之前,请务必详细阅读以下内容,保证脚本驱动按照您预期的行为执行。
如何编写自己的脚本驱动
当前arm组态软件暂未提供对脚本驱动编辑、编译与调试功能的支持,用户可使用原有的脚本驱动IDE(DrvConfig软件)实现对脚本驱动的编写、编译以及调试。DrvConfig软件的具体使用说明以及如何编写与调试自己的脚本驱动可参考其对应的帮助文档。需要注意的是用户如果使用了某些arm平台已被删除的脚本驱动函数,可能在组态加载到父设备时会报错,因此对于已经删除的函数,包括:!StrCompCase,!lnp(), !InpW(),!Outp(),!OutpW(),!OutpD(),!InpD(),!SvrOpenLog()以及!SvrCloseLog(),不能再使用;对于基本功能不一致的函数,包括:!StrComp(str1,str2),!InStrRev(n,str1,str2),需要谨慎使用;此外,当前arm平台的脚本驱动函数不支持”;”结束符,请不要再脚本驱动中使用”;”;其它发生变更的函数同样需要了解,确认变更是否对自己的原有的功能产生影响。
脚本驱动函数
脚本驱动函数主要调整了Trace函数的使用以及修复了通道操作相关函数的返回值的bug,其它函数的基本功能与wince一致:
!Trace(OutputString)
函数意义:要在DrvConfig输出窗口打印的字符串或在运行时的日志中记录的字符串;
参 数:OutputString:要在输出窗口打印的字符串或在日志中记录的字符串;
返 回 值: 整型。-1 失败, 0 成功;
实 例:!Trace(!strFormat(“%D”,123))。
注意事项:(1)在调试模式下执行,首先会在输出窗口中打印一个回车换行,然后再打印参数中指定的字符串;
(2)在运行模式下执行,将对应的日志以infomation级别输出到日志记录中,用户可通过设备U盘工具包打开device模块的运行类型的日志查看。
wince对比:基本功能与wince一致,但日志查看方式与wince不同
!GetIntChannelValueByName(DataStr,ByRef n)
函数意义: 根据通道的名字,将该通道的值读出,假设该通道为整型(开关型)变量
参 数: DataStr,字符型,需要读取的通道名的字符串;
n,引用型,整型,保存读出值的变量。
返 回 值: 整型。-1 失败,0 成功。
实 例:!GetIntChannelValueByName (“发电机启动”,n),将通道“显示内容”的值读出,赋给变量n。
注意事项:
wince对比:基本功能与wince一致,修复wince成功返回-1的bug
!GetSingleChannelValueByName(DataStr,ByRef x)
函数意义: 根据通道的名字,将该通道的值读出,假设该通道为单精度浮点型(开关型)变量;
参 数: DataStr,字符型,需要读取的通道名的字符串;
x,引用型,单精度浮点型,保存读出值的变量;
返 回 值: 整型。-1 失败,0 成功。
实 例:!GetSingleChannelValueByName (“温度”,x), 将通道“温度”的值读出,赋给变量x
注意事项:
wince对比:基本功能与wince一致,修复wince成功返回-1的bug
!GetIntChannelValueByNum(DataNum,ByRef n)
函数意义: 根据通道的编号,将该通道的值读出,假设该通道为整型(开关型)变量
参 数: DataNum,整型,需要读取的通道的编号;
n,引用型,整型,保存读出值的变量。
返 回 值: 整型。-1 失败,0 成功。
实 例:!GetIntChannelValueByNum (1,n),将通道1的值读出,赋给变量n;
注意事项:
wince对比:基本功能与wince一致,修复wince成功返回-1的bug
!GetSingleChannelValueByNum(DataNum,ByRef x)
函数意义: 根据通道的编号,将该通道的值读出,假设该通道为单精度浮点型(开关型)变量;
参 数: DataNum,整型,需要读取的通道的编号;
x,引用型,单精度浮点型,保存读出值的变量;
返 回 值: 整型。-1 失败,0 成功。
实 例:!GetIntChannelValueByNum (1,n),将通道1的值读出,赋给变量n;
注意事项:
wince对比:基本功能与wince一致,修复wince成功返回-1的bug
字符串函数
!Left(str,n)
函数意义: 字符型数据对象str左边起,取n个字符
参 数: str,字符型,源字符串
n,开关型,要获取的字符个数,n>=0
返 回 值: 字符型。返回获取到的字符串
实 例: ret = !Left(“ABCDEFG”,2),ret = “AB”
ret = !Left(“ABCDEFG”,20),ret = “ABCDEFG”
注意事项: (1)n > 字符串str的长度时,返回字符串str
(2)n = -1时,返回整串字符
wince对比:基本功能与wince一致,当输入长度<0时,wince返回””,arm返回输入字符串
!Right(str,n)
函数意义: 从字符型数据对象str右边起,取n个字符
参 数: str,字符型,源字符串
n,数值型,取字符个数,n >= 0
返 回 值: 字符型。返回获取到的字符串
实 例: ret = !Right(“ABCDEFG”,2),ret = “FG”
ret = !Right(“ABCDEFG”,20),ret = “ABCDEFG”
注意事项: (1)当n大于字符串str的字符个数时,函数将返回str的全部字符
(2)当n = -1时,返回整个字符串
wince对比:基本功能与wince一致,当输入长度<0时,wince返回””,arm返回输入字符串
!Mid(str,n,k)
函数意义: 从字符型数据对象str左边第n个字符起,取k个字符。计算字符时,从1开始算起
参 数: str,字符型,源字符串,起始位置为1
n,开关型,起始位置,1 <= n <= 字符串str的字符个数
k,开关型,取字符数,k > 0
返 回 值: 字符型。返回获取到的字符串
实 例: ret = !Mid(“ABCDEFG”,4,2),ret = “DE”
注意事项: (1)当n以后的字符个数小于k时,函数将返回n以后的所有字符串
(2)当k = -1时,返回n以后的所有字符
wince对比:基本功能与wince一致,当输入长度<0时,wince返回””,arm返回输入字符串
!StrComp(str1,str2)
函数意义: 比较字符型数据对象str1和str2是否相等,不区分大小写字母
参 数: str1,字符型
str2,字符型
返 回 值: 开关型,= 0,表示两个字符串相等,反之表示不相等
实 例: ret = !StrComp(“ABC”,”abc”),ret = 0
wince对比:基本功能有差异,同为字符串比较,wince区分字母大小写,arm不区分字母大小写
!InStr(n,str1,str2)
函数意义: 查找一字符串在另一字符串中最先出现的位置
参 数: n,开关型,开始搜索的位置
str1,字符串,被搜索的字符串,起始位置为1
str2,字符串,要搜索的字符串
返 回 值: 开关型
> 0表示查找成功
= 0表示查找失败
实 例: ret = !InStr(3,”sdlkfjwe”,”we”),查找成功,ret = 7
ret = !InStr(10,”sdlkfjwe”,”we”),查找失败,ret = 0
ret = !InStr(1,”we”,”sdlkfjwe”),查找失败,ret = 0″
注意事项: (1)当n <= 1时从字符串str1起始位置开始查找
(2)当1 < n < 字符串str1的长度时,第n个字符开始查找
(3)当n > 字符串str1的长度时,函数将返回0
(4)当字符串str1的长度 < 字符串str2的长度,函数将返回0
wince对比:基本功能与wince一致,当n<0时wince返回0,arm将n处理为0
!I2Bin(s)
函数意义: 把数值转换为二进制字符串
参 数: s,开关型
返 回 值: 字符型
实 例: ret = !I2Bin(5),ret = “101”
wince对比:基本功能与wince一致,wince返回值中,若字符串长度不足32位,在字符串前面补0,arm不补0
!I2Ascii(s)
函数意义: 返回指定Ascii值的字符
参 数: s,开关型,参数范围0~127
返 回 值: 字符型
实 例: ret = !I2Ascii(65),转换成功,ret = ‘A’
ret = !I2Ascii(65409),转换失败,ret = ‘?’
注意事项: (1)s = 0~33、127时对应不可见字符,函数将返回空字符串
(2)s = 33~126时对应可见字符,函数将返回对应字符
(3)s = 0~127以外的数据时,返回值不确定
wince对比:基本功能与wince一致,但参数s取值范围wince没有限制,arm限制为0~127
!InStrRev(n,str1,str2)
函数意义: 查找字符串str2在另一字符串str1中第一次出现的位置,字符串的首位置为1; 本函数与Instr函数的区别为,它是从字符串的尾部开始进行查找,尾部位置为1
参 数: n,整型,开始搜索的位置,该位置是从字符串的首位置开始计算的,字符串的首位置为1
str1,字符串,被搜索的字符串
str2,字符串,要搜索的字符串
返 回 值: 开关型
> 0表示查找成功
= -1表示查找失败
实 例: !InStrRev(0,”sdlkfjsd”,”sd”) = 7;!InStrRev(3,”sdlkfjsd”,”sd”) = 1; !InStrRev(3,”lkfjsd”,”sd”) = -1;
注意事项: (1)当n <= 1时从字符串str1起始末位置开始查找
(2)当1 < n < 字符串str1的长度时,倒数第n个字符开始查找
(3)当n > 字符串str1的长度时,函数将返回-1
(4)当字符串str1的长度 < 字符串str2的长度,函数将返回-1
wince对比:基本功能不一致,该函数功能被重新定义,请谨慎使用
!StrCompCase(str1,str2)
wince对比:原有wince用于不区分字母大小写字符串比较,函数已经被删除
时间函数
时间函数与wince的主要不同是时区的问题,wince包含时区,arm没有时区,所以在时间上两则相差8小时,其次输入参数无效时,其返回结果0或空
!TimeStr2I(strTime)
函数意义: 将表示时间的字符串(YYYY-MM-DD HH:MM:SS)转换为时间值
参 数: strTime,字符型,以字符串型表示的时间(YYYY-MM-DD HH:MM:SS)
返 回 值: 开关型,转换后的时间值
实 例: iTime = !TimeStr2I(“2001-01-01 03:15:28”),将表示时间的字符串”2001-01-01 03:15:28″转换为开关型的时间值iTime,iTime = 978290128
注意事项: (1)时间字符串格式为yyyy/MM/dd hh:mm:ss或yyyy-MM-dd hh:mm:ss
(2)时间字符串必须输入完整,否则失败且返回0
(3)时间范围1970年1月1日0时0分0秒-2100年12月31日
wince对比:基本功能与wince一致,但wince时间包含时区,arm暂时没有包含时区;输入无效的时间格式字符串,wince默认处理,arm返回0
!TimeI2Str(iTime,strFormat)
函数意义: 将时间值转换为字符串表示的时间
参 数: iTime,开关型,时间值(大于0小于2147483647)strFormat,字符型,转换后的时间字符串的格式
返 回 值: 字符型,转换后的时间字符串
实 例: strTime = !TimeI2Str(iTime,”%y,%m,%d,%H,%M,%S”),当iTime=0时,strTime为“1970,01,01,00,00,00”.表示1970年1月1日0时0分0秒.
说 明: !TimeI2Str的格式化标准为:
%d,月份中日期的十进制表示。如:07表示7日
%H,24时制的小时表示。如:17表示下午5时
%m,月份的十进制表示。如:06表示6月
%M,分钟的十进制表示。如:28表示28分
%S,秒钟的十进制表示
%X,适合当地的时间表示。如:9时47分12秒表示为:09:47:12
%Y 或者 %y,显示世纪的年的十进制表示。如:2001表示2001年
%%,百分号表示
wince对比:基本功能与wince一致,但wince时间包含时区,arm暂时没有包含时区
!TimeGetDayOfWeek(iTime)
函数意义: 获取时间值iTime中的星期
参 数: iTime,开关型,时间值(大于0小于2147483647)
返 回 值: 开关型,时间值iTime中的星期
实 例: data = !TimeGetDayOfWeek(iTime),获取时间值iTime中的星期(data的值为1表示星期一, 2表示星期一二,……7表示星期日)
注意事项: iTime为!TimeStr2I(strTime)得到的值
wince对比:基本功能与wince一致,但wince时间包含时区,arm暂时没有包含时区;
!TimeGetHour(iTime)
函数意义: 获取时间值iTime中的小时
参 数: iTime,开关型,时间值(大于0小于2147483647)
返 回 值: 开关型,时间值iTime中的小时(0~23)
实 例: ret = !TimeGetHour(iTime),ret为时间值iTime中的小时
注意事项: iTime为!TimeStr2I(strTime)得到的值
wince对比:基本功能与wince一致,但wince时间包含时区,arm暂时没有包含时区;
!TimeSpanGetDays(iTimeSpan)
函数意义: 获取时间差中的天数(时间差由!TimeGetSpan()函数计算得来)
参 数: iTimeSpan,开关型,时间差,参数>0且<2147483647
返 回 值: 开关型,时间值iTime中的天数(1~31)
实 例: ret = !TimeSpanGetDays(TimeSpan),ret为时间差TimeSpan的天数
注意事项: iTimeSpan为!TimeGetSpan(iTime1,iTime2)的值
wince对比:基本功能与wince一致,但wince时间包含时区,arm暂时没有包含时区;
端口操作
wince脚本驱动支持对端口的操作,当前arm平台没有提供对端口操作的支持,因此以下几个函数在arm平台已被删除:!lnp(),!InpW(),!Outp(),!OutpW(),!OutpD(),!InpD()。
串口(网络)字符串函数
当前arm保持其基本功能不变,提供对网络通信的支持,统一了通信脚本函数的错误返回值,包括:串口异常或串口未打开返回-1,数据发送失败返回-2,数据接收失败返回-3,用户输入的发送长度<=0返回-4, 用户输入的接收长度<=0返回0,匹配数据长度<=0返回-5,其它错误返回-6。用户可先在DrvConfig编写的串口类型的脚本驱动(因DrvConfig当前不支持网络脚本驱动),在组态设备窗口中安装为通用TCPIP父设备的子设备,配置好网络父设备的相关参数,如此可实现对TCP/IP网络通信的支持。
!DevReadStr(ByRef str1,n1,n2)
函数意义:从父设备读取一定长度的字符串。
参 数: str1, 传址型,字符型,接收的字符串
n1,整型,需接收的字符数,接收到足够多的字符则返回
n2,整型,等待的时间,如果超过时间尚未读到足够的字符也返回,如果为0则直接返回
返 回 值:整型;
>0:读的字符数
=0:读取的字符串长度<=0
-1:串口异常或没有打开
-3:读超时,未读入一个字符
-6:其它错误
实 例: !DevReadStr(str,20,500)从父设备读取字符串,如果在500毫秒内已读到20个字符,则返回,如果超过500毫秒未读取到20个字符,超时返回
注意事项:
wince对比:基本功能一致,错误返回值不一致。
!DevWriteStr (str)
函数意义:向串口或网络写一个字符串。
参 数: str,字符型,写入的字符串
返 回 值:整型
>0:写入字符数
-1:串口异常或没有打开;
-2:写入超时
-4:写入的字符串长度<=0
-6:其它错误
实 例: ! DevWriteStr(”ABCDE”)向父设备写入字符串”ABCDE”
注意事项:
wince对比:基本功能一致,错误返回值不一致。
!DevReadStrByFind (ByRef str1,str2,n)
函数意义:从父设备读取字符串,直到读到某字符串
参 数: str1, 传址型,字符型,接收的字符串
str2,字符型,需要读取的字符串
n,整型,等待的时间,如果超过时间尚未读到足够的字符也返回,如果为0则直接返回
返 回 值:整型
>0:读的字符数
=0:读取的字符串长度<=0;
-1:串口异常或没有打开
-3:读超时,未读入一个字符
-6:其它错误
实 例: !DevReadStr(str,20,500)从父设备读取字符串,如果在500毫秒内已读到20个字符,则返回,如果超过500毫秒未读取到20个字符,超时返回
注意事项:
wince对比:基本功能一致,错误返回值不一致。
!DevWriteAndReadStr (str1,ByRef str2, n1, n2)
函数意义:往父设备发送一字符串,等待,再从父设备读取指定的字符串
参 数: str,字符型,写入的字符串
str2, 传址型,字符型,接收的字符串;
n1,整型,需要接收的字符数量;
n2,整型,读写整个过程的等待延时,单位为毫秒,0表示采用系统缺省的等待时间;
返 回 值:整型
>0:读的字符数
=0:读取的字符串长度<=0
-1:串口异常或没有打开
-2:写入超时
-3:读超时,未读入一个字符串
-4:写入的字符串长度<=0
-6:其它错误
实 例:!DevWriteAndReadStr(”ABC”,InStr,30,500)往串口发送字符串”ABC”,发送数据完毕后,再从串口设备中读取字符串,如果已读到30个字符,或者500毫秒内尚未取读完毕,则返回
注意事项: 该函数首先调用清缓冲区的功能
wince对比:基本功能一致,错误返回值不一致。
!DevWriteAndReadStrByFind(str1,ByRef str2, str3, n)
函数意义:往父设备发送一字符串,等待,再从父设备读取指定的字符串
参 数: str,字符型,写入的字符串
str2, 传址型,字符型,接收的字符串
str3,字符型,匹配的字符串
n,整型,读写整个过程的等待延时,单位为毫秒,0表示采用系统缺省的等待时间
返 回 值:整型
>0:读的字符数
-1:串口异常或没有打开
-2:写入超时
-3:读超时,未读入一个字符串
-4:写入的字符串长度<=0
-5:匹配字符串长度<=0
-6:其它错误
实 例:!DevWriteAndReadStrByFind(”ABC”,InStr,Chr(13),100)往串口发送字符串”ABC”,发送完毕后,再从串口中读取字符串,如果已读到回车符,或者100毫秒内尚未取读完毕,则返回
注意事项: 该函数首先调用清缓冲区的功能
wince对比:基本功能一致,错误返回值不一致。
串口(网口)字节数组函数
!DevReadByte (ByRef byte,n)
函数意义:从父设备读取一定长度的字符串
参 数: byte, 传址型,字节型,保存读取的字节
n,整型,等待的时间,如果超过时间尚未读到足够的字符也返回,如果为0则直接返回
返 回 值:整型
=0:调用正常
-1:串口异常或没有打开
-3:读超时,未读入一个字符
-6:其它错误
实 例:! DevReadByte(A,100)从父设备读取一个字节,如果超过100毫秒则直接返回
注意事项:
wince对比:基本功能一致,错误返回值不一致。
!DevWriteByte (byte)
函数意义:向父设备写入一个字节
参 数: byte,字节型,写入的字节
返 回 值:整型
=0:调用正常
-1:串口异常或没有打开;
-2:写入超时
-6:其它错误
实 例:!DevWriteByte(byte)向父设备写入byte
注意事项:
wince对比:基本功能一致,错误返回值不一致。
!DevReadByteArr (ByRef byteArr,n1, n2)
函数意义:从父设备读取一定长度的字符串
参 数: byteArr, 传址型,字节数组,保存读取的字节数组
n1, 整型,需接收的字符数,接收到足够多的数据则返回;
n2,整型,等待的时间,如果超过时间尚未读到足够的字符也返回,如果为0则直接返回
返 回 值:整型
>0:读取到的字节数
-1:串口(网络)异常或没有打开
-3:读超时,未读入一个字符
-4:读取数据长度<=0
-6:其它错误
实 例:!DevReadByteArr(BA,20,500)从父设备读取数据,如果在500毫秒内已读到20个字节,则返回,如果超过500毫秒未读取到20个字节,超时返回
注意事项:
wince对比:基本功能一致,错误返回值不一致。
!DevWriteByteArr (ByRef byteArr,n)
函数意义:向父设备写入一个字节数组
参 数: byteArr,字节型,写入的字节数组
n,写入的字符数
返 回 值:整型
>0:写入的字节数
-1:串口(网络)异常或没有打开
-2:写入超时,未写入一个字节
-4:发送数据长度<=0
-6:其它错误
实 例:!DevWriteByteArr(BA,10)向父设备写入byte, 向父设备写入字节数组的前10个字节。如果,字节数组长度小于指定的长度,那么实际长度有效
注意事项:
wince对比:基本功能一致,错误返回值不一致。
!DevReadByteArrByFind (ByRef byteArr1, ByRef byteArr2 ,n1,n2)
函数意义:从父设备读取数据,直到读到某匹配的内容
参 数: byteArr1, 传址型,字节数组型,接收的数据
byteArr2,传址型,字节数组型
n1,整型,由参数2和参数3组成一定长度的匹配字节数组,如果从串口读到对应的数据,则返回;
n2,整型,等待的时间,如果超过时间尚未读到对应的数据也返回,如果为0则直接返回
返 回 值:整型;
>0:读的字符数
=0:读取的字符串长度<=0
-1:串口异常或没有打开;
-3:读超时,未读入一个字符;
-5:匹配的字节长度<=0
-6:其它错误
实 例:! DevReadByteArrByFind(BA,find,4,500)从父设备读取数据,如果在500毫秒内已读到find数组的前4个字节匹配的内容,则返回,如果超过500毫秒未读到匹配的内容,超时返回
注意事项:
wince对比:基本功能一致,错误返回值不一致。
!DevWriteAndReadByteArr(ByRef byteArr1,n1, ByRef byteArr2, n2, n3)
函数意义:往父设备发送一字节数组,等待,再从父设备读取指定的长度的数据
参 数: byteArr1, 传址型,字节数组型,发送的数组;
n1,整型,发送数组的长度
byteArr2,传址型,字节数组型,接收的数组;
n2,整型,需要接收的字节数量
n3, 整型,读写整个过程的等待延时,单位为毫秒,0表示采用系统缺省的等待时间
返 回 值:整型;
>0:读的字节数。
=0:读取的字节数组长度<=0
-1:串口(网口)异常或没有打开
-2:写入超时
-3:读超时,未读入一个字节
-4:写入的字节数组长度<=0
-6:其它错误
实 例:!DevWriteAndReadByteArr(OutBA,10,InBA,30,500)往串口中发送OutBA数组的前10个字节,发送完毕后,再从父设备中读取数据,如果已读到30个字节,或者500毫秒内尚未取读完毕,则返回
注意事项: 该函数首先调用清缓冲区的功能
wince对比:基本功能一致,错误返回值不一致。
!DevWriteAndReadByteArrByFind (ByRef byteArr1,n1, ByRef byteArr2, ByRef byteArr3, n2, n3)
函数意义:往父设备发送一数组数据,等待,再从父设备读取数据,如果已读到指定的内容,则返回
参 数: byteArr1,传址型,字节数组型,发送的数组
n1,整型,发送数组的长度
byteArr2,传址型,字节数组型,接收的数组
byteArr3,传址型,字节数组型,匹配的数组
n2,整型,匹配的数组的长度
n3,整型,读写整个过程的等待延时,0表示不判断是否超时
返 回 值:整型
>0:读的字节数
-1:串口(网口)异常或没有打开
-2:写入超时
-3:读超时,未读入一个字节
-4:写入的字节数组长度<=0
-5:匹配字节数组长度<=0
-6:其它错误
实 例:! DevWriteAndReadByteByFind(OutBA,10,InBA,Find,4,500)往串口中发送OutBA字节数组的前10个字节,发送完毕后,再从父设备中读取数据,如果已读到Find数组的前4个字节匹配的内容,或者500毫秒内尚未取读完毕,则返回
注意事项: 该函数首先调用清缓冲区的功能
wince对比:基本功能一致,错误返回值不一致。
数据校验函数
删除开启日志!SvrOpenLog()以及关闭日志的!SvrCloseLog()函数,arm平台通过设备商U盘功能包来实现对日志开启与关闭,详见设备商U盘功能包的使用文档;其他校验函数与wince保持一致。
初始化脚本
启动脚本并不是在启动时立即执行,而是在第一次通信连接成功时执行。
退出脚本
退出脚本在运行环境正常退出的时候执行,需要注意的是当前退出脚本里面暂不包含函数以及不能包含循环语句。
编译异常
当前组态软件的脚本函数编译不支持;作为语句的结尾,如x=1;此时DrvConfig可以编译通过,但组态软件加入子设备时会报错,需要将末尾的;删除,x=1即可。