BlinkToRadioAppC

tinyOS 2.x 的 App/tutorial/BlinkToRadio文件夹下面有demo:节点通信

下面分析一下:

BlinkToRadioAppC.nc

#include <Timer.h>
#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 <Timer.h>
#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

  }

 

  //因为设置了定时器,在每个周期到来时,定时器会发送fired信号,因此我们在每次信号处理函数里面可以处理了! 
  event void Timer0.fired() {

 

    counter++; //让counter++,这样发送出去的counter有了变化,不同的LED灯都可以闪烁了!

    if (!busy) {  

      /*如果信道不被暂用,那么...

        获得你要操作的message_t也就是pkt内部那块payload(负载)的地址,

        这样我就可以让message加上我自己的数据了 

       */ 

      BlinkToRadioMsg* btrpkt =
        (BlinkToRadioMsg*)(call AMSend.getPayload(&pkt, sizeof(BlinkToRadioMsg)));
      if (btrpkt == NULL) { //当然我要检测一下是不是失败了
        return;
      }
      btrpkt->nodeid = TOS_NODE_ID; //将节点的ID与counter值填入message中等待发送
      btrpkt->counter = counter;

      /*一切准备就绪以后,我们使用AMSend提供的command:send将该message发送出去,注意它的参数传递:

        第一个参数表示一个地址,这里的意思是广播,其中AM_BROADCAST_ADDR是预先定义的:

        在tinyos-2.x/tos/types.h/AM.h

        第二个参数表示你要发送的消息的地址,也就是带发送消息buffer的地址 

        第三个参数指明你所要携带的数据的大小,这个BlinkToRadioMsg在头文件中有定义,随后将给出 

      */ 

      if (call AMSend.send(AM_BROADCAST_ADDR,
          &pkt, sizeof(BlinkToRadioMsg)) == SUCCESS) {
        busy = TRUE;   //当然,在发送过程中,我必须设置Radio状态为繁忙
      }
    }
  }
  event void AMSend.sendDone(message_t* msg, error_t err) {
    if (&pkt == msg) {

                       /*如果发送完成,我就将Radio的状态切换为空闲,

                       这里之所以使用&pkt == msg表示当我发送完成后那么msg也就是

                       我要负载的那块buffer的地址了 

                       */ 

      busy = FALSE;
    }
  }
  /* 这个用来接收packet,对于我们接收下来的msg,

     我们先检测一下合法性:简单地判断一下负载长度是否和我之前装载在message上的数据长度吻合 

   */ 

  event message_t* Receive.receive(message_t* msg, void* payload, uint8_t len){
    if (len == sizeof(BlinkToRadioMsg)) {

      //只要取下payload,并且将其转换为BlinkToRadioMsg的地址,那么就可以操作我们装载的信息了!

      BlinkToRadioMsg* btrpkt = (BlinkToRadioMsg*)payload;
      call Leds.set(btrpkt->counter);
    }
    return msg;
  }

 

这段代码同样被我删剪了一些,源代码中使用自定义函数 void SetLeds(uint16_t val);来操作LED灯,其实完全可以由Leds.Set()来替代.


BlinkToRadio.h

#ifndef 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

COMPONENT=BlinkToRadioAppC
include $(MAKERULES)

 

这样,一个典型的mote与mote通信的应用程序就写好了, 注意这里我做了一些简化,和原来的有点不一样,但是这更容易理解。

 

 

 

 

 

 

 

 

 

 

posted on 2012-03-28 20:59  vincent Van Gogh  阅读(1163)  评论(0编辑  收藏  举报

导航