You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

拆分TinyOS RadioCountToLeds为收发独立应用后无法运行的问题

拆分TinyOS RadioCountToLeds为收发独立应用后无法运行的问题排查与修复

我帮你梳理了拆分后代码的几个核心问题,这些问题导致了程序无法正常运行,下面逐个说明并给出修复方案:

核心问题点

1. 头文件名称不匹配

你的头文件实际命名为RadioCountToLed.h,但收发应用的代码中均使用#include "RadioCountToLeds.h"(多了末尾的s)。在C语言编译阶段,文件名必须完全匹配,这会直接导致编译器找不到radio_count_msg_t结构体和AM_RADIO_COUNT_MSG常量的定义,编译失败。

2. 接收应用配置文件接口绑定缺失

接收模块RadioCountToLedsC声明使用了Boot、Receive、Packet接口,但你的接收应用配置文件RadioCountToLedsAppC.nc中只绑定了Leds接口到LedsC,其他关键接口都没有绑定到对应的实现组件:

  • Boot接口需要绑定到MainC.Boot才能触发启动事件
  • Receive接口需要绑定到AMReceiverC才能接收数据包
  • Packet接口需要绑定到AMReceiverC才能获取数据包 payload

没有这些绑定,模块的接口没有实际的实现载体,程序无法完成初始化,也无法接收任何数据包。

3. 发送应用冗余组件与定时器重复启动

  • 发送应用的配置中包含了AMReceiverC,但发送逻辑不需要接收功能,属于冗余配置,会浪费节点资源。
  • 发送模块的Boot.booted和AMControl.startDone中都调用了MilliTimer.startPeriodic(250),重复启动定时器可能导致触发频率异常或逻辑冲突。

修复后的完整代码

第一步:统一头文件名称

将头文件重命名为RadioCountToLeds.h(保持和代码中include一致),内容不变:

#ifndef RADIO_COUNT_TO_LEDS_H
#define RADIO_COUNT_TO_LEDS_H

typedef nx_struct radio_count_msg {
  nx_uint16_t counter;
} radio_count_msg_t;

enum {
  AM_RADIO_COUNT_MSG = 6,
};

#endif

修复后的接收应用

RadioCountToLedsC.nc(模块代码,仅修正头文件include)

#include "Timer.h"
#include "RadioCountToLeds.h"

module RadioCountToLedsC @safe() {
  uses {
    interface Leds;
    interface Boot;
    interface Receive;
    interface Packet;
  }
}

implementation {
  message_t packet;
  uint16_t counter = 0;

  event void Boot.booted() {
  }

  event message_t* Receive.receive(message_t* bufPtr, void* payload, uint8_t len) {
    dbg("RadioCountToLedsC", "Received packet of length %hhu.\n", len);
    if (len != sizeof(radio_count_msg_t)) {
      return bufPtr;
    } else {
      radio_count_msg_t* rcm = (radio_count_msg_t*)payload;
      
      call Leds.led0On();
      if (rcm->counter%3 != 0) {
        call Leds.led0Off();
      }
      
      call Leds.led1On();
      if (rcm->counter%3 != 1) {
        call Leds.led1Off();
      }
      
      call Leds.led2On();
      if (rcm->counter%3 != 2) {
        call Leds.led2Off();
      }
      
      return bufPtr;
    }
  }
}

RadioCountToLedsAppC.nc(配置文件,补充接口绑定)

#include "RadioCountToLeds.h"

configuration RadioCountToLedsAppC {}

implementation {
  components MainC, RadioCountToLedsC as App, LedsC;
  components new AMReceiverC(AM_RADIO_COUNT_MSG);
  components ActiveMessageC;

  // 绑定所有使用的接口到对应实现组件
  App.Boot -> MainC.Boot;
  App.Receive -> AMReceiverC;
  App.Packet -> AMReceiverC;
  App.Leds -> LedsC;
}

修复后的发送应用

RadioCountToLedsC.nc(模块代码,修复定时器重复启动)

#include "Timer.h"
#include "RadioCountToLeds.h"

module RadioCountToLedsC @safe() {
  uses {
    interface Leds;
    interface Boot;
    interface AMSend;
    interface Timer<TMilli> as MilliTimer;
    interface SplitControl as AMControl;
    interface Packet;
  }
}

implementation {
  message_t packet;
  bool locked;
  uint16_t counter = 0;

  event void Boot.booted() {
    // 先启动ActiveMessage,成功后再启动定时器
    call AMControl.start();
  }

  event void AMControl.startDone(error_t err) {
    if (err == SUCCESS) {
      call MilliTimer.startPeriodic(250);
    } else {
      call AMControl.start();
    }
  }

  event void AMControl.stopDone(error_t err) {
    // do nothing
  }

  event void MilliTimer.fired() {
    counter = (counter < 100) ? counter + 1 : 0;
    dbg("RadioCountToLedsC", "RadioCountToLedsC: timer fired, counter is %hu.\n", counter);

    if (locked) {
      return;
    }

    radio_count_msg_t* rcm = (radio_count_msg_t*)call Packet.getPayload(&packet, sizeof(radio_count_msg_t));
    if (rcm == NULL) {
      return;
    }

    rcm->counter = counter;
    if (call AMSend.send(AM_BROADCAST_ADDR, &packet, sizeof(radio_count_msg_t)) == SUCCESS) {
      dbg("RadioCountToLedsC", "RadioCountToLedsC: packet sent.\n");
      locked = TRUE;
    }
  }

  event void AMSend.sendDone(message_t* bufPtr, error_t error) {
    if (&packet == bufPtr) {
      locked = FALSE;
    }
  }
}

RadioCountToLedsAppC.nc(配置文件,移除冗余组件)

#include "RadioCountToLeds.h"

configuration RadioCountToLedsAppC {}

implementation {
  components MainC, RadioCountToLedsC as App, LedsC;
  components new AMSenderC(AM_RADIO_COUNT_MSG);
  components new TimerMilliC();
  components ActiveMessageC;

  App.Boot -> MainC.Boot;
  App.AMSend -> AMSenderC;
  App.AMControl -> ActiveMessageC;
  App.Leds -> LedsC;
  App.MilliTimer -> TimerMilliC;
  App.Packet -> AMSenderC;
}

验证步骤

  1. 将修复后的接收应用编译烧录到一台TelosB节点,发送应用编译烧录到另一台节点。
  2. 通电后,发送节点会每隔250ms广播计数值,接收节点收到后会根据计数值模3的结果点亮对应LED:
    • 模3余0:LED0亮
    • 模3余1:LED1亮
    • 模3余2:LED2亮

内容的提问来源于stack exchange,提问作者Qu峄慶 Chí Nguyện

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:04:22