tinyOS 2.x 的 App/tutorial/BlinkToRadio文件夹下面有demo:节点通信
下面分析一下:
BlinkToRadioAppC.nc
#include " BlinkToRadio.h "
configuration BlinkToRadioAppC {
}
implementation {
//
//基本配线,连线MainC.Boot, LedsC.Leds, Timer0.Timer
components MainC;
components LedsC;
components BlinkToRadioC as App;
components new TimerMilliC() as Timer0;
App.Boot -> MainC;
App.Leds -> LedsC;
App.Timer0 -> Timer0;
//
//通信模块的配线
components new AMSenderC(AM_BLINKTORADIOMSG);
components new AMReceiverC(AM_BLINKTORADIOMSG);
components ActiveMessageC;
App.AMSend -> AMSenderC.AMSend;
App.Receive -> AMReceiverC.Receive;
App.SplitControl -> ActiveMessageC.SplitControl;
}
注意,这个是简化版,真正的源代码多了一些接口,但都是没有必要的,we just need:
两个components: AMSenderC, AMReceiverC
三个interface:
AMSenderC.AMSend //发送信息全靠它了
AMReceiverC.Receive // 接收信息全靠它了
ActiveMessageC.SplitControl //这个用来开启节点的通信模块
BlinkToRadioC.nc
#include " BlinkToRadio.h "
module BlinkToRadioC {
//基本的接口
uses interface Boot;
uses interface Leds;
uses interface Timer<TMilli> as Timer0;
//通信接口
uses interface AMSend;
uses interface Receive;
uses interface SplitControl;
}
implementation {
uint16_t counter; //这个count用来控制被Leds.Set()作为参数传入,控制节点的LED灯
message_t pkt; //一个buffer,这个message_t变量用来存储发送或者接受的消息
bool busy = FALSE;// 表示节点当前的Radio是否繁忙,在AMSend.Send()时将其置为TRUE,
// 在AMSend.sendDone()时将其置为FALSE
event void Boot.booted() {
call SplitControl.start(); //先启动Radio,这个是Split-phase分阶段接口,
//在随后的SplitControl.startDone()中我们再处理
}
event void SplitControl.startDone(error_t err) {
//如果Radio成功打开,我们就设置定时器的周期否则继续尝试开启
if (err == SUCCESS) {
call Timer0.startPeriodic(TIMER_PERIOD_MILLI);
}
else {
call SplitControl.start();
}
}
event void SplitControl.stopDone(error_t err) {
//stopDone()我们不需要管,因为不需要关闭Radio
}
counter++; //让counter++,这样发送出去的counter有了变化,不同的LED灯都可以闪烁了!
/*如果信道不被暂用,那么...
获得你要操作的message_t也就是pkt内部那块payload(负载)的地址,
这样我就可以让message加上我自己的数据了
*/
/*一切准备就绪以后,我们使用AMSend提供的command:send将该message发送出去,注意它的参数传递:
第一个参数表示一个地址,这里的意思是广播,其中AM_BROADCAST_ADDR是预先定义的:
在tinyos-2.x/tos/types.h/AM.h
第二个参数表示你要发送的消息的地址,也就是带发送消息buffer的地址
第三个参数指明你所要携带的数据的大小,这个BlinkToRadioMsg在头文件中有定义,随后将给出
*/
/*如果发送完成,我就将Radio的状态切换为空闲,
这里之所以使用&pkt == msg表示当我发送完成后那么msg也就是
我要负载的那块buffer的地址了
*/
我们先检测一下合法性:简单地判断一下负载长度是否和我之前装载在message上的数据长度吻合
*/
//只要取下payload,并且将其转换为BlinkToRadioMsg的地址,那么就可以操作我们装载的信息了!
这段代码同样被我删剪了一些,源代码中使用自定义函数 void SetLeds(uint16_t val);来操作LED灯,其实完全可以由Leds.Set()来替代.
BlinkToRadio.h
#define BLINKTORADIO_H
enum {
AM_BLINKTORADIOMSG = 6, //消息的type
TIMER_PERIOD_MILLI = 250 //计时器的周期
};
typedef nx_struct BlinkToRadioMsg {
nx_uint16_t nodeid; //节点的TOS_NODE_ID
nx_uint16_t counter; //你懂的!
} BlinkToRadioMsg; //消息的负载类型
#endif
Makefile
include $(MAKERULES)
这样,一个典型的mote与mote通信的应用程序就写好了, 注意这里我做了一些简化,和原来的有点不一样,但是这更容易理解。