TinyOS、NesC程序开发经验谈
2019独角兽企业重金招聘Python工程师标准>>>
一、 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[i] = 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[i] = rssi_value[i];
}
// 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[i] = 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
转载于:https://my.oschina.net/wizardpisces/blog/209239
TinyOS、NesC程序开发经验谈相关推荐
- TinyOS、NesC程序开发经验谈[转载]
TinyOS.NesC程序开发经验谈[转载] 说明:来源于http://chinawangquan.spaces.live.com/blog/cns!9CF795352E94BF70!434.entr ...
- 《拍拍二手》微信小程序开发经验谈
前两周想必大家都看到了京东发布拍拍二手交易平台的新闻,「拍拍二手」APP也正式上线.与此同时我们也紧锣密鼓的进行着「拍拍二手」微信小程序的开发.整个过程痛并快乐着,体会着采坑的痛苦,和跳出坑之后的喜悦 ...
- 我的Delphi开发经验谈(转)
--2010年09月28日 星期二 下午 05:26 我的Delphi开发经验谈 -------- 开发环境 -------- Delphi 7是一个很经典的版本,在Win2000/XP下推荐安装De ...
- 项目开发经验谈之:项目到底谁说了算
项目开发经验谈:项目的到底谁说了算 前言:项目到底是为谁而做,一个项目的成功到底是怎么样在评价:是领导阶层肯定,还是客户满意? 系列文章链接 项目开发经验谈:如何成为出色的开发人员 盲目的项目开发 ...
- Android开发经验谈-很少有人会告诉你的Android开发基本常识,经验谈android
转载:http://www.android100.org/html/201507/15/165084.html Android开发经验谈-很少有人会告诉你的Android开发基本常识,经验谈andro ...
- zt我的Delphi开发经验谈
我的Delphi开发经验谈 -------- 开发环境 -------- Delphi 7是一个很经典的版本,在Win2000/XP下推荐安装Delphi 7来开发软件,在Vista下推荐使用 ...
- 基于Golang的CLI 命令行程序开发
基于Golang的CLI 命令行程序开发 [阅读时间:约15分钟] 一. CLI 命令行程序概述 二. 系统环境&项目介绍&开发准备 1.系统环境 2.项目介绍 3.开发准备 三.具体 ...
- python笔记6 模块与包 程序开发规范 包 re sys time os模块
模块与包 python 模块首引用加载到内存,如果再次引用此模块,直接从内存中读取. python文件分为:执行文件(解释器运行的文件),被引用文件(import) 模块引用一共发生了3件事: 1.他 ...
- Spark菜鸟学习营Day5 分布式程序开发
Spark菜鸟学习营Day5 分布式程序开发 这一章会和我们前面进行的需求分析进行呼应,完成程序的开发. 开发步骤 分布式系统开发是一个复杂的过程,对于复杂过程,我们需要分解为简单步骤的组合. 针对每 ...
最新文章
- Spring Boot中实现跨域的五种方式
- 程序中下载采购申请的附件
- python实现以及所有排序大总结【转】
- 递归法:财务金额漏掉1笔或者几笔(排列组合)
- 【王道考研】计算机网络知识点
- spreadjs使用
- ntfs是什么硬盘?ntfs硬盘如何在苹果电脑使用
- 移动安全-IOS越狱
- 绝对地址、相对地址、/、./、../之间的区别
- ALPS磁式传感器和轴地磁式传感器
- MySQL:BLOB/TEXT Column Used in Key Specification Without a Key Length
- matlab坐标值旋转平移
- 阿里云部署公司网盘实例
- cisco链路聚合 不均衡_思科CISCO交换机间链路聚合端口聚合实现方法详解
- java:去除数组重复元素的四种方法
- 45-js操作DOM和bom操作
- java容器系列一(java容器Collection概述)
- 莫烦Python--Tensorflow Day5
- 火车头采集下载图片的位置和URL地址的更换
- Re-ID: Person Re-identification by Local Maximal Occurrence Representation and Metric Learning 论文解析