有了blink的基础和对blink修改的经验,现在再看sense和sensetask已经很简单了。
需要注意的地方:
按照我们上一篇的思路: SenseM提供StdControl接口,使用Timer、ADC、StdControl、Leds接口.使用的ADC和StdControl是两个新的接口, ADC 接口——用于从模拟-数字转换器上存取数据;StdControl接口——用于初始化ADC 组件。
nesC程序中可以使用同一个接口的多个实例,比如本例中有:
interface StdControl as ADCControl
而ADCControl是StdControl的实例,如果不提供实例名,则实例名与接口名相同。所以interface ADC相当于interface ADC as ADC.
SenseM.ADControl -> Sensor等价于 SenseM.ADControl -> Sensor.StdControl这是因为Sensor没有ADControl接口,但是有同类型的StdControl接口,nesC编译器能够判断出来这种简写的意思,当然,如果Sensor有两个StdControl类型的接口,就会报错。
Sense.nc不提供任何接口,使用Main、SenseM、LedsC、TimerC、Photo组件, Main.StdControl接口连接到SenseM.StdControl和TimerC.StdControl ;SenseM.ADC接口连接到Photo.ADC;SenseM.ADCControl连接到Photo.StdControl。
注意到这个display函数. 在程序的注解当中写着: display is module static function. 也就是说,他是在module当中出现的函数。注意我们这里直接叫它为“函数”,因为官方文档的英文是function。
它的申明方式:result_t display(uint16_t value)
可以看到它的数据类型是result_t, display是函数的名字,他可以有参数,参数的类型是uint16_t.
观察函数内部的结构可以发现,这种内部定义的函数是有返回值的。这里是return SUCCESS
函数的调用方式是,在需要使用,直接调用它的名字。 比如本例中:display(7-((data>>7) &0x7));
在ADC 接口中的event申明中,使用了关键字async,
async event result_t ADC.dataReady(uint16_t data)
它表示所声明的命令和事件为异步代码。异步代码是可以对硬件中断予以及时响应的代码。
参数化接口:允许一个组件提供一个接口的多个实例,它们以一个编译时刻或运行时刻的参数来索引(其实相当于定义一个数组)。参数化接口允许组件通过运行时或编译时参数值使用多个该接口的实例:
provides interface Timer[uint8_t id];
每个Timer可以有256实例,每个实例对应一个8位数字,可直接以Timer[1],Timer[2],…来使用这256个接口. nesC为了避免使用不慎导致两个地方用到了相同的一个实例,引入了unique(“Timer”),即nesC编译器保证所有由字符串“Timer”标识的一组实例的索引号互不相同,以避免冲突.unique、uniqueCount函可以产生一个唯一的8位数字与参数关联。unique("Timer")是产生一个唯一的数字与Timer串关联;unique("Timer")与unique("MyTimer")可能产生相同的数 uniqueCount返回与参数关联的数的个数。
返回两个函数返回值的“与”值使用如下语句: # return rcombine(call ADCControl.init(), call Leds.init());
sensetask主要是在sense的基础上进行了简单的修改,加入了task的使用。
关于tinyos当中任务的调动方式前面已经有所介绍,这里再啰嗦一下:
tinyos具有两级调度机制:task和hardware event handler。
Task一般被用于编写后台处理程序。
Task的声明:task void taskname () {…}
Task的调用:post taskname();
可以在command中提交任务;可以在event中提交任务;还可以在Task中提交任务。post后的任务被放到一个内部FIFO队列。要注意的是task返回类型必须为void且不带参数。当某个任务执行时,它会一直运行直至结束,然后下一个任务开始执行。因此,任务不应该被挂起或阻塞太长时间。虽然任务之间不能够相互抢占,但任务可能被硬件事件句柄所抢占。如果要运行一系列较长的操作,应该为每个操作分配一个任务,而不是使用一个过大的任务。
关键字async 声明了可被硬件事件句柄执行的命令或事件。这意味着它们可在任何时候执行(可能抢占其他代码的执行),因此async 命令和事件操作一般是少量工作,要快速完成,不可以太长。除此之外,还要考虑被异步命令或事件访问的共享数据存在数据竞争使用的可能性。与硬件事件句柄不同,任务用来执行更长时间的处理操作,如背景数据处理等,同时,任务可以被硬件事件句柄所抢占。
Atomic代码中atomic 的含义是其后花括号内的代码段在执行过程中不可以被抢占。在本例中,对共享缓冲区rdata 的访问是要受到保护的。atomic会推迟中断处理,从而使得系统的反应看起来不迅速。为了使这种影响降低到最小程度,nesC 中的atomic语句应该尽可能地避免调用命令或触发事件,因为外部命令或事件的执行时间还要依赖于与之绑定的其他组件。
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。