2. LED闪烁控制
任务目标
在Contiki OS中,使用etimer事件定时器驱动一个进程,实现LED以固定周期交替亮灭。通过本案例掌握Contiki进程的基本结构、PROCESS_EVENT_TIMER事件的处理方式,以及etimer的周期性重载方法。
环境与依赖
本案例面向Contiki原生平台(如Sky mote、CC2538DK等),需要:
- Contiki操作系统源码(版本3.x或2.7均可)
- 目标平台对应的工具链(如msp430-gcc)
- 平台LED驱动头文件(通常为
dev/leds.h)
核心实现
以下代码创建一个独立进程,启动后每0.5秒切换一次LED状态。使用etimer_set实现单次定时,在事件处理中重新加载定时器形成周期循环。
#include "contiki.h"
#include "dev/leds.h"
#include <stdio.h>
/* 定义LED闪烁进程 */
PROCESS(led_blink_process, "LED Blink");
AUTOSTART_PROCESSES(&led_blink_process);
/* 闪烁周期:0.5秒 */
#define BLINK_INTERVAL (CLOCK_SECOND / 2)
PROCESS_THREAD(led_blink_process, ev, data)
{
static struct etimer timer;
static uint8_t led_state = 0;
PROCESS_BEGIN();
/* 设置初始定时器 */
etimer_set(&timer, BLINK_INTERVAL);
while(1) {
/* 等待定时器事件 */
PROCESS_WAIT_EVENT_UNTIL(ev == PROCESS_EVENT_TIMER);
/* 切换LED状态 */
if(led_state == 0) {
leds_on(LEDS_RED);
led_state = 1;
} else {
leds_off(LEDS_RED);
led_state = 0;
}
/* 重新加载定时器,实现周期性触发 */
etimer_reset(&timer);
}
PROCESS_END();
}
编译与烧录
以Sky mote平台为例,在Contiki源码根目录执行:
make TARGET=sky led-blink
make TARGET=sky led-blink.upload
若使用其他平台,将TARGET替换为对应平台名称(如cc2538dk),并确保平台支持LEDS_RED定义。
验证方法
将编译固件烧录至目标硬件后,观察板载LED:
- 红色LED应以0.5秒为周期交替亮灭(亮0.5秒,灭0.5秒)
- 若平台无红色LED,可改用
LEDS_GREEN或LEDS_YELLOW,需确认平台leds.h中定义了对应宏 - 通过串口连接目标板,若在
while(1)循环中加入printf输出状态变化,可观察到周期性的串口打印
通过条件:LED按预期周期持续闪烁,且进程不阻塞其他系统任务(如无线协议栈仍可正常工作)。
关键说明
Contiki的etimer是事件定时器,到期后向关联进程发送PROCESS_EVENT_TIMER事件。本案例使用etimer_reset重新加载相同周期,而非重新调用etimer_set,两者区别在于reset基于原定时间点计算下一次到期时间,长时间运行下更精确。若需动态改变周期,应使用etimer_set。
进程通过PROCESS_WAIT_EVENT_UNTIL宏挂起自身,直到定时器事件到达才继续执行,这体现了Contiki的协作式调度——进程在等待时不占用CPU,适合低功耗物联网场景。