Cooja模拟器运行Contiki-ng湿度传感器代码报错:Event is already scheduled: DELAY
问题解决办法
1. 修正进程事件处理逻辑
原代码中多余的事件判断会导致逻辑分支混乱,甚至可能在极端情况下引发定时器重复调度问题。修改后的进程代码如下:
PROCESS_THREAD(humidity_sensor_process, ev, data) { PROCESS_BEGIN(); static struct etimer et_hum; // 初始化随机数生成器,保证每次模拟的湿度变化序列不同 srand((unsigned int)clock_seconds()); etimer_set(&et_hum, 5 * CLOCK_SECOND); // 每5秒采样一次湿度 while (1) { // 阻塞直到定时器过期,无需额外判断事件类型 PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et_hum)); humidity = generate_humidity_data(); printf("Humidity: %d\n", humidity); // 重启定时器,自动处理旧事件的取消与新事件的调度 etimer_restart(&et_hum); } PROCESS_END(); }
2. 初始化随机数生成器
在进程启动时调用srand((unsigned int)clock_seconds()),避免每次运行生成完全相同的湿度变化序列,同时消除未初始化变量带来的潜在风险。
3. 检查版本兼容性
如果修改代码后问题依然存在,尝试将Contiki-ng更新到最新稳定版本。旧版本的Cooja模拟器可能存在事件队列的已知bug,会导致重复添加事件触发崩溃。
4. 替换定时器重启方式(可选)
若上述方案无效,可以改用etimer_reset或重新调用etimer_set替代etimer_restart:
// 替代etimer_restart的写法 etimer_reset(&et_hum); // 或者重新设置定时器 etimer_set(&et_hum, 5 * CLOCK_SECOND);
问题根源分析
原代码中PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et_hum))已经确保只有定时器过期事件触发时才会执行后续代码,额外的if (ev == PROCESS_EVENT_TIMER && data == &et_hum)判断属于冗余逻辑。这种冗余可能导致定时器状态异常,进而触发Cooja事件队列的重复添加错误。
内容的提问来源于stack exchange,提问作者Noushin
相关产品推荐
相关产品推荐

