| 
 | 
 
一、 nesC的语法 
       NesC是标准C的扩展,应用背景是传感器网络这样的嵌入式系统,这类系统的特点是内存有限,存在任务和中断两类操作。NesC的语法和标准C基本没有区别(NesC应该不能动态分配内存)。NesC程序的基本组成是Component,一个Component是一个*.nc文件。每个Component 可以完成一定的工作,一个app一般有一个称为“Main”的Component作为程序的执行体(类似于C的main函数),“Main”调用其他的 component以实现程序的功能。“Main”调用其他Component,以及一个Component调用其他的Component的方式是 “interface”的连接,Component “uses”的interface连接到其他component “provides”的interface。Interface可以看作函数声明的一种封装,一个interface的内容是几个函数的声明(没有函数的定义),TinyOS系统提供了一系列interface(interface应该是由系统提供,不用自己写的)。可以理解为Interface是 Component的属性,函数是interface的属性。Component分为两类,“configuration”用来完成component之间的连接,“module”用来完成该Component的功能(内容是“provides”的interface中函数的定义)。NesC定义了两类特殊的函数,“command”和“event”。函数调用时,Command用“call”,event用“signal”,在一个component 中,provides的interface中的command函数必须被实现(在implementation中定义),uses的interface中的event函数必须被实现。“async”指出这个command或者event可以在有中断时使用。为了协调任务和中断的执行,nesC使用 “atomic”指出该段代码“不可被打断”。另外定义了“task”封装一些代码来完成一个任务,系统有FIFO的task队列。不同的Task之间没有优先级,但task可以被interrupt handler打断。为防止全局变量等公用数据被非正常修改,nesC规定只在task中进入公共的数据部分。 
二、 学习nesC比较有效的过程 
      在系统附带的文档里../tinyos/cygwin/opt/tinyos-1.x/doc/tutorial 提供了8个lesson,是用来熟悉nesC语法用的。把lesson1(Blink)和lesson2(sense)看懂,并且按照后面练习中的要求修改程序。做完之后,对于nesC的语法就比较熟悉了。之后看别的程序差不多就可以直接看源代码了。 
三、 生成程序的结构图 
      很有用的功能,在程序的文件夹里,键入“make micaz docs”命令,可以在../doc/nesdoc/micaz目录下生成这个程序的结构图。通过看结构图来了解程序比较直观。另外,在编写程序的时候,有一个问题,就是调试程序很困难。因此在编写完程序并且编译通过之后,可以先生成它的结构图,检查是否正确,作为调试程序的一个步骤。 
四、 调试方法 
在程序中尽量多得使用三个指示灯,是比较有效的调试方法。程序写完之后可以生成程序的结构图以及用listen命令读取消息包的类型。 
五、 有用的链接 
TinyOS tutorial: http://www.tinyos.net/tinyos-1.x/doc/tutorial/ 
TinyOS FAQ:     http://www.tinyos.net/faq.html#SEC-43 
TinyOS Programming, NesC Tutorial(这些网上可以下载到,没有找到的话,留下Email我给你发,对了我这也有TinyOS中文版和NesC中文版,但我建议还是英文原版的好,翻译过来的实在是...) 
六、 一个程序示例 
(实现RSSI信号的16个Node节点采集,请注意对应的文件名,烧制时注意节点ID号。以下是完整的 Node节点程序,PC程序为以前说的SNICI软件系统,这个程序加以修改可以得到声音定位程序,实验室现在在做视频无线传感器网络的是在 starget上实现的。) 
 
/******************************************************************** 
        Copyright (C), 2006-2007, by Enoch. 
        FileName:       Rssi.h 
        Description:    Hardware specific definitions for the MTS300/310. 
*********************************************************************/ 
 
enum 
{ 
    INITIAL_TIMER_RATE      = 1000, 
    INITIAL_TIMER_REAE_STEP = 8, 
    INITIAL_TIMER_DELAY     = 1500 
}; 
 
enum 
{ 
    BASE_NODE = 0, 
    MOVE_NODE = 100, 
}; 
 
