实验时间: 2012-7-5
实验内容:上位机通过串口将数据发送到节点,节点将接收到的数据反馈给上位机
实验环境:基于Linux下的TinyOS
1、上位机->基站节点
上位机向串口发送数据,基站通过串口接收数据,并将该数据对应地转化成点亮LED灯(1~7)。
定义新的组件,命名为PC2NodeC。这里使用SerialActiveMessageC组件,该组件提供了的接口Receive接口可实现串口数据的接收。
发送数据的定义:
首先需要明确在TinyOS中发送数据的格式如下(>7字节):
目标节点地址 | 链路层源地址 | 消息长度 | 网络组号 | AM类型 | 载荷区(有效数据) | |||||
2字节 | 2字节 | 1字节 | 1字节 | 1字节 | 最大28字节 | |||||
| | | | | | | | | …… | |
实现思路:
启动SplitControl(.start)->启动完成->发送数据->进入相应函数
应该了解:在基于TinyOS编程中,事件中的参数是从底层中传过来的,可作为实参处理。
PC2NodeC.nc文件:
module PC2NodeC
{
uses interface SplitControl as SerialControl;
uses interface AMPacket as SerialAMPacket;
uses interface Packet as UartPacket;
uses interface Receive as UartReceive[am_id_t id];
uses interface Leds;
uses interface Boot;
}
implementation
{
typedef nx_struct RealMsg
{
nx_uint8_t LedCount;
}RealMsg;
uint8_t uartIn,uartOut;
bool uartBusy,uartFull;
event void Boot.booted()
{
uint8_t i;
call SerialControl.start();//启动
}
event void SerialControl.startDone(error_t error)
{}
event void SerialControl.stopDone(error_t error){}
//接收到从PC发过来的数据
event message_t *UartReceive.receive[am_id_t id](message_t *msg,void *payload,uint8_t len)
{
If(len==sizeof(RealMsg))
{
RealMsg *btrpkt=(RealMsg *)payload;
Call Leds.set(btrpkt->LedCount);
}
Return msg;
}
PC2NodeAppC.nc文件:
configuration PC2NodeAppC
{
}
implementation
{
//components
components PC2NodeC,MainC,LedsC;
components SerialActiveMessageC as SeriAcMsg;
//Links
PC2NodeC -> SeriAcMsg.AMPacket;
// PC2NodeC -> SeriAcMsg.AMSend;
PC2NodeC -> SeriAcMsg.Receive;
PC2NodeC -> MainC.Boot;
PC2NodeC.SerialControl -> SeriAcMsg;
PC2NodeC -> LedsC.Leds;
}
Makefile文件:
COMPONENT=PC2NodeAppC
//CFLAGS += -DCC2420_NO_ACKNOWLEDGEMENTS
//CFLAGS += -DCC2420_NO_ADDRESS_RECOGNITION
//CFLAGS += -DTASKLET_IS_TASK
include $(MAKERULES)
在上位机(linux终端)输入:
export MOTECOM=serial@/dev/ttyUSB0:115200
java net.tinyos.tools.Send 00 ff ff 00 00 02 00 89 XX
实验现象:
从PC输入数据到串口,头两次的数据在LED灯反映是正确,三次的数据在LED上反映错误,三次之后节点出现“死机”现象,即不管上层输入什么数据,LED都不再更新显示。
按下复位键后,在输入数据,现象同上。
通过测试,发现原因:没有返回msg,即在事件响应完之后没有调用语句:return msg
添加之后,上述异常消除。