TinyOS学习笔记(4)
CntToLedsAndRfm configuration
CntToLedsAndRfm.nc
----------------------------------------------------------
|configuration CntToLedsAndRfm {
|}
|implementation {
| components Main, Counter, IntToLeds, IntToRfm, TimerC;
|
| Main.StdControl -> Counter.StdControl;
| Main.StdControl -> IntToLeds.StdControl;
| Main.StdControl -> IntToRfm.StdControl;
| Main.StdControl -> TimerC.StdControl;
| Counter.Timer -> TimerC.Timer[unique("Timer")];
| IntToLeds <- Counter.IntOutput;
| Counter.IntOutput -> IntToRfm;
|}
----------------------------------------------------------
◆使用模块Main、Counter、IntToLeds、IntToRfm和TimerC
◆在Main中初始化Counter、IntToLeds、IntToRfm和TimerC
◆都是标准库
◆Counter处理Timer.fire()事件
◆IntOutput接口
◇output() Command:有一个16位的参数
◇outputComplete() Event:返回一个result_t
◆IntToLeds:在LED上显示值的低三位
◆IntToRrm:通过Radio广播
◆Counter使用IntToLeds和IntToRfm的IntOutput接口
◆箭头总是由使用者指向提供者
发送消息
◆TinyOS中的radio通信采用Active Message(AM)模型,网络中的每个包都有一个handler ID,接收结点 会触发这个ID对应的事件,可以认为这个ID是“端口号”,不同的结点可以把不同的事件关联到相同的handler ID。
◆在消息传递层,成功的通信涉及5个方面
◇标明发送数据
◇标明接收结点
◇回收与发送数据相关联的内存
◇缓存接收数据
◇处理消息
IntToRfm configuration
IntToRfm.nc
----------------------------------------------
|configuration IntToRfm
|{
| provides interface IntOutput;
| provides interface StdControl;
|}
|implementation
|{
| components IntToRfmM, GenericComm as Comm;
|
| IntOutput = IntToRfmM;
| StdControl = IntToRfmM;
|
| IntToRfmM.Send -> Comm.SendMsg[AM_INTMSG];
| IntToRfmM.StdControl -> Comm;
|}
----------------------------------------------
◆IntToRfm configuration提供了两个接口IntOputput和StdControl
◆提供了接口的configuration也成为了组件,可以被其它configuartion使用
◆组件别名
◇使用了GenericComm组件
◇取别名(local name)Comm
◇为了能方便地使用其它通信组件替换GenericComm而不用修改每一处作用该组件的代码
◆=(equal sign)
◇IntOutput = IntToRfmM
◇StdControl = IntToRfmM
◇模块中左面接口的实现等价于右边模块中接口的实现
◆AM_INTMSG是定义在tos/lib/Counters/IntMsg.h中的全局常量
IntToRfm module
IntToRfmM.nc
----------------------------------------------------------------
|bool pending;
|struct TOS_Msg data;
|
|/* ... */
|
|command result_t IntOutput.output(uint16_t value) {
| IntMsg *message = (IntMsg *)data.data;
|
| if (!pending) {
| pending = TRUE;
|
| message->val = value;
| atomic {
| message->src = TOS_LOCAL_ADDRESS;
| }
|
| if (call Send.send(TOS_BCAST_ADDR, sizeof(IntMsg), &data))
| return SUCCESS;
|
| pending = FALSE;
| }
| return FAIL;
|}
----------------------------------------------------------------
◆IntMsg结构(tos/lib/Counters/IntMsg.h)
◇Field: val
◇Field: src
◆TOS_LOCAL_ADDRESS
◇全局常量
◇代表local source address
◆TOS_BCAST_ADDR
◇全局常量
◇代表radio广播地址
◆TOS_Msg(tos/system/AM.h)
◇send函数所使用的消息结构
◇IntMsg是对TOS_Msg的封装
◆调用Send.send()发送数据
◇数据分段
◇数据传完触发SendMsg.sendDone()事件
◇发送成功才接收下一个分段消息队列
◇发送不成功就不接受传输消息
◆TinyOS Active Message缓存管理
◇允许并发操作
◇遵守严格的可选所有者协议,避免太大内存管理开销
◇message layer接受send()后,管理缓存,传输完成前不允许请求者再修改缓存
◆pending flag
◇跟踪缓存状态
◇前面的消息没发完,则放弃output(),返回FAIL
◇缓存可用,则发送消息
◆GenericComm网络栈(tos/system/GenericComm.nc)
◇TinyOS generic网络栈的实现
◇使用低级接口实现通信
◇AMStandard实现Active Message的接收与发送
◇UARTNoCRCPacket实现mote的串口通信
◇RadioCRCPacket实现radio通信
◆RfmToLeds
◇ReceiveMsg接口(tos/interfaces/ReceiveMsg.nc)只定义了一个事件: receive()
◇接收消息的内存管理是动态继承的
◇Active Message层解码handler type并进行分派
◇缓存被传递给程序(通过ReceiveMsg.receive()事件),但关键的是,程序必须在处理完后返回指向缓存的指针
◇若是要保存消息内容以后处理,那么应复制消息内容到新的缓存,或向网络栈返回一个新缓存的指针
◆底层细节
◇消息头中包含group ID,使得多个mote组可以共享同一个radio channel
◇group ID是一个8位数
◇默认group ID是0x7D
◇使用DEFAULT_LOCAL_GROUP改变默认group ID
●DEFAULT_LOCAL_GROUP = 0x42 # for example...
◇使用MakeLocal文件改变所有程序胡group ID
◇消息头带有16位的目的结点地址
◇组中的每个通信结点在编译时都分配有惟一一个16位地址
◇TOS_BCAST_ADDR (0xfff)广播通用地址
◇TOS_UART_ADDR (0x007e)串口通用地址
CntToLedsAndRfm.nc
----------------------------------------------------------
|configuration CntToLedsAndRfm {
|}
|implementation {
| components Main, Counter, IntToLeds, IntToRfm, TimerC;
|
| Main.StdControl -> Counter.StdControl;
| Main.StdControl -> IntToLeds.StdControl;
| Main.StdControl -> IntToRfm.StdControl;
| Main.StdControl -> TimerC.StdControl;
| Counter.Timer -> TimerC.Timer[unique("Timer")];
| IntToLeds <- Counter.IntOutput;
| Counter.IntOutput -> IntToRfm;
|}
----------------------------------------------------------
◆使用模块Main、Counter、IntToLeds、IntToRfm和TimerC
◆在Main中初始化Counter、IntToLeds、IntToRfm和TimerC
◆都是标准库
◆Counter处理Timer.fire()事件
◆IntOutput接口
◇output() Command:有一个16位的参数
◇outputComplete() Event:返回一个result_t
◆IntToLeds:在LED上显示值的低三位
◆IntToRrm:通过Radio广播
◆Counter使用IntToLeds和IntToRfm的IntOutput接口
◆箭头总是由使用者指向提供者
发送消息
◆TinyOS中的radio通信采用Active Message(AM)模型,网络中的每个包都有一个handler ID,接收结点 会触发这个ID对应的事件,可以认为这个ID是“端口号”,不同的结点可以把不同的事件关联到相同的handler ID。
◆在消息传递层,成功的通信涉及5个方面
◇标明发送数据
◇标明接收结点
◇回收与发送数据相关联的内存
◇缓存接收数据
◇处理消息
IntToRfm configuration
IntToRfm.nc
----------------------------------------------
|configuration IntToRfm
|{
| provides interface IntOutput;
| provides interface StdControl;
|}
|implementation
|{
| components IntToRfmM, GenericComm as Comm;
|
| IntOutput = IntToRfmM;
| StdControl = IntToRfmM;
|
| IntToRfmM.Send -> Comm.SendMsg[AM_INTMSG];
| IntToRfmM.StdControl -> Comm;
|}
----------------------------------------------
◆IntToRfm configuration提供了两个接口IntOputput和StdControl
◆提供了接口的configuration也成为了组件,可以被其它configuartion使用
◆组件别名
◇使用了GenericComm组件
◇取别名(local name)Comm
◇为了能方便地使用其它通信组件替换GenericComm而不用修改每一处作用该组件的代码
◆=(equal sign)
◇IntOutput = IntToRfmM
◇StdControl = IntToRfmM
◇模块中左面接口的实现等价于右边模块中接口的实现
◆AM_INTMSG是定义在tos/lib/Counters/IntMsg.h中的全局常量
IntToRfm module
IntToRfmM.nc
----------------------------------------------------------------
|bool pending;
|struct TOS_Msg data;
|
|/* ... */
|
|command result_t IntOutput.output(uint16_t value) {
| IntMsg *message = (IntMsg *)data.data;
|
| if (!pending) {
| pending = TRUE;
|
| message->val = value;
| atomic {
| message->src = TOS_LOCAL_ADDRESS;
| }
|
| if (call Send.send(TOS_BCAST_ADDR, sizeof(IntMsg), &data))
| return SUCCESS;
|
| pending = FALSE;
| }
| return FAIL;
|}
----------------------------------------------------------------
◆IntMsg结构(tos/lib/Counters/IntMsg.h)
◇Field: val
◇Field: src
◆TOS_LOCAL_ADDRESS
◇全局常量
◇代表local source address
◆TOS_BCAST_ADDR
◇全局常量
◇代表radio广播地址
◆TOS_Msg(tos/system/AM.h)
◇send函数所使用的消息结构
◇IntMsg是对TOS_Msg的封装
◆调用Send.send()发送数据
◇数据分段
◇数据传完触发SendMsg.sendDone()事件
◇发送成功才接收下一个分段消息队列
◇发送不成功就不接受传输消息
◆TinyOS Active Message缓存管理
◇允许并发操作
◇遵守严格的可选所有者协议,避免太大内存管理开销
◇message layer接受send()后,管理缓存,传输完成前不允许请求者再修改缓存
◆pending flag
◇跟踪缓存状态
◇前面的消息没发完,则放弃output(),返回FAIL
◇缓存可用,则发送消息
◆GenericComm网络栈(tos/system/GenericComm.nc)
◇TinyOS generic网络栈的实现
◇使用低级接口实现通信
◇AMStandard实现Active Message的接收与发送
◇UARTNoCRCPacket实现mote的串口通信
◇RadioCRCPacket实现radio通信
◆RfmToLeds
◇ReceiveMsg接口(tos/interfaces/ReceiveMsg.nc)只定义了一个事件: receive()
◇接收消息的内存管理是动态继承的
◇Active Message层解码handler type并进行分派
◇缓存被传递给程序(通过ReceiveMsg.receive()事件),但关键的是,程序必须在处理完后返回指向缓存的指针
◇若是要保存消息内容以后处理,那么应复制消息内容到新的缓存,或向网络栈返回一个新缓存的指针
◆底层细节
◇消息头中包含group ID,使得多个mote组可以共享同一个radio channel
◇group ID是一个8位数
◇默认group ID是0x7D
◇使用DEFAULT_LOCAL_GROUP改变默认group ID
●DEFAULT_LOCAL_GROUP = 0x42 # for example...
◇使用MakeLocal文件改变所有程序胡group ID
◇消息头带有16位的目的结点地址
◇组中的每个通信结点在编译时都分配有惟一一个16位地址
◇TOS_BCAST_ADDR (0xfff)广播通用地址
◇TOS_UART_ADDR (0x007e)串口通用地址
浙公网安备 33010602011771号