Sending packet 2
Received packet sequence number 49
当用Ctrl+z停止时,节点不再闪烁,接收不到java程序传来的数据。利用SerialActiveMessage实现了节点与计算信。
TinyOS学习笔记11-节点与计算机利用串口通信2-BaseStation 节点与计算机利用串口通信2-BaseStation
BaseStation的功能是实现一个中转的功能,将收到的节点信息发送给计算机,将收到的计算机的信息广播给其他的节点。
对于基站的节点来说,LED0s闪烁:发送一个数据包到其他节点。LED1闪烁:接收到数据包,发送一个数据包到串口。LED2闪烁:丢失一个数据包(接收的速度大于发送的速度)。 下面对BaseStationP.nc的代码进行分析: //需要用到发送信息的数据包和串口
#include \ #include \
module BaseStationP @safe() { uses {
interface Boot;//启动系统
interface SplitControl as SerialControl; //串口控制 interface SplitControl as RadioControl; //radio控制
//向串口发送数据的设置am_id_t id,指定发送接收的am数据id interface AMSend as UartSend[am_id_t id]; interface Receive as UartReceive[am_id_t id]; interface Packet as UartPacket;
interface AMPacket as UartAMPacket;
//向radio发送数据的设置
interface AMSend as RadioSend[am_id_t id]; interface Receive as RadioReceive[am_id_t id];
interface Receive as RadioSnoop[am_id_t id]; //嗅探 interface Packet as RadioPacket;
interface AMPacket as RadioAMPacket;
//Led灯设置 interface Leds; } }
implementation {
//设置序列的长度
enum {
UART_QUEUE_LEN = 12, RADIO_QUEUE_LEN = 12, };
//串口设置
message_t uartQueueBufs[UART_QUEUE_LEN];//数据Buffer
message_t * ONE_NOK uartQueue[UART_QUEUE_LEN]; //?????? uint8_t uartIn, uartOut; //??????????? bool uartBusy, uartFull;//串口状态
//radio设置
message_t radioQueueBufs[RADIO_QUEUE_LEN];//buffer message_t * ONE_NOK radioQueue[RADIO_QUEUE_LEN]; uint8_t radioIn, radioOut; //???? bool radioBusy, radioFull;//radio状态
//声明
task void uartSendTask();//串口发送 task void radioSendTask();//radio发送
//丢失数据包led2闪烁 void dropBlink() {
call Leds.led2Toggle(); }
//失败,led2闪烁 void failBlink() {
call Leds.led2Toggle(); }
//启动
event void Boot.booted() { uint8_t i;
for (i = 0; i < UART_QUEUE_LEN; i++)
uartQueue[i] = &uartQueueBufs[i]; //将buffer中的每一个赋给指针 uartIn = uartOut = 0; //输入输出都为0 uartBusy = FALSE; //串口不忙 uartFull = TRUE; //数据已满
//同理设置radio
for (i = 0; i < RADIO_QUEUE_LEN; i++) radioQueue[i] = &radioQueueBufs[i];
radioIn = radioOut = 0; radioBusy = FALSE; radioFull = TRUE;
call RadioControl.start(); //启动radio call SerialControl.start();//启动串口
}
event void RadioControl.startDone(error_t error) { if (error == SUCCESS) {
radioFull = FALSE; //启动成功,radio数据不满 } }
event void SerialControl.startDone(error_t error) { if (error == SUCCESS) {
uartFull = FALSE; //启动成功,serial数据不满 } }
event void SerialControl.stopDone(error_t error) {} event void RadioControl.stopDone(error_t error) {}
uint8_t count = 0; //计数
message_t* ONE receive(message_t* ONE msg, void* payload, uint8_t len);
//radio嗅探接收数据
event message_t *RadioSnoop.receive[am_id_t id](message_t *msg, void *payload, uint8_t len) { return receive(msg, payload, len); }
//radio接收数据
event message_t *RadioReceive.receive[am_id_t id](message_t *msg, void *payload, uint8_t len) { return receive(msg, payload, len); }
//接收数据
message_t* receive(message_t *msg, void *payload, uint8_t len) {
message_t *ret = msg; //整个数据
//原子操作,不可被打断 atomic {
if (!uartFull)//串口未满
{
ret = uartQueue[uartIn];//ret指向输入 uartQueue[uartIn] = msg;//msg进入序列
uartIn = (uartIn + 1) % UART_QUEUE_LEN; //uarIn指向下一个
if (uartIn == uartOut) //入==出,串口序列的数据已满 uartFull = TRUE;
if (!uartBusy) //串口不忙,则发送数据 {
post uartSendTask(); //发送操作 uartBusy = TRUE; //串口变忙 } } else
dropBlink();//串口已满,数据丢失 }
return ret; }
uint8_t tmpLen;
//向串口发送收到的数据 task void uartSendTask() { uint8_t len; am_id_t id;
am_addr_t addr, src; message_t* msg; //将所有数据发送完毕
atomic
if (uartIn == uartOut && !uartFull) {
uartBusy = FALSE; return; }
msg = uartQueue[uartOut]; //待发送的数据
//从radio的msg数据包中获取每一个参数
tmpLen = len = call RadioPacket.payloadLength(msg); id = call RadioAMPacket.type(msg);
addr = call RadioAMPacket.destination(msg); src = call RadioAMPacket.source(msg);
call UartPacket.clear(msg);//清空串口数据包
call UartAMPacket.setSource(msg, src);//设置数据
//发送数据给串口,成功led1闪烁,寻找sendDone
if (call UartSend.send[id](addr, uartQueue[uartOut], len) == SUCCESS) call Leds.led1Toggle(); else {
failBlink();//发送失败,继续发送
post uartSendTask(); } }
event void UartSend.sendDone[am_id_t id](message_t* msg, error_t error) { if (error != SUCCESS) failBlink();//发送失败
else
atomic //发送成功
if (msg == uartQueue[uartOut]) //发送的数据是所要发的数据
{
if (++uartOut >= UART_QUEUE_LEN) //输入指向下一个的超过了长度12 uartOut = 0; //从0开始
if (uartFull) //如果满的话,设置为没满 uartFull = FALSE; }
post uartSendTask(); //继续发送其他数据 }
//串口接收数据
event message_t *UartReceive.receive[am_id_t id](message_t *msg, void *payload, uint8_t len) { message_t *ret = msg; bool reflectToken = FALSE;
//串口接收到数据发送给radio atomic
if (!radioFull) {

