Posts Contiki 功耗评估
Post
Cancel

Contiki 功耗评估

1. 前言

在无线传感器网络中,网络节点的功耗是一个很重要的问题。通常情况下,为了节省能量,传感器节点会关闭射频接收器,这些射频接收器仅仅在接收来自其他节点(例如,邻居节点)的数据包时打开。这个方法的原理是,当传感器节点无需接收数据时,能量消耗是最少的。然而,在某些应用中,这个方法很可能是无效或者干脆不能被使用。

在Contiki中,MAC 和 RDC(Radio Duty Cycling)在通信协议栈中的地位非常重要,因为它们会直接影响传感器节点的总功耗。

Contiki中集成了多种RDC驱动,例如:ContikiMAC、X-MAC、LPP 以及 NullRDC。RDC 驱动会尽可能的关闭射频接收器以降低节点功耗。另外,它会周期性检查是否需要接收数据。默认检查频率为 8Hz。

  • Contiki MAC:适用于802.15.4
  • X-MAC:短序文协议
  • LPP:由接收者发起传输的RDC协议
  • NullRDC:从不会关闭射频接收器(测试用)

Contiki有两种类型的 MAC: nullmac 以及 csma。

  • nullmac:简单的“通过型”协议
  • csma:实现了寻址、序列号以及重传

2. 设置 RDC 驱动

若要启动RDC驱动,需要在项目中包含头文件 project-conf.h。注意,每个项目都有一个特点的配置文件。另外,为了启动 RDC 配置,必须在项目的 Makefile 中添加以下内容:

1
CFLAGS += ­DPROJECT_CONF_H="project­conf.h" 

完整的 Makefile 文件看起来像这样:

1
2
3
CONTIKI = /home/user/contiki
CFLAGS += DPROJECT_CONF_H=\"project.conf.h\"
include $(CONTIKI)/Makefile.include 

配置文件用于重写 Contiki 的一项或多项默认配置。为了启用 RDC,需要在项目配置文件中重写 RDC 层驱动的配置信息。

首先,添加以下内容,以修改RDC通道的检查频率(Hz):

1
#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 16

接下来,指定 RDC 驱动:

1
#define NETSTACK_CONF_RDC nullrdc_driver 

最后,指定MAC驱动的类型:

1
#define NETSTACK_CONF_MAC nullmac_driver 

设置完成后,建议通过以下命令清除项目文件夹中已经存在的依赖(如果之前编译过该项目的话。使用需要部署的节点的类型替换[platform],例如“cc2530dk”。):

1
make TARGET=[platform] clean

接下来,编译即可:

1
make TARGET=[platform]

需要注意的是,默认情况下,Contiki协议栈各层使用的驱动如下:

  1. Network layer - rime_driver
  2. MAC layer - nullmac_driver
  3. RDC - nulldc_driver
  4. Framer - framer_nullmac
  5. Radio - nullradio_driver

Contiki中RDC驱动及与其对应的值

RDC驱动配置
ContikiMACcontikimac_driver
Null_RDCnullrdc_driver
LPPlpp_driver
X-MACxmac_driver
CX-MACcxmac_driver

3. 功耗评估

在 Contiki 中,可以使用 Energest 模块来估计能量消耗。本例中,只关注四个方面的功耗:传输、监听、CPU 以及 LPM。

  • 传输和监听指射频传输和接收

  • CPU指微控制器在没有射频传输和接收情况下的运行模式

  • LPM指低功耗模式(low power mode,例如,睡眠模式)

能量消耗由电压、电流以及持续时间(传感器节点为某项操作花费的时间,例如:传输、接收)相乘得出。电压和电流可以从节点的数据手册(datasheet)中获得。

需要注意的几点:Energest 模块返回的不是某项操作花费的秒数,而是CPU的时钟周期数(ticks)。因此,为了得到秒数,需要使用常量 RTIMER_SECOND 去除时钟周期数。这个常量表示每秒包含的 CPU 时钟周期数,并且随着平台的不同而不同。因此,为了减少复杂性,直接使用 Contiki 中Clock 库内的宏。

可以用下列公式来计算传感器节点的能量消耗:

1
2
3
4
5
𝐸𝑡𝑟𝑎𝑛𝑠𝑚𝑖𝑡 = 𝑡𝑡𝑟𝑎𝑛𝑠𝑚𝑖𝑡(𝑡𝑖𝑐𝑘𝑠) / 𝑡𝑖𝑚𝑒𝑟 (𝑡𝑖𝑐𝑘𝑠/𝑠𝑒𝑐𝑜𝑛𝑑) ∗ 𝐼𝑡𝑟𝑎𝑛𝑠𝑚𝑖𝑡 ∗ V
𝐸𝑡𝑟𝑎𝑛𝑠𝑚𝑖𝑡 = 𝑡𝑡𝑟𝑎𝑛𝑠𝑚𝑖𝑡(𝑡𝑖𝑐𝑘𝑠) / 𝑡𝑖𝑚𝑒𝑟 (𝑡𝑖𝑐𝑘𝑠/𝑠𝑒𝑐𝑜𝑛𝑑) ∗ 𝐼𝑡𝑟𝑎𝑛𝑠𝑚𝑖𝑡 ∗ V
𝐸𝑟𝑒𝑐𝑖𝑣𝑖𝑛𝑔 = 𝑡𝑟𝑒𝑐𝑒𝑖𝑣𝑖𝑛𝑔(𝑡𝑖𝑐𝑘𝑠) / 𝑡𝑖𝑚𝑒𝑟 (𝑡𝑖𝑐𝑘𝑠/𝑠𝑒𝑐𝑜𝑛𝑑) ∗ 𝐼𝑟𝑒𝑐𝑒𝑖𝑣𝑖𝑛𝑔 ∗ 𝑉
𝐸𝐶𝑃𝑈 = 𝑡𝐶𝑃𝑈(𝑡𝑖𝑐𝑘𝑠) / 𝑡𝑖𝑚𝑒𝑟 (𝑡𝑖𝑐𝑘𝑠/𝑠𝑒𝑐𝑜𝑛𝑑) ∗ 𝐼𝐶𝑃𝑈 ∗ 𝑉
𝐸𝐿𝑃𝑀 = 𝑡𝐿𝑃𝑀(𝑡𝑖𝑐𝑘𝑠) / 𝑡𝑖𝑚𝑒𝑟 (𝑡𝑖𝑐𝑘𝑠/𝑠𝑒𝑐𝑜𝑛𝑑) ∗ 𝐼𝐿𝑃𝑀 ∗ V

4. 示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "sys/energest.h"
…
static unsigned long rx_start_duration; 
…
while(1) {
 …
 cpu = energest_type_time(ENERGEST_TYPE_CPU;
 lpm = energest_type_time(ENERGEST_TYPE_LPM); 
 transmit = energest_type_time(ENERGEST_TYPE_TRANSMIT);
 listen = energest_type_time(ENERGEST_TYPE_LISTEN);
 time = cpu + lpm;
 radio = transmit + listen;
 …
}

参考

[1] Cousera Embedded Hardware and Operating Systems 课程互评作业(Energy consumption estimation)指导材料

[2] The ContikiMAC Radio Duty Cycling Protocol. Adam Dunkels. Technical report 2011.http://dunkels.com/adam/dunkels11contikimac.pdf

This post is licensed under CC BY 4.0 by the author.