TinyOS bug程序的执行01(T-Check中的bug)
来源:互联网 发布:理财大视野数据靠谱吗 编辑:程序博客网 时间:2024/05/17 08:16
bug1:串行栈bug + bug2
背景知识介绍
- 内容涉及到BaseStation节点与PC端数据通信的基本实现;
注意:TinyOS2.X中数据包的格式是与平台无关的,因此PC端的程序可以与任意节点通信,而TinyOS1.X中的数据包与平台相关。
串行栈的相关知识
- TinyOS2.X串口协议栈(即在节点上)的4个功能组件从下至上的分别为:
1、原始UART:功能为:为串口通信提供字节级数据的收发(例如:UartC组件提供的SerialByteCom接口) + 刷新缓存的功能(UartC组件提供的SerialFlush接口)
2、编码器/装帧器:将原始字节数据转换为串口协议数据包格式.(该层的HdlcTranslaterC组件使用了SerialByteComm接口和提供了SerialFrameComm接口)
3、传输协议:负责接收或发送协议数据包(Serial组件提供了面向字节的接口用于收发数据包),提供如下两个接口;
②、发送(SendBytePacket接口):从分派器发送到Uart
①、接收(ReceiveBytePacket):从Uart接收到的数据传到分派器(会有一个确认操作,因此会有延迟)
4、分派器:负责处理协议组件接收的数据包(SerialDispatcherC组件)
①、使用了SendBytePacket和ReceiveBytePacket,提供Send和Receive接口
②、接收数据的过程:SerialDispatcherC收到SerialC发送的一个字节数据后,然后调用offset()确定偏移量,再将数据填充到message_t结构的缓存中。 - SerialActiveMessageC组件的简单介绍
1、该组件是串行通信栈中顶层的配置组件 - 在串口栈中,数据包在连接过程中有如下格式,各协议字段分别和特定的组件对应
1、帧字节(编码器/装帧器) + 协议字节(SerialP) + 序列字节(SerialP) + 数据包格式分派字节(SerialDispatcherC) + 有效负载payload(SerialDispatcher) + CR校验序列(Serial) + 帧字节
2、payload:由组件SerialDispatcher读入的连续数据包。
MIG
- MIG(Message Interface Generator)消息接口产生器:通过该接口自动生成一个java类,用于将平台应用程序中的二进制数据打包成相应的消息数据类,来能耗的解析和显示。
- TestSerial应用程序就是用到了MIG:该程序中,利用MIG来生成对于BlinkToRadio数据包的msg代码
- 生成相应MSG代码历来与MakeFile文件,详情见《TinyOS是用编程》P141。
数据包源
- “数据包源”是传感器节点和PC直接通信的媒介,可用于接收节点上传的数据包,并向节点发送数据包。TinyOS常用的方式是串行代理连接(SerialForwarder)方式。
(应该可以这样理解:串行栈位于节点上,而数据包源位于PC端) - 数据包源的格式例如:serial@COM1:115200表示:串口使用直接连接方式 + 使用串口端口COM1 + 波特率为115200B
- SerialForwarder程序实现从串口中读取数据并在互联网中转发
串口通信测试TestSerial程序
- 程序功能:测试PC和节点之间的正常通信,节点和PC美妙会通过串口互发一个数据包。节点收到数据包在LED灯上打印,而PC收到数据包则打印数据包内容。
- TestSerial源码分析:
http://blog.sina.com.cn/s/blog_5bce66f00100sj3d.html
1、TestSerial.h文件
//定义数据包的有效数据typedef nx_struct test_serial_msg { nx_uint16_t counter; //计数 } test_serial_msg_t;
2、TestSerialC.nc
module TestSerialC { uses { // 串口的开关接口 interface SplitControl as Control; interface Leds; interface Boot; interface Receive; interface AMSend; interface Timer<TMilli> as MilliTimer; interface Packet; }}implementation { message_t packet;//数据包 bool locked = FALSE;//节点是否忙,同busy,发送数据时true,发送成功后置为false uint16_t counter = 0;//数据包计数 event void Boot.booted() { call Control.start(); //打开串口操作;向下找startDone。 } //时间每次启动调用的函数 event void MilliTimer.fired() { counter++; if (locked) { return; } else { //设置数据包的有效负载,rcm指向数据包的有效负载 test_serial_msg_t* rcm = (test_serial_msg_t*)call Packet.getPayload(&packet, sizeof(test_serial_msg_t)); if (rcm == NULL) {return;} //所发的数据超界 if (call Packet.maxPayloadLength() < sizeof(test_serial_msg_t)) { return; } //设置有效负载的数据(即数据包的数据) rcm->counter = counter; //发送该数据包三个参数分别为:目的地址 + 数据包 + 有效负载的长度。寻找sendDone if (call AMSend.send(AM_BROADCAST_ADDR, &packet, sizeof(test_serial_msg_t)) == SUCCESS) { locked = TRUE; } } } //接收数据程序,接收到数据后三位设置led灯,三个参数分别为:数据包 + 有效负载 + 有效负载长度。 event message_t* Receive.receive(message_t* bufPtr, void* payload, uint8_t len) { if (len != sizeof(test_serial_msg_t)) {return bufPtr;} else { test_serial_msg_t* rcm = (test_serial_msg_t*)payload; if (rcm->counter & 0x1) { call Leds.led0On(); } else { call Leds.led0Off(); } if (rcm->counter & 0x2) { call Leds.led1On(); } else { call Leds.led1Off(); } if (rcm->counter & 0x4) { call Leds.led2On(); } else { call Leds.led2Off(); } return bufPtr; } } event void AMSend.sendDone(message_t* bufPtr, error_t error) { if (&packet == bufPtr) { locked = FALSE;//发送成功,节点空闲 } } event void Control.startDone(error_t err) { if (err == SUCCESS) { call MilliTimer.startPeriodic(1000); //开始成功,调用计时器,每隔一秒触发fired } } event void Control.stopDone(error_t err) {} //结束成功}
3、TestSerialAppC.nc
#include "TestSerial.h"configuration TestSerialAppC {}implementation { components TestSerialC as App, LedsC, MainC; components SerialActiveMessageC as AM; components new TimerMilliC(); App.Boot -> MainC.Boot; App.Control -> AM; //参数化接口 App.Receive -> AM.Receive[AM_TEST_SERIAL_MSG]; App.AMSend -> AM.AMSend[AM_TEST_SERIAL_MSG]; App.Leds -> LedsC; App.MilliTimer -> TimerMilliC; App.Packet -> AM;}
4、TestSerial.java实现PC端实现与串口的连接和数据收发通信:
import java.io.IOException;import net.tinyos.message.*;import net.tinyos.packet.*;import net.tinyos.util.*;public class TestSerial implements MessageListener { private MoteIF moteIF; public TestSerial(MoteIF moteIF) { this.moteIF = moteIF; this.moteIF.registerListener(new TestSerialMsg(), this); //为节点添加监听事件 } //发送数据包,由PC发给节点发送数据 public void sendPackets() { int counter = 0; TestSerialMsg payload = new TestSerialMsg(); try { while (true) { System.out.println("Sending packet " + counter); //输出接收的数据包,接收数据包的个数 payload.set_counter(counter); moteIF.send(0, payload);//计算机给节点发送数据 counter++; try {Thread.sleep(1000);} catch (InterruptedException exception) {} } } catch (IOException exception) { System.err.println("Exception thrown when sending packets. Exiting."); System.err.println(exception); } } //接收节点向PC发送的数据,MessageListener的实现 public void messageReceived(int to, Message message) { TestSerialMsg msg = (TestSerialMsg)message; System.out.println("Received packet sequence number " + msg.get_counter()); } private static void usage() { System.err.println("usage: TestSerial [-comm <source>]"); } //调用程序,传入参数为-comm serial@/dev/ttyUSB0:telosb public static void main(String[] args) throws Exception { String source = null; if (args.length == 2) { if (!args[0].equals("-comm")) { usage();//提示信息 System.exit(1); } source = args[1]; //参数serial@/dev/ttyUSB0:telosb } else if (args.length != 0) { usage(); System.exit(1); } PhoenixSource phoenix; //?????? if (source == null) { phoenix = BuildSource.makePhoenix(PrintStreamMessenger.err); } else { phoenix = BuildSource.makePhoenix(source, PrintStreamMessenger.err);//连接串口 } MoteIF mif = new MoteIF(phoenix);//设置节点 TestSerial serial = new TestSerial(mif); serial.sendPackets(); }}
Bug3:DIP bug
涉及的背景知识:TinyOS中的网络协议。
背景知识介绍
TinyOS中两种基本的多跳路由协议:分发协议和汇聚协议。
- 分发(Dissemination)协议实现的功能:将小数据项可靠地传送到网络中每一个节点。
- 分发协议中有一个共享变量,当共享变量发生改变时会通知应用程序,从而实现整个网络最终的一致性(即实现共享变量的网络一致性),网络中每一个共享变量都有一个该数据的副本。
相关的接口和组件
- 分发协议涉及的接口:
//读取网络中的共享数据并且更新interface DisseminationValue<typedef t>{ command const t *get();//获取分发变量的指针; command void set(const t *);//为该变量设置值(例如初始值) event void changed();//当分发(共享)的变量值发生改变时,触发该事件 }//产生(或者说是更新)需要分发的共享数据,interface DisseminationUpdate<typedef t>{command void change(t *newVal);//更新要发粪的值}
0 0
- TinyOS bug程序的执行01(T-Check中的bug)
- TinyOS论文01:T-Check:Bug Finding for Sensor Networks.
- Bug Check
- tinyos的程序执行顺序
- 一种bug的check方式
- 奇妙的BSOD:Bug Check 0xDA
- ESP8266 arduino下载程序不执行的若干bug
- 老婆程序的BUG
- 查找程序的bug
- Bug Check Code Reference
- 蓝屏 BUG Check 109
- 发现Java程序中的Bug
- 程序员如何才能减少自己的程序中的BUG
- U-boot程序在FL2440的SDRAM中的BUG
- 善用php-fpm的慢执行日志slow log分析PHP执行效率和程序BUG
- 善用php-fpm的慢执行日志slow log分析PHP执行效率和程序BUG
- 善用php-fpm的慢执行日志slow log分析PHP执行效率和程序BUG
- 不易觉察的程序BUG
- 监听短信数据库,获取验证码
- 把jar打包成exe
- VIM强大插件列表
- Codeforces 617C:Watering Flowers
- float 浮点数的无效值和无限大和无限小
- TinyOS bug程序的执行01(T-Check中的bug)
- 显著性检测(Salient Detection)
- 1007. 素数对猜想 (20)
- RDD持久化、广播、累加器
- windows程序设计(第五版)笔记-001
- python 二进制,十进制,十六进制
- 配置Ceph为openstack后端
- 浮点数的理解和BigDecimal的使用
- 关于符号位扩展你又知道多少