TinyOS学习笔记1---入门
当我们uses某接口时,那么该接口下的所有command和event都可以调用。 在一些情况下,组件也可以provides和uses
Command。同样的provides的组件要实现command的函数内容。 配置文件
现在,我们已经知道某些组件提供的接口,但,仅仅通过这还不足以访问这个组件。
如果a,b同时都提供了一个接口c,那么,当组件d访问c接口时访问的到底是a还是b呢?
所以配置文件就产生了,它的目的就是声明你要访问的组件名称,并且将它所提供的接口与你想要使用的接口相连接。
配置文件的构成
配置文件configuration首先声明了其应用程序下的组件,关键字:components.
声明了组件之后,通过->可以将两个组件的接口连接起来。 Main.StdControl -> BlinkM.StdControl;
这段代码就是把组件main和blinkm的stdcontrol连接起来,这样,就建立了两个组件之间的联系。当调用main.stdcontrol的时候就相当于调用了blinkm.stdcontrol。
关键字-> 永远是将一个使用(uses)的接口(左边)于一个提供(provides)的接口(右边)相连接。
也就是说只有左边的组件能够调用右边的组件的接口。反之则不可以。并且该关键是一个多对多的关系,即一个组件可以连接到很多接口,反之一样
配置文件还可以通过=关键字来进行接口之间的连接,=号表示两个接口之间的关系是等同的,类似于c语言中的指针。=号两边可以是uses=pro
也可以是u=u ,p=p.
注:配置文件中也可以使用或提供接口。(后面有例子) 配置文件和顶级配置文件
一个程序中可以有多个配置文件,但一定要有一个顶级配置文件。 在tinyos中组件也是分层次的。最底层的组件贴近硬件部分,是经过一层一层封装才有了上层的组件,封装的过程中就使用了配置文件。而一个应用程序需要一个顶级配置文件,在所有其他的配置文件的更高一层,编译时会首先参照该文件进行编译。
程序组成 程序实例:blink
现在我们要编写一个程序,是传感器上的灯每一秒闪烁一次。 首先,我们要根据实际情况去筛选我们所需要的组件。 控制亮灯的组件:ledc. 控制时间的组件:singletime.
控制程序开始的组件:main.程序开始从这里运行所以要通过这个组件带动blinkm.再通过blinkm中的函数控制ledc和singletime.
控制程序逻辑上下文:blinkm.在该文件中表达逻辑思路。因此该组件需要连接到时间和亮灯的组件接口上。
编写配置文件 Blink.nc
configuration Blink { } implementation { components Main, BlinkM, SingleTimer, LedsC; Main.StdControl -> BlinkM.StdControl; Main.StdControl -> SingleTimer.StdControl; BlinkM.Timer -> SingleTimer.Timer; BlinkM.Leds -> LedsC; }
StdControl 接口
interface StdControl { command result_t init(); command result_t start(); command result_t stop(); }
Result_t是一个数据类型,表示uint8_t 该接口用来初始化和启动TinyOS 组件。
我们需要知道,tinyos中,任何组件使用之前都需要进行初始化,有些组件会提供如stdcontrol的接口比如singletime 我们就可以用它实现该组件的初始化。
编写blinkm.nc
通过我们知道要使用一个组件或者模块必须先要启动它,而main又uses stdcontrol来实现blinkm和singletime的启动,因此我们blinkm一定要提供stdcontrol的接口,并且实现它。同时,blink需要控制ledc和singletime因此它还需要使用他们所提供的接口leds,timer。
Blinkm.nc module BlinkM { provides {
interface StdControl; } uses {
interface Timer; interface Leds; }
Stdcontrol的实现 implementation {
command result_t StdControl.init() { return SUCCESS; }
command result_t StdControl.start() { }
command result_t StdControl.stop() { }
在前面我们说过,没一个组件使用之前都需要初始化,现在我们还剩下led没有进行初始化,观看该接口的函数,我们通过添加call Leds.init();进行此接口的初始化。再让我们看看timer接口。
Timer接口 Timer.nc
interface Timer {
command result_t start(char type, uint32_t interval); command result_t stop(); event result_t fired(); }
Start()命令被用于指定timer 的类型和那些即将过期的时间间隔。我们使用毫秒来计算时间间
隔。有TIMER_REPEAT 和TIMER_ONE_SHOT 两种可用的类型。在指定的时间间隔过后,timer 将会结束,
下一个重复的timer 将会继续执行,直到被stop()命令所终止。 当一个间隔到来时,事件 fired()被触发。 因此我们的设计思路如下:
在blinkm初始化时我们需要对所有组件进行启动,然后开始设置时间间隔,当一个时间间隔过后,事件函数被触发,call Leds.redToggle(); 使红灯亮起。经修改,blinkm.nc如下:
Blinkm.nc implementation {
command result_t StdControl.init() { call Leds.init(); return SUCCESS; }
command result_t StdControl.start() {
return call Timer.start(TIMER_REPEAT, 1000) ; }
command result_t StdControl.stop() { return call Timer.stop(); }
event result_t Timer.fired() {
call Leds.redToggle();
return SUCCESS; } } 关系图
命令是一层一层向下传递 事件是一层一层向上传递
当timer到期时。首先发生硬件中断然后将此时间向上传递到timer.fired()中,我们再call leds.red()
编译
Vi,写字板可以进行.nc的创建编译
通过gywin我们到apps/blink目录,输入make micaz ncc编译起会产生一个main.exe文件,而这就是我们需要灌到板子上的程序。但通过软件将程序下载到传感器时无法识别程序的型号,所以采用在blink目录下输入 make micaz install eprb, ip的方法也可以将程序下载到传感器当中,经过实验第二种方法可以成功实现blink程序。
之所以输入make platform就可以进行编译是因为该目录先有一个makefile的脚本。在以后的实验中,一个新程序的编译脚本将由我们自己来编写。
如果没有该文件那么要进行编译就要输入 ncc -o main.exe -target=mica Blink.nc 小结
我们所操作的仅仅是上层部分。
我们所使用的模块和组件都是经过一层一层封装。 程序真正的入口是在raelmain.nc底下
当然,因为这涉及到底层的调用,我们可以不关心这一点。但我们要知道的是,就像是c++,c#一样,系统组件和将来我们编写自己的组件一样都需要进行
封装。
模块内部声明的变量都是局部私有的变量。
如果需要声明全局函数或者变量要用到_attribute_. 关于blink程序的补充
关于blink的代码只有configuration和module 两个.nc 文件,但是,如果只用这两个文件的是编译不出来main.exe的。这是因为singletime 并不是一个系统组件,他是一个非系统的配置文件。我们来看下他的代码
singletimer.nc
configuration SingleTimer { provides interface Timer; provides interface StdControl; }
implementation { components TimerC;
Timer = TimerC.Timer[unique(\ StdControl = TimerC; }
Singletime.nc Timerc是一个时间集。
Singletime是对timerc的一个封装。从其中抽象出来了一个时间timer。 启示:使用配置文件可以对原有系统组件进行封装。 编译时类似文件需要添加在一个文件夹内一起编译。 Tinyos调度机制
TinyOS中的调度机制比较简单,它仅设置一个任务队列。关键字post将一个任务添加到任务队列中。TinyOS的调度遵循FIFS(先来先服务)规则
当事件发生时发生抢占。 总结
Tinyos事件驱动。程序调度使用任务列表,当事件发生时产生中断处理,
没有事件发生时任务列表按着fifs进行处理,因为我们是在post一个个的任务,同时当事件发生时编写时间处理函数。
Nesc 语言组件之间通过接口和配置文件进行联系。每个模块要声明自己使用和提供的接口,当提供一接口,就要实现其command函数,当使用一个接口就要实现其event函数。调用command函数时使用call关键字,发送event事件时使用signal关键字。
认识到tinyos程序是层次化的。命令由顶层向底层传递,而事件有底层向顶层传递。函数和接口通过一步步的封装成为模块,模块又可以通过配置文件的封装成为新的组件。编译的过程中,自定义的组件都要一起编译。
系统中所有的应用程序都放在 opt/tinyos-1.x/apps中 系统中所有的系统组件都方在 opt/tinyos-1.x/tos/system下 系统中所有的接口都放在 opt/tinyos-1.x/tos/interface 通过命令make platform docs可以在 opt/tinyos-1.x/doc/nesc/生成source tree和组件关系图。
TinyOS学习笔记2---连接
永远箭头左边是use 关于通信的时候 顶级配置文件要使用箭头 configuration RfmToLeds { }
implementation {
components Main, RfmToInt, IntToLeds; Main.StdControl -> IntToLeds.StdControl; Main.StdControl -> RfmToInt.StdControl; RfmToInt.IntOutput -> IntToLeds.IntOutput; }
configuration RfmToInt {
provides interface StdControl;
uses interface IntOutput; 在这里此地使用的是 use 接口 是因为 rfmtoint要调用intoutput接口 顶级配置文件
可以把他方在左边 是他调用别人 同时有些数据结构使用时要加上头文件才可以用
}
implementation {
components RfmToIntM, GenericComm; IntOutput = RfmToIntM; StdControl = RfmToIntM;
RfmToIntM.ReceiveIntMsg -> GenericComm.ReceiveMsg[AM_INTMSG]; RfmToIntM.CommControl -> GenericComm; }
sense程序中
configuration Sense {
// this module does not provide any interface }
implementation {
components Main, SenseM, LedsC, TimerC, Photo; Main.StdControl -> SenseM; Main.StdControl -> TimerC; SenseM.ADC -> Photo; SenseM.ADCControl -> Photo; SenseM.Leds -> LedsC;
SenseM.Timer -> TimerC.Timer[unique(\} 和
configuration Sense {
// this module does not provide any interface }
implementation {
components Main, SenseM, LedsC, TimerC, DemoSensorC as Sensor; Main.StdControl -> Sensor; Main.StdControl -> TimerC; Main.StdControl -> SenseM; SenseM.ADC -> Sensor; SenseM.ADCControl -> Sensor; SenseM.Leds -> LedsC;
SenseM.Timer -> TimerC.Timer[unique(\}
两者相同 一个是使用了main.stdcontrol接口来初始化sensor 但在模块内部没有实现其中的adccontrol接口
另一个是没有使用main进行初始化而是使用了adccontrol接口在模块中初始化 语句如下:
command result_t StdControl.init() {
return rcombine(call ADCControl.init(), call Leds.init()); } /** *
从这里我们可以知道 使用了一个接口但并不一定要在实现中出现其中的函数。
今日完成: 编译blink程序 并且改名之后再次编译都成功 将blink中的red改为green也成功 最后绿灯每秒亮一次
编译了sense程序 得知该程序是在传感器中取得数据,并且将数据
通过led显示出来
得到的硬件依赖于光线或者温度传感器。
看了关于传感器之间的通信,阅读其中的源代码发现use的另类使用方法。
在下载程序到传感器的时候 扳子和传感器的接口一定要连接紧密同时也许要 reset编程主板。
有些程序要使用头文件 发现一些程序在lib以下以前没有注意到过 photo
D:\\学习\\tinyos-1.x\\tos\\sensorboards\\basicsb下面。
TinyOS学习笔记3
弄明白了 cnttoledandrfm和rfmtoled两个程序 知道了组件和组件之间如何进行工作
同时 只有前者的程序时 也可以接收到数据但接收到的数据没有编写事件处理函数 所以不显示。
初次使用模拟器进行模拟节点的之间的数据通信 configuration RfmToLeds { }
implementation {
components Main, RfmToInt, IntToLeds; Main.StdControl -> IntToLeds.StdControl; Main.StdControl -> RfmToInt.StdControl; RfmToInt.IntOutput -> IntToLeds.IntOutput; }
includes IntMsg; configuration RfmToInt {
provides interface StdControl; uses interface IntOutput;
}
implementation {
components RfmToIntM, GenericComm; IntOutput = RfmToIntM; StdControl = RfmToIntM;
RfmToIntM.ReceiveIntMsg -> GenericComm.ReceiveMsg[AM_INTMSG]; RfmToIntM.CommControl -> GenericComm; }
includes IntMsg; module RfmToIntM {
provides interface StdControl; uses {
interface ReceiveMsg as ReceiveIntMsg; interface IntOutput;
interface StdControl as CommControl; } }
implementation {
command result_t StdControl.init() { return call CommControl.init(); }
command result_t StdControl.start() { return call CommControl.start(); }
command result_t StdControl.stop() { return call CommControl.stop(); }
event TOS_MsgPtr ReceiveIntMsg.receive(TOS_MsgPtr m) { IntMsg *message = (IntMsg *)m->data;
call IntOutput.output(message->val); return m; }
event result_t IntOutput.outputComplete(result_t success) { return SUCCESS; } }
进行了 通信结点的试验 结果和预期想符合当两者都同cnttoledandrfm时 都是以广播形式
向外发送数据 只有当另一者为rfmtoled时才进行了接收事件的处理使leds组件工作。
分配ip时 如果找不到设备可以手动添加输入ip
数据显示文档的阅读。
TinyOS学习笔记4
uartcomm组件是什么 发送和接受数据的一个组件 封装于底层 类似于 genericcomm
该程序是通过adc先接受来自传感器上的数据然后通过通信组件将数据发送到本地 然后接受 再读取数据并且把他显示在pc上面。
configuration Oscilloscope { } implementation {
components Main, OscilloscopeM , TimerC , LedsC
, DemoSensorC as Sensor
, UARTComm as Comm; Main.StdControl -> OscilloscopeM; Main.StdControl -> TimerC;
OscilloscopeM.Timer -> TimerC.Timer[unique(\ OscilloscopeM.Leds -> LedsC;
OscilloscopeM.SensorControl -> Sensor; OscilloscopeM.ADC -> Sensor; OscilloscopeM.CommControl -> Comm; OscilloscopeM.ResetCounterMsg Comm.ReceiveMsg[AM_OSCOPERESETMSG];
OscilloscopeM.DataMsg -> Comm.SendMsg[AM_OSCOPEMSG]; }
module OscilloscopeM {
provides interface StdControl; uses {
interface Timer; interface Leds;
interface StdControl as SensorControl; interface ADC;
interface StdControl as CommControl; interface SendMsg as DataMsg;
interface ReceiveMsg as ResetCounterMsg; } }
implementation {
uint8_t packetReadingNumber;
->
uint16_t readingNumber; TOS_Msg msg[2]; uint8_t currentMsg;
command result_t StdControl.init() { call Leds.init(); call
Leds.yellowOff();
call
Leds.redOff();
Leds.greenOff();
//turn on the sensors so that they can be read. call SensorControl.init(); call CommControl.init();
atomic {
currentMsg = 0;
packetReadingNumber = 0; readingNumber = 0; }
dbg(DBG_BOOT, \ return SUCCESS; }
command result_t StdControl.start() { call SensorControl.start();
call Timer.start(TIMER_REPEAT, 125); call CommControl.start(); return SUCCESS; }
call
command result_t StdControl.stop() { call SensorControl.stop(); call Timer.stop(); call CommControl.stop(); return SUCCESS; }
task void dataTask() { struct OscopeMsg *pack; atomic {
pack = (struct OscopeMsg *)msg[currentMsg].data; packetReadingNumber = 0;
pack->lastSampleNumber = readingNumber; }
pack->channel = 1;
pack->sourceMoteID = TOS_LOCAL_ADDRESS;
if (call DataMsg.send(TOS_UART_ADDR, sizeof(struct OscopeMsg), &msg[currentMsg])) { atomic {
currentMsg ^= 0x1; }
call Leds.yellowToggle(); } }
async event result_t ADC.dataReady(uint16_t data) {
struct OscopeMsg *pack; atomic {
pack = (struct OscopeMsg *)msg[currentMsg].data; pack->data[packetReadingNumber++] = data; readingNumber++;
dbg(DBG_USR1, \
if (packetReadingNumber == BUFFER_SIZE) { post dataTask(); } }
if (data > 0x0300) call Leds.redOn(); else
call Leds.redOff(); return SUCCESS; }
event result_t DataMsg.sendDone(TOS_MsgPtr sent, result_t success) {
return SUCCESS; }
event result_t Timer.fired() { return call ADC.getData(); }
event TOS_MsgPtr ResetCounterMsg.receive(TOS_MsgPtr m) { atomic {
readingNumber = 0;
}
return m; } }
该程序每0。135秒激发一次时间事件 然后调用adc.getdata 等数据准备好时放入 一个数据结构中 10次之后 引发
一个新任务 该任务是将数据发送到本地然后通过java的程序在端口处监听来显示到pc上面。
有关于如何进行数据转换的问题: 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; } 接受如下
event TOS_MsgPtr ReceiveIntMsg.receive(TOS_MsgPtr m) { IntMsg *message = (IntMsg *)m->data; call IntOutput.output(message->val); return m; }
可以知道 最外层 发送和接收到的数据类型都是 Tos_Msg 当我们接收时首先要把其中的data转换成IntMsg的指针
然后使用其中的val字段显示出来
当我们要发送的时候 最终发送出去的 也是Tos_Msg 的变量但我们首先要创建一个这样类型的变量,然后将其中的data
字段转换成IntMsg类型 在给其中的val字段和src字段分别 添上 uint16_t 和 addr的值 当我们调用send的时候 第一个参数是
发送的地址 第二是数据类型 不要添 Tos_Msg 而要添你把tos_msg转换以后的变量类型。
使用java程序进行监听端口时 界面显示和文档所说的一样但是无法在屏幕上输出数据
在一个程序中可以定制自己的接口 自己的组件 自己的配置文件只要符合语法
查阅ident 下的代码
未解决问题: astomi{currentmsg^=0x1;} 代码的目的。英文注释说是0和1之间转换 但每明白如何进行的。
2 当两个组件都使用相同接口时 比如顶级配置和下面的配置都声明leds组件那么要初始化几次呢?
3 对本程序进行调试 发现无法接受到发送到本地的数据原因为明 但每1秒多会发送一次数据。
app下很多程序看不懂。。。痛苦。。。都要涉及到底层
TinyOS2.0安装
1. 安装java jdk
在压缩包中有文件jdk-1_5_0_08-windows-i586-p.exe,点击安装,环境变量的配置参考doc 专业设置预测系统用户操作手册.doc 中2.2小节。
2.安装cygwin
打开文件/cygwin-installationfiles/setup.exe,安装cygwin。参考http://fanqiang.chinaunix.net/program/other/2005-04-06/3110.shtml 和 http://blog.sina.com.cn/s/blog_4a7218b501000axj.html 安装。
3.安装avr单片机工具。
压缩包softwares.rar 解压后,将其下文件夹AVR,MSP430,TingOS2.x, TinyOS-specific Tools拷贝到//cygwin/tmp下。
在cygwin中使用cd 命令进入到 /tmp 路径下,使用ls命令可以查看文件。 使用rpm –ivh rpmname(ls 查看到的文件名) 安装avr工具,按如下顺序安装
avr-binutils-2.15tinyos-3.cygwin.i386.rpm avr-gcc-3.4.3-1.cygwin.i386.rpm avr-libc-1.2.3-1.cygwin.i386.rpm avarice-2.4-1.cygwin.i386.rpm avr-insight-6.3-1.cygwin.i386.rpm
4.安装TinyOS工具
在cygwin中输入以下命令 cd /tmp/TinyOS-specificTools
rpm –ivh nesc-1.2.8b-1.cygwin.i386.rpm rpm –ivh tinyos-tools-1.2.4-2.cygwin.i386.rpm
5.安装TinyOS2.0 在cygwin中输入以下命令 cd /tmp/TinyOS2.x
rpm –ivh --ignoreos tinyos-2.0.2-2.cygwin.noarch.rpm
6.配置环境变量
在cygwin中输入以下命令 cd /etc/profile.d ls (列出文件)
cp openssl.sh tinyos.sh (拷贝一个sh格式的文件)
然后到本地磁盘中,相应的目录下找到这个tinyos.sh文件,用记事本打开,拷贝以下内容替换原文件中的全部内容。
# script for profile.d for bash shells,adjusted for each users # installation by substituting /opt for the actual tinyos tree # installation point
export TOSROOT=\export TOSDIR=\
export CLASSPATH=`cygpath -w $TOSROOT/support/sdk/java/tinyos.jar`
export CLASSPATH=\
export MAKERULES=\export PATH=\添加安装图形工具. 7.测试是否安装成功
在cygwin中使用如下命令
tos-check-env 当命令运行到最后一行为:tos-check-env completed without error 则安装成功
8.安装MSP430单片机工具。
只有上述操作成功后安装msp430工具才能成功。 使用命令仍旧为 rpm -ivh –ignoreos rpmname 顺序如下:
msp430tools-base-0.1-20050607.cygwin.i386.rpm msp430tools-python-tools-1.0-1.cygwin.noarch.rpm msp430tools-binutils-2.16-20050607.cygwin.i386.rpm msp430tools-gcc-3.2.3-20050607.cygwin.i386.rpm msp430tools-libc-20050308cvs-20050608.cygwin.i386.rpm
TinyOS2.0学习笔记1
2。0安装时 在安装完tos2.0后需要安装图形那个软件然后再进行tos-check-env才不会出错
再休息tosim.extra似的仿真模拟程序可以运行。 在把程序灌到传感器时可以设定id
灌入程序 blink RadioCountToLeds RadioSenseToLeds sense 在2。0下都已经实现
除了暂时没有尝试读取数据现实到pc上以外原来1。x下的东西都已经实现 以上三个程序分别用于为blink设置3个时钟 分别闪烁红黄绿
维护一个计时器 并且将他以广播的形式发送出去接受并且用leds显示出来
sense读取传感器取得的数据 并且显示
sensetoled 广播发送传感器上的数据 接受并且显示出来。 原来的timer统一由TimerMilliC()代替 启动由原来的stdcontrol 有boot时间来代替
所以 在配置文件中 BlinkC -> MainC.Boot; 然后在模块中处理了boot的事件处理函数
在2。0中 很多组件不再需要初始化。使用了一个接口就可以直接进行调用 三个灯改为0 1 2 starttime之前没init了
原来的adc如今通过read访问传感器 使用time组件如果要加上#include \
interface Timer
TinyOS2.0学习笔记2
添加变量时 不能添加在dbg后面 只有防在前面时才不会报错 原因 未知
当我们在一次timefired时处理时间较长的数据时会对其他事件的发生造成阻塞
所以这时候我门用任务来处理这个问题 这样当其他事件发生时会发生抢占 就不会影响了
阅读2。0文档 0 1 2 已经阅读完毕
TinyOS2.0学习笔记3
makefile 文件
COMPONENT=BlinkToRadioAppC include $(MAKERULES)
2。0使用 message_t来取代tos_msg
其中的数据不能直接进行访问 需要通过接口 packet ampacket类似的接口来进行访问
发送和接受数据使用amsendc amrecievec两个组件 typedef nx_struct message_t {
nx_uint8_t header[sizeof(message_header_t)];
nx_uint8_t data[TOSH_DATA_LENGTH];
nx_uint8_t footer[sizeof(message_header_t)]; nx_uint8_t metadata[sizeof(message_metadata_t)]; } message_t;
关于给节电点灌入一个id $ make telosb install,1 mkdir -p build/telosb
compiling BlinkToRadioAppC to a telosb binary
ncc -o build/telosb/main.exe -Os -O -mdisable-hwmul -Wall -Wshadow -DDEF_TOS_AM_GROUP=0x7d
-Wnesc-all
-target=telosb
-fnesc-cfile=build/telosb/app.c -board= BlinkToRadioAppC.nc -lm
compiled BlinkToRadioAppC to build/telosb/main.exe 9040 bytes in ROM 246 bytes in RAM msp430-objcopy build/telosb/main.ihex
writing TOS image
tos-set-symbols --objcopy msp430-objcopy --objdump msp430-objdump --target ihex build/telosb/main.ihex build/telosb/main.ihex.out-1 TOS_NODE_ID=1 ActiveMessageAddressC$addr=1
found mote on COM17 (using bsl,auto) installing telosb binary using bsl
tos-bsl --telosb -c 16 -r -e -I -p build/telosb/main.ihex.out-1 MSP430 Bootstrap Loader Version: 1.39-telos-8 Mass Erase...
Transmit default password ... Invoking BSL...
--output-target=ihex
build/telosb/main.exe
Transmit default password ...
Current bootstrap loader version: 1.61 (Device ID: f16c) Changing baudrate to 38400 ... Program ...
9072 bytes programmed.
$ java net.tinyos.tools.Listen -comm serial@/dev/ttyS0:micaz
TinyOS2.0学习笔记4
java testserial 可以对串口的程序进行测试应该显示接受和发送数据包
testserial 是通过串口广播发送和通过串口接受数据 当灯亮 说明串口上得到数据
是本机先发送一个包到串口上 串口接到包 灯亮
(如果安装以后灯一直在闪烁说明是传感器发送数据到串口,否则就是pc发送的数据包到串口)
测试 sendcounttoradio 和 basestation
basestation是个被动接受数据 当他从radio接收到了数据就把该数据发送到了串口 串口再接收数据
当串口接收到了数据的时候再把该数据通过radio以广播形式发送出去。(注意其中的目的地址)
sendcounttoradio 是不断通过广播把数据通过radio发送出去并且接受来自radio的数据 并用闪灯表示
实际中 我们要在编程住板做一个类似于basestation的程序将通过am接收到的数据 发送到本机的串口上 然后通过
java来把数据以2进制形式表示出来 显示在pc上面。
可以给recieve制定要接收的包的类型 也可以不指定 指定各种包的类型和发送各种包的类型 可以把数据包分成几个别类
每个类专门制定相关的 发送和接收的函数
作为basestation要接收所有的包的类型 所以不需要指定包的类型 在定义各种包的时候 就需要使用 new新建 amsendc amrecievec
components ActiveMessageC as Radio, SerialActiveMessageC as Serial;
查看 amsendc和amreceivec就是从activemessagec中抽象出来的一个对象都是使用的am其中的发送和接收函数
TinyOS2.0学习笔记5
使用java来把显示在PC上的二进制的数据整理成字定义的数据包的格式
在MAKEFILE文件里添加如下,以BLINKTORADIO为例
BUILD_EXTRA_DEPS=BlinkToRadioMsg.class
BlinkToRadioMsg.class: BlinkToRadioMsg.java javac BlinkToRadioMsg.java BlinkToRadioMsg.java: mig
j
a
v
a
-target=null
-j
a
v
a
-classname=BlinkToRadioMsg BlinkToRadio.h BlinkToRadioMsg -o $@
添加以后在MAKE的时候编译器会创建一个blinktoraidomsg的java程序用他可以将二进制的
数据转换成我们数据包的格式
我们的数据包的是通过 告诉MIG 定义其包的头文件和数据名称BlinkToRadio.h BlinkToRadioMsg
最后java的CLASS名字为BlinkToRadioMsg
实现方法: basestation接收到了数据 并且发送到传口 调用命令 java net.tinyos.tools.MsgReader BlinkToRadioMsg 在串口接收二进制的数据
然后使用java的工具msgreader 把BLINKTORAIDOMSG作为一个参数传
递进去实际上blinktoradiomsg是我们刚刚编译出来的一个java的CLASS 这样MSGREADER只会读取关于
我们定义的数据包的格式
并且 当我们在发送和接受时 定义过包的类型 AM_MESSAGETYPE
该工具会读取头文件中AM_BLINKTORADIOMSG这个类型并且只接收这个类型的数据
因此 我们所定义的AM类型必须改成AM_BLINKTORADIOMSG 原来是 AM_BLINKTORADIO
现在改为AM_BLINKTORADIOMSG
TestSerialMsg.java is a dependency for TestSerial.class, 前者是后者的从属物
BASETATION 应该是可以接收任务类型的AM包 然后把包发送到串口上去并且可以将AM包的类型
也发送过去 让MSGREADER可以读取。。