/******************************************************************** 
        Copyright (C), 2006-2007, by Enoch. 
        FileName:       RssiMsg.h 
        Description:    RSSI tracking system. 
*********************************************************************/ 
 
enum 
{ 
    TOTAL_NODE = 16 
}; 
 
typedef struct RssiMsg 
{ 
    uint8_t addr; 
    uint16_t seq; 
}RssiMsg; 
 
typedef struct NodeUARTMsg 
{    
    uint8_t fromaddr; 
    uint8_t rssi; 
    uint16_t seq; 
}NodeUARTMsg; 
 
typedef struct UARTMsg 
{    
    uint8_t rssi[TOTAL_NODE]; 
    uint16_t seq; 
}UARTMsg; 
 
enum 
{ 
    RSSI = 44, 
}; 
 
/******************************************************************** 
        Copyright (C), 2006-2007, by Enoch. 
        FileName:       RssiM.nc 
        Description:    RSSI tracking system. 
*********************************************************************/ 
 
includes RssiMsg; 
includes Rssi; 
 
module RssiM 
{ 
     provides interface StdControl; 
     uses 
     { 
         interface Timer as TimerSend; 
         interface SendMsg as Sendtest; 
         interface ReceiveMsg as Receivetest; 
         interface SendMsg as UARTSend; 
         interface Leds; 
     } 
} 
 
