Получать и отправлять в Tinyos - PullRequest
0 голосов
/ 24 мая 2018

У меня есть программа связи между двумя телосбами.Это пример tinyos: https://github.com/tinyos/tinyos-release/tree/tinyos-2_1_2/apps/RadioCountToLeds. Этот код будет отправлять и получать счетчик значений, при выполнении условий включается соответствующий светодиод.Я хочу разделить код на 2 части: отправить и получить.И я создаю 2 приложения: Получить:

//RadioCountToLedC.nc
#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) {
    call Leds.led0On();
    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;
      if (rcm->counter%3 == 0) {
    call Leds.led0On();
      }
      else {
    call Leds.led0Off();
      }
      if (rcm->counter%3 == 1) {
    call Leds.led1On();
      }
      else {
    call Leds.led1Off();
      }
      if (rcm->counter%3 == 2) {
    call Leds.led2On();
      }
      else {
    call Leds.led2Off();
      }
      return bufPtr;
    }
  }

}


   //RadioToLedAppC.nc
    #include "RadioCountToLeds.h"

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

  }

Отправить:

//RadioCountToLedC.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() {
    call MilliTimer.startPeriodic(250);
    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() {
    if(counter<100){
       counter++;
    }else{
       counter=0;
    }
    dbg("RadioCountToLedsC", "RadioCountToLedsC: timer fired, counter is %hu.\n", counter);
    if (locked) {
      return;
    }
    else {
      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", counter); 
    locked = TRUE;
      }
    }
  }

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

}
//RadioToLedAppC.nc

    #include "RadioCountToLeds.h"

    configuration RadioCountToLedsAppC {}
    implementation {
      components MainC, RadioCountToLedsC as App, LedsC;
      components new AMSenderC(AM_RADIO_COUNT_MSG);
      components new AMReceiverC(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;
    }

RadioCountToLed.h

#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

Но когда я запускаю, это не работает.Если я напишу Получить и Отправить в том же файле RadioCountToLedC.nc, как в примере выше.Это будет хорошо работать.Что не так с моим приложением?

Ответы [ 2 ]

0 голосов
/ 19 июля 2018

Существует несколько простых способов решения этой проблемы. Самый простой способ - это просто иметь переменную, которая управляет потоком программы, или альтернативно использовать каждый узел TinyOS ID для управления потоком.

Например, вы могли бы иметь (было сделано только 4 небольших изменения):

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

/**
 * Implementation of the RadioCountToLeds application. RadioCountToLeds 
 * maintains a 4Hz counter, broadcasting its value in an AM packet 
 * every time it gets updated. A RadioCountToLeds node that hears a counter 
 * displays the bottom three bits on its LEDs. This application is a useful 
 * test to show that basic AM communication and timers work.
 *
 * @author Philip Levis
 * @date   June 6 2005
 */

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

  message_t packet;

  bool locked;
  uint16_t counter = 0;

  enum state {TX, RX} mode; //Change 1: Define States

  event void Boot.booted() {
    call AMControl.start();
    mode = RX; // CHANGE 2: Set States - "RX" for receiver & "TX" for transmitter
  }

  event void AMControl.startDone(error_t err) {
    if (err == SUCCESS) {
      if(mode == TX) //CHANGE 3: Only the transmitter sends
          call MilliTimer.startPeriodic(250);
    }
    else {
      call AMControl.start();
    }
  }

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

  event void MilliTimer.fired() {
    counter++;
    dbg("RadioCountToLedsC", "RadioCountToLedsC: timer fired, counter is %hu.\n", counter);
    if (locked) {
      return;
    }
    else {
      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", counter); 
    locked = TRUE;
      }
    }
  }

  event message_t* Receive.receive(message_t* bufPtr, 
                   void* payload, uint8_t len) {
    dbg("RadioCountToLedsC", "Received packet of length %hhu.\n", len);

    if(mode == TX) return bufPtr; //CHANGE 4: Only RX processes packets

    if (len != sizeof(radio_count_msg_t)) {return bufPtr;}
    else {
      radio_count_msg_t* rcm = (radio_count_msg_t*)payload;
      if (rcm->counter & 0x1) {
    call Leds.led0On();
      }
      else {
    call Leds.led0Off();
      }
      if (rcm->counter & 0x2) {
    call Leds.led1On();
      }
      else {
    call Leds.led1Off();
      }
      if (rcm->counter & 0x4) {
    call Leds.led2On();
      }
      else {
    call Leds.led2Off();
      }
      return bufPtr;
    }
  }

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

}

Вместо установки режима в событии Booted, вы можете альтернативно использовать препроцессор C для установкиmode переменная, если хотите.

Проблема с приложением получателя, которое вы сделали, состоит в том, что оно

i) не запускает трансивер, так как оно не вызывает AMControl.start() в Boot.Booted() событие.

ii) Неправильное подключение в RadioCountToLedsAppC, так как интерфейсы не подключены.Вам необходимо подключить все интерфейсы (Boot, Leds, Receive и AMControl).Подобно тому, как вы подключили их в отправителе.

0 голосов
/ 24 мая 2018

Я думаю, вам нужно

call AMControl.start();

в вашей загруженной функции вашего приемника.Это включит радио и позволит вам получать сообщения.

PS Если это не полностью решит вашу проблему, пожалуйста, предоставьте более подробную информацию о том, что вы наблюдаете во время бега.

...