contiki 之 button sensor
@(我的第一个笔记本)[sensor, button, cc1310]
contiki是以一款应用于单片机上的操作系统,主要服务于WSN(无线传感器网络)。它的强大之处在于对于网络方面的支持,包括6lowpan, IEEE802.15.4,rime 等网络协议。不仅如此,低内存占有,protothread的设计也为人们津津乐道。它的作者是大名鼎鼎的Adam,同时也是uip和lwip的作者。还有就是完全开源,并辅以许多高质量论文,这对于有兴趣研究的同学,可算是关键问题了。
————————————
Sensor 简介
sensor 顾名思义,就是生活中无处不在的传感器。可以用于检测温度、湿度、电流、压力等等参数。由于contiki主要服务于WSN(无线传感器网络),其中关于sensor方面的设计自然是重中之重。那么这些sensor检测到的数据是怎么传输给单片机处理的呢?下面将会以德州仪器的cc1310作为例子,介绍button sensor的工作原理。
数据结构
part1
路径&文件名 (contiki-3.0\core\lib\sensor.h)
struct sensors_sensor {
char * type;
int (* value) (int type);
int (* configure) (int type, int value);
int (* status) (int type);
};
这个结构体用于定义每一个sensor属性。
- type:一个char类型的指针,一般会用一个字符串定义这个sensor的类型。
- value:一个输入参数为( int ) 类型,返回值也为int类型的函数指针。这个函数主要用于取得该sensor的值。
- configure:一个输入参数为( int ,int ) 类型,返回值也为int类型的函数指针。主要用于该sensor的初始化配置。
- status:主要用于查看该sensor的状态。
part2
#define SENSORS_SENSOR(name, type, value, configure, status) \
const struct sensors_sensor name = { type, value, configure, status }
很明显,该宏定义用于创建一个名字为name的具体的sensors_sensor结构体。
part3
#define SENSORS_NUM (sizeof(sensors) / sizeof(struct sensors_sensor *))
#define SENSORS(...) \
const struct sensors_sensor *sensors[] = {__VA_ARGS__, NULL}; \
unsigned char sensors_flags[SENSORS_NUM]
刚才的SENSORS_SENSOR是为了创建一个具体的sensors_sensor,之所以每个sensor都用一个结构体来定义就是方便管理和使用。最终是需要把他们统一起来的。这里,SENSORS(…) 的作用就是把它们都统一到一个数组里面方便管理。但,这并不是单纯地把结构体都放在数组里面,而是把代表每个sensor的结构体指针放在数组里面。这样既不影响每个sensor的单独定义,又能够把它们放在一起集中管理。
宏定义的SENSORS_NUM能取到sensor的数量。利用它,能够定义一个相同数量的sensor_flags的数组,用于作为每个sensor的标记。
Sensor模版设计
sensor的整体设计大致就是每个sensor触发后,就会交给sensor_process线程(PROCESS_THREAD)进行处理。下面先介绍sensor_process线程(PROCESS_THREAD)用到的几个函数。
sensors.c 内的几个函数
路径&文件名 (contiki-3.0\core\lib\sensor.c)
get_sensor_index
static int
get_sensor_index(const struct sensors_sensor *s)
{
int i;
for(i = 0; i < num_sensors; ++i) {
if(sensors[i] == s) {
return i;
}
}
return i;
}
它的输入参数为类型为sensors_sensor的结构体。也就是每个sensor在使用之初都会利用sensors_sensor结构体来定义自己的属性,详见 数据结构 part1。该函数遍历数组const struct sensors_sensor * sensors[]中的结构体,并找到代表该sensor的结构体在指针数组中的索引(index)位置。
sensors_first
const struct sensors_sensor *
sensors_first(void)
{
return sensors[0];
}
该函数用于查找数组const struct sensors_sensor * sensors[]的第一个结构体,并返回该sensor的结构体指针。
sensors_next
const struct sensors_sensor *
sensors_next(const struct sensors_sensor *s)
{
return sensors[get_sensor_index(s) + 1];
}
找到下一个sensor的结构体,并返回该sensor的结构体指针。
sensors_changed
#define FLAG_CHANGED 0x80
void
sensors_changed(const struct sensors_sensor *s)
{
sensors_flags[get_sensor_index(s)] |= FLAG_CHANGED;