`

『TinyOS』学习笔记 #2

阅读更多

Lesson 3 : Mote-mote radio communication

 

 

Active Message Interfaces

Since it is very common to have multiple services using the same radio to communicate, TinyOS provides the Active Message (AM) layer to multiplex access to the radio. The term "AM type" refers to the field used for multiplexing. AM types are similar in function to the Ethernet frame type field, IP protocol field, and the UDP port in that all of them are used to multiplex access to a communication service. AM packets also includes a destination field, which stores an "AM address" to address packets to particular motes. Additional interfaces, also located in the tos/interfaces directory, were introduced to support the AM services:

 

  • AMPacket - Similar to Packet, provides the basic AM accessors for the message_t abstract data type. This interface provides commands for getting a node's AM address, an AM packet's destination, and an AM packet's type. Commands are also provides for setting an AM packet's destination and type, and checking whether the destination is the local node.
  • AMSend - Similar to Send, provides the basic Active Message sending interface. The key difference between AMSend and Send is that AMSend takes a destination AM address in its send command.

 

The AM address of a node can be set at installation time, using the make install.n or make reinstall.n commands. It can be changed at runtime using the ActiveMessageAddressC component.

 

 

 

Sending a Message over the Radio

 

Reimplementing Blink

BlinkToRadioC.nc

 

 

#include <Timer.h>
 #include "BlinkToRadio.h"
 
 module BlinkToRadioC {
   uses interface Boot;
   uses interface Leds;
   uses interface Timer<TMilli> as Timer0;
 }
 implementation {
   uint16_t counter = 0;
 
   event void Boot.booted() {
     call Timer0.startPeriodic(TIMER_PERIOD_MILLI);
   }
 
   event void Timer0.fired() {
     counter++;
     call Leds.set(counter);
   }
 }

 

 

 

 

BlinkToRadio.h header file

 

#ifndef BLINKTORADIO_H
 #define BLINKTORADIO_H
 
 enum {
   TIMER_PERIOD_MILLI = 250
 };
 
 #endif

 

the use of the ifndef(if not define), define, and endif directives. These directives are used to ensure that the definitions in each header file is not included multiple times because the compiler would complain about multiply-defined objects. By convention, the literal used for these directives is an all-caps version of the filename with any periods converted to underscores.

 

the use of an enum declaration for defining the constant TIMER_PERIOD_MILLI. Using enum for defining constants is preferred over using define because enum does not indiscriminantly replace every occurence of the defined literal, regardless of where it appears in the source. As a result, enums provide better scoping as well.

 

BlinkToRadioAppC.nc (用来连接use interface 和提供了它的实现的组件)to wire the interfaces that the implementation uses to the actual components which provide these interfaces

 

#include <Timer.h>
 #include "BlinkToRadio.h"
 
 configuration BlinkToRadioAppC {
 }
 implementation {
   components MainC;
   components LedsC;
   components BlinkToRadioC as App;
   components new TimerMilliC() as Timer0;
 
   App.Boot -> MainC;
   App.Leds -> LedsC;
   App.Timer0 -> Timer0;
 }

 

 最后建立Makefiel

 

COMPONENT=BlinkToRadioAppC
include $(MAKERULES)

 

The first line tells the TinyOS make system that the top-level application component is BlinkToRadioAppC.

 

The second line loads in the TinyOS build system, which has all of the rules for building and installing on different platforms.

 

 

 

 

Defining a Message Structure

message will send both the node id and the counter value over the radio. Rather than directly writing and reading the payload area of the message_t with this data, we will use a structure to hold them and then use structure assignment to copy the data into the message payload area.

 

用structure来读写payload更便利

Using a structure allows reading and writing the message payload more conveniently when your message has multiple fields or multi-byte fields (like uint16_t or uint32_t) because you can avoid reading and writing bytes from/to the payload using indices and then shifting and adding (e.g. uint16_t x = data[0] << 8 + data[1]).

 

Even for a message with a single field, you should get used to using a structure because if you ever add more fields to your message or move any of the fields around, you will need to manually update all of the payload position indices if you read and write the payload at a byte level. Using structures is straightforward.

 

typedef nx_struct BlinkToRadioMsg {
  nx_uint16_t nodeid;
  nx_uint16_t counter;
} BlinkToRadioMsg;

 

The nx_ prefix is specific to the nesC language and signifies that the struct and uint16_t are external types.

 

External types have the same representation on all platforms. The nesC compiler generates code that transparently reorders access to nx_ data types and eliminates the need to manually address endianness and alignment (extra padding in structs present on some platforms) issues.

 

the nx_ prefix on a type (e.g. nx_uint16_t) indicates the field is to serialized in big endian format. In contrast, the nxle_ prefix signifies that the field is serialized in little endian format.

 

 

 

Sending a Message

 

  1. First, we need to identify the interfaces (and components) that provide access to the radio and allow us to manipulate the message_t type.
  2. Second, we must update the module block in the BlinkToRadioC.nc by adding uses statements for the interfaces we need.
  3. Third, we need to declare new variables and add any initialization and start/stop code that is needed by the interfaces and components.
  4. Fourth, we must add any calls to the component interfaces we need for our application.
  5. Fifth, we need to implement any events specified in the interfaces we plan on using.
  6. Sixth, the implementation block of the application configuration file, BlinkToRadioApp.c, must be updated by adding a components statement for each component we use that provides one of the interfaces we chose earlier.
  7. Finally, we need to wire the interfaces used by the application to the components which provide those interfaces.  

Note using the as keyword to rename an interface. nesC allows interfaces to be renamed in this way for several reasons. First, it often happens that two or more components that are needed in the same module provide the same interface. Second, interfaces are sometimes renamed to something more meaningful.

 

 

components ActiveMessageC;
components new AMSenderC(AM_BLINKTORADIO);

 

ActiveMessageC is a singleton component that is defined once for each type of hardware platform. AMSenderC is a generic, parameterized component. The new keyword indicates that a new instance of AMSenderC will be created. The AM_BLINKTORADIO parameter indicates the AM type of the AMSenderC.  the value of AM_BLINKTORADIO 定义在BlinkToRadio.h header file 中的enum.

 

 

 

Receiving a Message over the Radio

 

 

和上面一样的过程去添加代码。 

 

Note that we can safely manipulate the counter variable outside of an atomic section. The reason is that receive event executes in task context rather than interrupt context (events that have the async keyword can execute in interrupt context). Since the TinyOS execution model allows only one task to execute at a time, if all accesses to a variable occur in task context, then no race conditions will occur for that variable. Since all accesses to counter occur in task context, no critical sections are needed when accessing it.  

 

The AM_BLINKTORADIO parameter indicates the AM type of the AMReceiverC and is chosen to be the same as that used for the AMSenderC used earlier, which ensures that the same AM type is being used for both transmissions and receptions.

 

 

 

 

分享到:
评论

相关推荐

    TinyOS学习笔记

    总的来说,TinyOS的学习涵盖了nesC语言的特性和编程范式,包括组件接口、并发模型、任务调度以及事件处理。理解这些知识点对于编写和调试TinyOS应用程序至关重要。通过深入学习和实践,开发者能够更好地掌握如何利用...

    tinyos 自学笔记

    TinyOS自学笔记主要关注的是nesC语言,这是一种针对传感器网络节点设计的编程语言,特别适用于资源有限的环境。nesC是C语言的一种扩展,其设计原则和执行模型都是为了体现TinyOS操作系统的核心特性。 1. **结构和...

    tinyos tutorial

    ### TinyOS 教程知识点详解 #### 一、硬件简介 **MICA2 Mote (MPR400CB)** - **处理器**: Atmel ATmega128L 微处理器,运行频率为 7.3827MHz。...通过上述知识点的学习,可以更好地理解 TinyOS 的架构和开发流程。

    TinyOS 2.0 Tutorials-new.pdf

    根据给定文件内容,我们可以提炼出以下知识点: TinyOS是一个为无线嵌入式传感器网络设计的开源...通过学习这些教程,开发者可以掌握如何利用TinyOS所提供的工具和机制,实现快速部署和有效管理资源有限的嵌入式系统。

    tinyos-nesc-note:nesc编程注意事项

    tinyos-nesc-note note of nesc programming ###nesc 学习笔记 记录在学习这新的一门知识的过程中遇到的问题和解决办法,还有一些重要知识点。 一些nesc程序。

    zigbee学习笔记

    ### Zigbee学习笔记要点 #### 一、Zigbee学习误区与正确方向 在学习Zigbee技术的过程中,很多初学者容易陷入一个误区——过度关注协议栈代码的细节。这实际上并不是一种高效的学习方法,主要原因有两点: 1. **从...

    motework学习笔记

    通过以上步骤的学习和实践,不仅可以帮助初学者熟悉 MoteWorks 和 MoteView 的使用,还能让他们了解 TinyOS 下的应用程序开发流程,以及如何控制无线传感器网络中的节点行为。这对于新手来说是非常有价值的实践经验...

    zigduino的Arduino学习笔记

    学习者可以使用Arduino代码来编写程序,并且ZigDuino同样支持多种开源无线传感器网络操作系统,如Contiki、TinyOS和Nank-RK等,这为更深入地学习物联网提供了可能。 在学习资源方面,ZigDuino的开发社区提供了大量...

    无线传感器网络点结构PPT学习教案.pptx

    4. **TinyOS**:是一种专为WSNs设计的操作系统,强调低功耗和模块化,常用于教学和研究。 5. **Ad hoc节点结构**:与标准传感器节点相比,Ad hoc节点通常具有更多辅助设备,如显示器、键盘等,更像是简化版的笔记本...

    基于ARM控制的农业物联网传感器节点系统设计-教程与笔记习题

    2. 软件设计:主要包括固件开发,涉及操作系统的选择(如FreeRTOS或TinyOS),驱动程序编写,以及数据处理算法的设计。软件设计需考虑实时性、节能优化和网络协议栈的实现。 三、物联网传感器类型及功能 1. 温湿度...

Global site tag (gtag.js) - Google Analytics