【摘要】:在LonWorks技术中,Neuron芯片的程序设计语言是Neuron C。Neuron C基于标准C并在标准C的基础上进行了自然扩展。Neuron C严格遵守ANSI C语言规则,但不是对ANSI C的全部复制性实现。6)Neuron C的网络变量不能为指针类型。7)Neuron C不支持指向定时器、消息标签和I/O对象的指针。10)Neuron C的网络变量名和报文标签被限定在16个字符以内。
在LonWorks技术中,Neuron芯片的程序设计语言是Neuron C。Neuron C基于标准C并在标准C的基础上进行了自然扩展。Neuron C没有使用标准C的部分功能,如标准的函数库等,Neu-ron C提供了在LON网络环境下的一些特定对象集合以及访问这些对象的内部函数。Neuron C提供了一些适用于LonWorks应用系统开发的新功能。
Neuron C提供的部分新功能如下:
1)网络变量:一个新的对象类,网络节点间的数据通信和数据共享。
2)when语句:一个新的语句类型,用来引入对事件当前时间序列进行定义,引入事件(e-vents)驱动机制,整个应用程序用when语句引导。
3)I/O操作的显式控制,使Neuron芯片的多功能I/O接口标准化,便于对多种类型的信号进行监控。
4)支持显式报文,用于直接访问基础的LonTalk协议服务。
1.Neuron C与ANSI C语言的区别
美国国家标准局(ANSI)颁布的ANSI标准X3.159—1989,也就是ANSI C标准,由这个标准定义的C语言被称作ANSI C。Neuron C严格遵守ANSI C语言规则,但不是对ANSI C的全部复制性实现。Neuron C与ANSI C之间的主要区别如下:
1)Neuron C不支持浮点运算:浮点运算就是实数运算,浮点运算速度很慢。机器有两种办法表示实数:一种是定点,就是小数点位置是固定的;另一种是浮点,就是小数点位置不固定,计算方法也比较麻烦且计算量大。浮点运算使用3种不同的数据:
① 整数(Integer),又分为字、短整数(Short Integer)和长整数(Long Integer);
② 实数(Real),分单准确度(Single Real)和双准确度(Double Real);
③ 压缩的二-十进制数。
浮点数比定点数的表述范围宽,有效准确度高,更适合于科学计算与工程计算。浮点运算可分为2类:非规格化和规格化浮点运算。非规格化浮点运算,不要求操作数是规格化数,对运算结果也不要求规格化处理。而规格化浮点运算只能对规格化的浮点数进行操作,并且要求对运算结果加以规格化处理。
Neuron C尽管不支持浮点运算,但它提供了一个浮点库,允许使用符合IEEE 754标准(IEEE二进制浮点数算术标准)的浮点数。
2)ANSI C定义short int为16位或多于16位,long int为32位或多于32位;而Neuron C定义short int为8位,long int为16位。在Neuron C中,int默认为short int。如果需要使用32位的值,可以使用32位有符号整数库。
3)Neuron C不支持register或volatile类。
4)Neuron C在自动(auto)变量定义时不对其赋初值。
5)Neuron C不支持将结构体(structure)和共用体(union)作为过程参数或作为函数的返回值。
6)Neuron C的网络变量不能为指针类型。
7)Neuron C不支持指向定时器、消息标签(Message Tag)和I/O对象的指针。
8)Neuron C指向网络变量和EEPROM变量的指针被当作指向常量(const)的指针,被这个指针引用的变量内容可读但不能被修改。
9)Neuron C的宏被扩展后,宏参数才能被重复扫描。宏操作符“#”和“##”在嵌套的宏表达式中出现时,不能像ANSI C定义的那样产生相应的结果。
10)Neuron C的网络变量名和报文标签被限定在16个字符以内。
11)一些标准C库函数(如memcpy()和memset()等)被Neuron C所保留。Neuron C还提供有针对字符串和字节的操作库,从而允许用户使用定义在〈string.h〉头文件中的标准C函数的子集。其他的标准C库函数(如文件I/O和存储分配函数等)并不包括在Neuron C中。
12)Neuron C包括3个标准头文件:〈stddef.h〉、〈stdlib.h〉和〈limits.h〉。
13)如果出现函数调用先于函数定义的情况,Neuron C要求首先声明函数原型。
14)Neuron C包含了一些补充的保留字和语法,这些保留字和语法并不包括在ANSI C中。
15)Neuron C支持二进制常数,作为对八进制和十六进制的补充。二进制常数以0B<二进制数>的形式定义,例如,0B1101等于十进制数13。
16)Neuron C支持来自C++的//…注释格式,作为对传统/∗…∗/注释格式的补充;在//…格式中,两个斜杠(//)开始一个注释行。
17)Neuron C不再使用main()函数结构,而是代之以由when()语句和函数组成的Neu-ron C程序的可执行对象。
18)Neuron C不支持标准C的预处理指令#if、#elif和#line,但支持#ifdef、#els和#endif。
2.事件驱动和when语句
Neuron C中,控制程序中采用事件驱动(event driven)方式进行任务调度,程序中的when语句中的条件变为真,则条件关联的应用程序代码被执行。被执行的任务有优先级的不同,执行的顺序也不同。
在事件驱动方式中,一个when语句就是一个表达式,当表达式描述的条件为真时,表达式后面的任务代码被执行。一个简单的when语句和实现定时关闭一只LED灯的控制情况如下:
when(timer expires(led_timer))
{
//turn off the LED
io_out(io_led,OFF)
}
语句中,已经在程序的其他部分定义过的led_timer软件定时器设定时间到达后,turn off the LED io_out(io_led,OFF)代码段被执行,完成LED灯的关闭。
定义在when语句中的事件一般分为两种类型:预定义事件和用户定义事件。预定义事件包括输入引脚状态的改变、网络变量的改变、计时器终止和报文的接收等,用户定义事件可以使用任何有效的Neuron C表达式。
用户定义事件和预定义事件的区别并不是非常严格的,但由于预定义事件使用的代码空间较少,因此要尽可能使用预定义事件。
(1)预定义事件
前面出现过的事件timer_expires是一种类型的预定义事件,某些I/O事件和网络变量事件,其后面可能加有修饰符(modifier)以限制事件的作用域。常使用的预定义事件如下:
io_changes //输入I/O对象的输入值发生改变
io_update_occurs //输入I/O对象值改变,只对定时器/计数器I/O对象有效
nv_update_occurs //输入网络变量接收到新值
nv_update_completes //输出网络变量发送完成
nv_update_fails //输出网络变量发送失败
nv_update_succeeds //输出网络变量发送成功
offline //接收到offline(使节点离线)网络管理报文
online //接收到online(使节点在线工作)网络管理报文
reset //Neuron芯片被复位
timer_expires //定时器定时间隔到
预定义事件还可以用作子表达式,包括在if、while和for语句的控制表达式里,例如:
#define OFF 0 //预定义OFF为0
IO0 output bit io led; //定义IO0引脚为输出I/O对象,且为bit(只有高、低两种电平)类型
mtimert; //定义一个以毫秒为计时单位的软件定时器t
when(事件)
{ …
if(timer_expires(t)) //定时器t时间到时为真
io_out(io_led,OFF); //io_led输出I/O对象对应的IO0引脚输出低电平
…
}
在使用Neuron C编程的过程中,任何内部预定义事件关键字表达式(例如timer_expires(t))与其他子表达式和任何被标准C表达式语法允许的组合都被同等对待。
(2)用户定义(user_defined)事件
用户定义事件可以包含赋值和函数调用,在用户定义的事件内,只能对全局变量赋值。
例如:
int a;
…
when(a==0)//用户自定义a=0时间为真时,执行后面的程序代码
{
…
}
(3)reset(复位)事件
在Neuron芯片由于某种原因被复位(如芯片刚上电、人为将RESET引脚接低电平等)后re-set事件为真。芯片被复位后所执行的第一个任务为reset事件后的任务。格式为:when(reset)
(4)when语句的调度
调度程序以由上到下循环的方式检测when语句,每一个when语句都由调度程序检测,如果为真(TRUE),则与其相关联的任务就被执行;如果when语句为假(FALSE),调度程序将继续检查后面的when语句。在检查完最后一个when语句后,调度又返回至队列首部重复执行上述过程。
when语句的语法如下:
[priority]when(事件)
{
…
}
Priority关键字用于设定优先级when语句,这种when语句被检测的次数多于无优先级的when语句。如果任何优先级when语句被检测为真,则与它相对应的任务就被执行,然后调度程序又重新回到第一个优先级when语句处,从头开始检测优先级when语句。如果任何一个优先级when语句都没有被检测为真,调度程序才以如前所述的循环方式检测无优先级when语句。如果选上的无优先级when语句检测为真,它的任务被执行,然后调度程序重新回到第一个优先级when语句处;如果该无优先级when语句被检测为假,则它的任务被忽略,调度程序重新回到第一个优先级when语句处。
使用优先级when语句必须仔细考虑。因为优先级when语句太多的话,将使无优先级的when语句被“挂起”,即不被执行。如果一个优先级when语句在大部分时间里都为真,它将独占处理器时间。
相关推荐