教学文库网 - 权威文档分享云平台
您的当前位置:首页 > 精品文档 > 政务民生 >

TinyOS系统与nesC程序设计课内实验指导书(9)

来源:网络收集 时间:2026-07-10
导读: 2、Cygwin with TinyOS 2.x 3、UltraEdit / EditPlus 四 实验内容和步骤 1、卷 一个卷表具体的写法如下: 卷表是针对特殊应用的,所以必须放在应用程序的文件夹中且命名为volumes-CHIPNAME.xml(CHIPNAME是特定平台

2、Cygwin with TinyOS 2.x 3、UltraEdit / EditPlus

四 实验内容和步骤 1、卷

一个卷表具体的写法如下:

卷表是针对特殊应用的,所以必须放在应用程序的文件夹中且命名为volumes-CHIPNAME.xml(CHIPNAME是特定平台的闪存芯片名)。举例来说,telos节点使用的是M25P闪存家族的ST微电子器件,这种芯片的驱动在/tos/chips/stm25p目录下。 2、存储配置数据

本节介绍如何从闪存读/写配置数据。配置数据有以下几个特点:这些数据的大小有限,从几十到几百字节不等;这些值在不同节点平台上是不统一的;这些值有时是未知的,有时又与硬件相关。由于上述特点,在节点重启,重新供电,或是对它重新写程序时,配置数据必须依然存在并且能够重新存储。配置数据包括以下几种:

? 校验 传感器节点的系数校验是在节点出厂时就已经配置好的,这些数据需要在节

点中永久存在。例如一个假想的温度传感器可能会有偏移(offset)和获取(gain)两个数据需要校验,它们必须永久的存储着,这样才能将输出由电压值转换成摄氏度。这些校验数据如下结构:

typedef struct calibration_config_t { int16_t temp_offset; int16_t temp_gain; } calibration_config_t; ? 识别 设备识别信息,像IEEE MAC地址或是TinyOS的TOS_NODE_ID参数。它

们虽然不是由硬件指定的,但是一旦分配了,就得永久的存储起来。 typedef struct radio_config_t { ieee_mac_addr_t mac; uint16_t tos_node_id; } radio_config_t; ? 定位 节点位置数据在编译时是不知道的,只有当部署时才会有用。应用程序可能

会像下面给出的坐标方式存储:

typedef struct coord_config_t { uint16_t x; uint16_t y; uint16_t z; } coord_config_t; ? 传感 传感器采集和处理数据过程中,使用的参数像采样周期,过滤系数和检测阈

值等配置数据可能会进行调整。 typedef struct sense_config_t { uint16_t temp_sample_period_milli; uint16_t temp_ema_alpha_numerator; uint16_t temp_ema_alpha_denominator; uint16_t temp_high_threshold; uint16_t temp_low_threshold; } sense_config_t; 上面介绍了几种配置数据以及为什么要使用这种存储,接下来,我们要看看如何使用 它们。/tinyos-2.x/apps/tutorials/BlinkConfig/ 在程序第一次运行之前,一个卷它不包含任何有用数据。所以,我们的代码需要检测卷的第一次使用并采取合适的措施(事先加载默认值)。类似的,当卷的数据布局改变了(例如,应用程序需要不同的配置变量时),程序也要检测出来并采取相应的动作。因此,我们需要追踪卷的版本号,定义的配置结构包含版本号和灯闪烁周期:

typedef struct config_t { uint16_t version; uint16_t period; } config_t; (1)卷表volumes-stm25p.xml(telosb)信息用于创建一个包含文件(include file)。这个文件是系统自己生成的,但是需要在声明ConfigStorageC组件的配置文件(BlinkConfigAppC.nc)中手动添加一句话: #include \

(2)BlinkConfigC使用了Mount和ConfigStorage接口。

module BlinkConfigC { uses { ... interface ConfigStorage as Config; interface Mount; ... } } (3)这两个接口都是由ConfigStorageC(VOLUME_CONFIGTEST)提供的,这是一个泛型组件。

configuration BlinkConfigAppC { } implementation { components BlinkConfigC as App; components new ConfigStorageC(VOLUME_CONFIGTEST); ... App.Config -> ConfigStorageC.ConfigStorage; App.Mount -> ConfigStorageC.Mount; ... }

(4)在闪存芯片被使用之前,必须先将它挂载(mount)。

event void Boot.booted() { conf.period = DEFAULT_PERIOD; if (call Mount.mount() != SUCCESS) { // Handle failure } } (5)当挂载成功后,接下来需要检查各卷是否有用(valid)。若可用,则读闪存(ConfigStore.read);不可用,则调用Config.commit(该命令也可以将缓存数据刷到闪存里)使它变得可用。

event void Mount.mountDone(error_t error) { if (error == SUCCESS) { if (call Config.valid() == TRUE) { if (call Config.read(CONFIG_ADDR, &conf, sizeof(conf)) != SUCCESS) // Handle failure } else { // Invalid volume. Commit to make valid. call Leds.led1On(); if (call Config.commit() == SUCCESS) { call Leds.led0On(); } else { // Handle failure } } } else{ // Handle failure } } (6)如果读成功,我们检查版本号。若版本号相同,则把配置数据复制到本地变量,并调整它的值;不然,设为默认值。最后,调用Config.write命令。

event void Config.readDone(storage_addr_t addr, void* buf, storage_len_t len, error_t err) __attribute__((noinline)) { if (err == SUCCESS) { memcpy(&conf, buf, len); if (conf.version == CONFIG_VERSION) { conf.period = conf.period/2; conf.period = conf.period > MAX_PERIOD ? MAX_PERIOD : conf.period; conf.period = conf.period < MIN_PERIOD ? MAX_PERIOD : conf.period; } else { // Version mismatch. Restore default. call Leds.led1On(); conf.version = CONFIG_VERSION; conf.period = DEFAULT_PERIOD; } call Leds.led0On(); call Config.write(CONFIG_ADDR, &conf, sizeof(conf)); } else { // Handle failure. } }

(7)在Config.write之后,再用Config.commit来确保数据写到闪存中。 event void Config.writeDone(storage_addr_t addr, void *buf, storage_len_t len, error_t err) { // Verify addr and len if (err == SUCCESS) { if (call Config.commit() != SUCCESS) { // Handle failure } } else { // Handle failure } } (8)安装程序到节点,观察实验现象。

(9)将节点拔下后重新插上供电,观察实验现象。 (10)重复(9),观察实验现象。

3、日志数据 可靠的记录事件或是小的数据项是一个普通应用程序的要求。当系统崩溃时,那些数据不应被丢失。我们可以线性的记录这些数据(当卷满时停止记录)或是循环的记录它们(当卷满时,把最不常用的数据项覆盖掉)。 TinyOS中LogStorage抽象支持这些需求。演示程序PacketParrot,向大家展示了如何使用LogWrite和LogRead抽象。它先将接收到的数据包写入日志,当下一个电力循环(power cycle)开始时,发送记录到日志的数据包,同时擦除日志。 (1)首先定义我们想要存储的日志结构:

typedef nx_struct logentry_t { nx_uint8_t len; message_t msg; } logentry_t; (2)与Config存储不同,Log存储不要求在应用程序中明确地挂载卷。一个简单的读命令就足够了。

event void AMControl.startDone(error_t err) { if (err == SUCCESS) { if (call LogRead.read(&m_entry, sizeof(log …… 此处隐藏:3041字,全部文档内容请下载后查看。喜欢就下载吧 ……

TinyOS系统与nesC程序设计课内实验指导书(9).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
本文链接:https://www.jiaowen.net/wendang/447636.html(转载请注明文章来源)
Copyright © 2020-2025 教文网 版权所有
声明 :本网站尊重并保护知识产权,根据《信息网络传播权保护条例》,如果我们转载的作品侵犯了您的权利,请在一个月内通知我们,我们会及时删除。
客服QQ:78024566 邮箱:78024566@qq.com
苏ICP备19068818号-2
Top
× 游客快捷下载通道(下载后可以自由复制和排版)
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能出现无法下载或内容有问题,请联系客服协助您处理。
× 常见问题(客服时间:周一到周五 9:30-18:00)