| 
 | 
 
Active Message Interfaces 
 
由于会出现多个服务利用同一个radio通信的情况,TinyOS提供了AM层来多元访问radio。 
AM type代表AM的类型,与以太网的帧类型,IP协议区,UDP协议区相类似。 
AM address接收节点的地址,目的区域 
 
AMPacket:对AM数据包的基本设置 
位于/opt/tinyos-2.1.1/tos/interfaces/AMPacket.nc 
#include <message.h> 
#include <AM.h> 
 
interface AMPacket { 
 
  //返回AM栈中节点的am地址 
  command am_addr_t address(); 
  //返回AM数据包的目的地址的AM地址 
  command am_addr_t destination(message_t* amsg); 
  //返回AM数据包中的原地址的AM地址 
  command am_addr_t source(message_t* amsg); 
  //设置AM数据包的目的地址的AM地址 
  command void setDestination(message_t* amsg, am_addr_t addr); 
  //设置AM数据包中的原地址的AM地址 
  command void setSource(message_t* amsg, am_addr_t addr); 
  //返回该信息是否为给本节点的,简单判断destination和address是否一致,广播可能出错 
  command bool isForMe(message_t* amsg); 
  //返回AM数据包的AM类型,就是说包的类型 
  command am_id_t type(message_t* amsg); 
  //设置包的类型 
  command void setType(message_t* amsg, am_id_t t); 
  //获得AM数据包的AM组 
  command am_group_t group(message_t* amsg); 
  //设置AM数据包的AM组 
  command void setGroup(message_t* amsg, am_group_t grp); 
  //返回本节点的AM组 
  command am_group_t localGroup(); 
} 
 
AMSend:为基本的AM数据包提供发送接口 
 
#include <TinyError.h> 
#include <message.h> 
#include <AM.h> 
 
interface AMSend { 
 
  //发送负载长度为len的数据,addr为发送地址 
  command error_t send(am_addr_t addr, message_t* msg, uint8_t len); 
  //取消发送数据 
  command error_t cancel(message_t* msg); 
  //数据发送完成,成功返回SUCCESS,失败返回FAIL,被取消返回ECANCEL 
  event void sendDone(message_t* msg, error_t error); 
  //返回通信层提供的最大负载长度 
  command uint8_t maxPayloadLength(); 
  //获取负载 
  command void* getPayload(message_t* msg, uint8_t len); 
} 
 
通信的组件:此组件位于/tos/system的目录下 
 
AMReceiverC:提供Receive,Packet和AMPacket的接口 
 
 
#include "AM.h" 
 
generic configuration AMReceiverC(am_id_t amId) { 
  provides { 
    interface Receive; 
    interface Packet; 
    interface AMPacket; 
  } 
} 
 
implementation { 
  components ActiveMessageC; 
 
  Receive = ActiveMessageC.Receive[amId]; 
  Packet = ActiveMessageC; 
  AMPacket = ActiveMessageC; 
} 
generic的含义:普通的,可以在其他的程序中调用 
 
AMSenderC:提供AMSend,Packet和AMPacket和ACK的接口 
#include "AM.h" 
 
generic configuration AMSenderC(am_id_t AMId) { 
  provides { 
    interface AMSend; 
    interface Packet; 
    interface AMPacket; 
    interface PacketAcknowledgements as Acks; 
  } 
} 
 
implementation { 
 
#if defined(LOW_POWER_LISTENING) 
  components new LplAMSenderC(AMId) as SenderC; 
#else 
  components new DirectAMSenderC(AMId) as SenderC; 
#endif 
 
  AMSend = SenderC; 
  Packet = SenderC; 
  AMPacket = SenderC; 
  Acks = SenderC; 
} 
 
AMSnooperC:提供Receive,Packet和AMPacket的接口,进行嗅探的组件功能于AMRecieverC相同,用于接收数据 
#include "AM.h" 
 
generic configuration AMSnooperC(am_id_t AMId) { 
  provides { 
    interface Receive; 
    interface Packet; 
    interface AMPacket; 
  } 
} 
 
implementation { 
  components ActiveMessageC; 
 
  Receive = ActiveMessageC.Snoop[AMId]; 
  Packet = ActiveMessageC; 
  AMPacket = ActiveMessageC; 
} 
 
AMSnoopingReceiverC:提供Receive,Packet和AMPacket的接口,多了个ActiveMessageC.Receive[AMId] 
 
#include "AM.h" 
 
generic configuration AMSnoopingReceiverC(am_id_t AMId) { 
  provides { 
    interface Receive; 
    interface Packet; 
    interface AMPacket; 
  } 
} 
 
implementation { 
  components ActiveMessageC; 
 
  Receive = ActiveMessageC.Snoop[AMId]; 
  Receive = ActiveMessageC.Receive[AMId]; 
  Packet = ActiveMessageC; 
  AMPacket = ActiveMessageC; 
} 
 
ActiveMessageAddressC:本module提供了get和set节点AM地址的commond。本module不是为一般用户提供的,容易破坏网络栈,在了解其操作的情况下才可使用。 
 
module ActiveMessageAddressC @safe() { 
  provides { 
    interface ActiveMessageAddress; 
    async command am_addr_t amAddress(); 
    async command void setAmAddress(am_addr_t a); 
  } 
} 
implementation { 
 
  
  am_addr_t addr = TOS_AM_ADDRESS; 
 
  
  am_group_t group = TOS_AM_GROUP; 
  
  async command am_addr_t ActiveMessageAddress.amAddress() { 
    return call amAddress(); 
  } 
  
  async command void ActiveMessageAddress.setAddress(am_group_t myGroup, am_addr_t myAddr) { 
    atomic { 
      addr = myAddr; 
      group = myGroup; 
    } 
    signal ActiveMessageAddress.changed(); 
  } 
 
  async command am_group_t ActiveMessageAddress.amGroup() { 
    am_group_t myGroup; 
    atomic myGroup = group; 
    return myGroup; 
  } 
  
  async command am_addr_t amAddress() { 
    am_addr_t myAddr; 
    atomic myAddr = addr; 
    return myAddr; 
  } 
 
  async command void setAmAddress(am_addr_t a) { 
    atomic addr = a; 
    signal ActiveMessageAddress.changed(); 
  } 
  
  default async event void ActiveMessageAddress.changed() { 
  } 
  
} 
 
 
 
 
 |   
 
 
 
 |