implementation 
{ 
    TOS_Msg MoveData, UARTSendData, MoteSendData; 
    uint8_t rssi_value[TOTAL_NODE]; 
    uint16_t seq = 0; 
    uint32_t i = 0; 
    task void SendData() 
    { 
        call UARTSend.send(TOS_UART_ADDR, sizeof(UARTMsg), &UARTSendData); 
    } 
    task void SendNodeData() 
    { 
        call Sendtest.send(TOS_BCAST_ADDR, sizeof(RssiMsg), &MoveData); 
    } 
     command result_t StdControl.init() 
     { 
         call Leds.init(); 
         call Leds.greenOn(); 
         for (i = 0; i < TOTAL_NODE; i++) 
        { 
            rssi_value = 255; 
        } 
         seq = 0; 
         return SUCCESS; 
     } 
 
     command result_t StdControl.start() 
     {    
         /* Moving node start the timer */ 
         if (TOS_LOCAL_ADDRESS == MOVE_NODE) 
         { 
             call TimerSend.start(TIMER_REPEAT, INITIAL_TIMER_RATE); 
             call Leds.greenToggle(); 
             call Leds.redToggle(); 
         } 
         else if (TOS_LOCAL_ADDRESS == BASE_NODE) 
         { 
             seq = 1; 
         } 
         return SUCCESS; 
     } 
 
     command result_t StdControl.stop() 
     { 
         if (TOS_LOCAL_ADDRESS == MOVE_NODE) 
         { 
             call TimerSend.stop(); 
         } 
         return SUCCESS; 
     } 
     event result_t TimerSend.fired() 
     { 
         /* Moving node send message */ 
         if (TOS_LOCAL_ADDRESS == MOVE_NODE) 
         { 
             RssiMsg* snd_msg = (RssiMsg*)MoveData.data; 
            // Data 
             snd_msg->addr = TOS_LOCAL_ADDRESS; 
             snd_msg->seq = ++seq; 
             call Sendtest.send(TOS_BCAST_ADDR, sizeof(RssiMsg), &MoveData); 
             call Leds.yellowToggle(); 
         } 
         return SUCCESS; 
     } 
 
     event result_t Sendtest.sendDone(TOS_MsgPtr msg, result_t success) 
     { 
          call Leds.yellowToggle(); 
          return SUCCESS; 
     } 
    /* Motes Reciece Message */ 
     event TOS_MsgPtr Receivetest.receive(TOS_MsgPtr msgptr) 
     { 
         /* BASE mote recieve message to UART */ 
         if (TOS_LOCAL_ADDRESS == BASE_NODE) 
         { 
             NodeUARTMsg* node_uart_msg = (NodeUARTMsg*)msgptr->data; 
             UARTMsg* uart_msg = (UARTMsg*)UARTSendData.data; 
             RssiMsg* snd_msg = (RssiMsg*)MoveData.data; 
             uint8_t node_addr = node_uart_msg->fromaddr; 
             uint16_t node_seq = node_uart_msg->seq; 
             uint8_t max_rssi = 255; 
             uint16_t max_node = 0; 
             if (((RssiMsg*)msgptr->data)->addr == MOVE_NODE) 
             { 
                 if (((RssiMsg*)msgptr->data)->seq > 0) 
                 { 
                     /* Select the max rssi value node */ 
                     for (i = 0; i < TOTAL_NODE; i++) 
                     { 
                         uart_msg->rssi = rssi_value; 
                     } 
                    // Data 
                     uart_msg->seq = node_seq; 
                     /* Upstream the data */     
                     //call UARTSend.send(TOS_UART_ADDR, sizeof(RssiMsg), &MoveData); 
                     //call UARTSend.send(TOS_UART_ADDR, sizeof(UARTMsg), &UARTSendData); 
                     post SendData(); 
                     //post SendNodeData(); 
                     //call Sendtest.send(TOS_BCAST_ADDR, sizeof(RssiMsg), &MoveData); 
                     for (i = 0; i < TOTAL_NODE; i++) 
                     { 
                         rssi_value = 255; 
                     } 
                     rssi_value[node_addr-1] = node_uart_msg->rssi; 
                     //call Leds.redToggle(); 
                 } 
                 return msgptr; 
             } 
             else 
             { 
                 /* data is recieved for saving */ 
                 rssi_value[node_addr-1] = node_uart_msg->rssi; 
                 //call Leds.greenToggle(); 
             }    
         } 
         /* Node proccess */ 
         else if (TOS_LOCAL_ADDRESS > BASE_NODE && TOS_LOCAL_ADDRESS != MOVE_NODE) 
         { 
             RssiMsg* recv_rssi_msg = (RssiMsg*)msgptr->data; 
             NodeUARTMsg* send_mote_msg = (NodeUARTMsg*)MoteSendData.data; 
             if (recv_rssi_msg->addr == MOVE_NODE) 
             { 
                 send_mote_msg->fromaddr = TOS_LOCAL_ADDRESS; 
                  send_mote_msg->rssi = (int8_t)msgptr->strength; 
                  send_mote_msg->seq = recv_rssi_msg->seq; 
                  /* Delay send to base mote */ 
                  for (i = 0; i < TOS_LOCAL_ADDRESS * INITIAL_TIMER_DELAY; i++) 
                 call Sendtest.send(BASE_NODE, sizeof(NodeUARTMsg), &MoteSendData); 
              } 
              else if (recv_rssi_msg->addr == BASE_NODE) 
              { 
                  if (recv_rssi_msg->seq == TOS_LOCAL_ADDRESS) 
                  { 
                      call Leds.redOn(); 
                  } 
                  else 
                  { 
                      call Leds.redOff(); 
                  } 
              }    
         } 
         return msgptr; 
     } 
    // UART Send Message 
       event result_t UARTSend.sendDone(TOS_MsgPtr msg, result_t success) 
     { 
         //call Leds.yellowToggle(); 
          return SUCCESS; 
     } 
} 
/******************************************************************** 
        Copyright (C), 2006-2007, by Enoch. 
        FileName:       Makefile 
        Description:   RSSI tracking system. 
*********************************************************************/ 
 
COMPONENT = Rssi 
 
XBOWROOT=%T/../contrib/xbow/tos 
 
PFLAGS= -I$(XBOWROOT)/platform/micaz 
 
# For MICA2 and MICA2DOT 
#PFLAGS+= -I../../tos/platform/mica2 -I../../tos/CC1000RadioAck -I../../tos/lib/ReliableRoute -I%T/lib/Queue -I%T/lib/Broadcast -I%T/lib/Attributes 
 
# For MICAZ 
PFLAGS+= -I../../beta/tos/lib/CC2420Radio -I%T/lib/Broadcast -I%T/lib/Attributes 
 
include ../MakeXbowlocal 
include ${TOSROOT}/tools/make/Makerules  
 |   
 
 
 
 |