第七章 TinyOS典型应用

第二节 存储

    7.2.2  配置数据的存储

    配置数据是指用于配置节点属性的一组参数。它们的字节数是不确定的,从几十字节到几百字节,一般都属于小数据对象。另外,它们的值也不确定,在各个节点可能都不一样,甚至是未知的。本节主要介绍配置数据如何保存以及如何从存储中读取。

    配置数据要求必须能够在复位、能量循环(关闭电源,再重开电源,算作一个能量循环)或者重编程时保存下来。在很多场合,完整保存配置数据的能力是非常必要的。

    对于传感器网络节点而言,配置数据中一个很重要的部分是刻度校正。一般情况下,传感器的校准系数在节点出厂时就已配置好,并存储下来,所以它们不会在节点掉电或者重编程时丢失。例如,温度传感器利用校准系数将输出电压信号转换成直观的温度数据。传感器校准系数的结构定义代码可参考如下:

    typedef struct calibration_config_t {

       int16_t temp_offset;

       int16_t temp_gain;

    } calibration_config_t;

    身份信息,即设备辨认信息,也是配置数据的重要组成部分。如IEEE兼容的MAC地址或TinyOS的TOSNODE_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;

    接下来我们将用一个简单的例子程序来说明如何存储和读取配置数据,这个示例程序的功能是节点周期性地从flash中读出配置数据,处理后再写回flash。

    卷在第1次使用之前不包含任何有效数据。因此,应当首先检测卷是否是初次使用,并作出适当的行为(例如预加载默认值)。同样,当卷中的数据发生变化时(例如应用程序需要新的或不同的配置变量),应用程序应当检测到变更,并作出相应的响应(例如擦写卷,并重新加载默认值)。类似这些情况,建议跟踪卷的版本。为此,在配置数据的结构中,引入了版本控制变量。BlinkConfig应用中配置数据的字段包括卷的版本和读取周期。其结构形式如下:

    typedef struct config_t {

    uint16_t version;

      uint16_t period;

    } config_t;

    下面将分析BlinkConfig例子程序的设计要点和具体的操作步骤:

    创建volumes-CHIPNAME.xml文件,即建立卷表,并保存在应用程序所在目录。注意,CHIPNAME是目标平台上的flash芯片名字。例如,Telos平台上的flash是stm25p,Micaz平台的flash则是at45db。卷表的具体内容如下:

    <volume_table>

    <volume name="LOGTEST" size="262144"/>

    <volume name="CONFIGTEST" size="131072"/>

    </volume_table>

    编译工具会利用该卷表自动创建一个StorageVolumes.h头文件。然而,在有Config StorageC组件声明的配件(如BlinkConfigAppC组件)里,需要手动添加该头文件:

    #include "StorageVolumes.h"

    (2)在BlinkConfigC模块的规范说明里,声明Mount接口和ConfigStorage接口。注意,ConfigStorage接口被重命名为Config接口。其代码如下: