2014-10-03 5 views
2

Может ли кто-нибудь объяснить мне, что происходит внутри Contiki-OS, когда он передает пакет UDP?Contiki UDP длительность передачи пакета с CC2538

Вот текущее потребление моего устройства в деталях работает с чипом CC2538:

CC2538 Current consumption

Мой вопрос: почему это занимает так много времени, чтобы передать UDP широковещательный пакет (около 250 мс), зная, что теоретически при скорости 250 кбит/с пакет длиной 408 бит должен быть передан примерно в 2 мс? Я бы понял, если последняя передача скажет десять миллисекунд, но здесь разница огромна.

Я использую пример в contiki/examples/ipv6/simple-udp-rpl/broadcast-example.c

Кто-нибудь есть идеи?

ответ

1

Я нашел проблему: радиоприемник не выключен должным образом после передачи пакета.

В конце функции transmit() в файле cpu/cc2538/dev/cc2538-rf.c радио выключено, только если оно было ранее выключено.

if(rf_flags & WAS_OFF) { 
    rf_flags &= ~WAS_OFF; 
    off(); 
} 

Но на самом деле программа никогда не переходит в это состояние, и радио не отключается сразу же после передачи пакета.

Проблема возникает из-за того, что функция channel_clear() (называемая в начале функции transmit()) сначала очищает этот флаг. Таким образом, функция transmit() больше не знает, что радио было выключено перед его исполнением, и поэтому радио продолжает работу.

Чтобы устранить проблему, я установил локальную переменную внутри channel_clear(), которая отключает радио и очищает флаг только в том случае, если он включен внутри самой функции.

static int 
channel_clear(void) 
{ 
    int cca; 
    /* Fix: local variable */ 
    uint8_t intern_onoff; 

    intern_onoff = 0; 

    PRINTF("RF: CCA\n"); 

    /* If we are off, turn on first */ 
    if((REG(RFCORE_XREG_FSMSTAT0) & RFCORE_XREG_FSMSTAT0_FSM_FFCTRL_STATE) == 0) { 
    rf_flags |= WAS_OFF; 
    on(); 
    intern_onoff = 1; 
    } 

    /* Wait on RSSI_VALID */ 
    while((REG(RFCORE_XREG_RSSISTAT) & RFCORE_XREG_RSSISTAT_RSSI_VALID) == 0); 

    if(REG(RFCORE_XREG_FSMSTAT1) & RFCORE_XREG_FSMSTAT1_CCA) { 
    cca = CC2538_RF_CCA_CLEAR; 
    } else { 
    cca = CC2538_RF_CCA_BUSY; 
    } 

    /* If we were off, turn back off */ 
    if((rf_flags & WAS_OFF) == WAS_OFF && intern_onoff) { 
    rf_flags &= ~WAS_OFF; 
    off(); 
    intern_onoff = 0; 
    } 

    return cca; 
} 

Потребление тока во время передачи пакета выглядит как сейчас:

Current consumption of contiki-os when UDB transmission

Примечание: время строба был уменьшен намеренно 10ms с:

#define STROBE_TIME      RTIMER_ARCH_SECOND/100 

Эта объясните, почему существует только три строба передачи для широковещательного сообщения.

Продолжительность строба составляет 3 мс. Это означает, что скорость передачи данных составляет ~ 140 кбит/с (?).

2

По умолчанию Contiki использует протокол перехода на радиостанцию ​​ContikiMAC (RDC). Протокол должен иметь дело с двумя противоречивыми требованиями: позволить приемным узлам спать почти все время, когда нет пакетов для приема, но в то же время позволяют максимально надежно передавать данные. Решение, принятое в ContikiMAC, должно наложить нагрузку на передатчик. Учитывая, что приемник проверяет радиоканал 8 раз в секунду (конфигурация по умолчанию на платформе cc2538dk), передатчик должен передавать длительностью не менее 125 мс, чтобы убедиться, что приемник проснулся и увидел пакет. На практике это означает, что пакет повторно передается несколько раз подряд. См. ContikiMAC paper и Contiki documentation для более подробного описания.

При этом вы не всегда будете видеть передачи с максимальной продолжительностью. Если его одноадресная передача, приемник обычно отправляет ACK после успешного приема. Передатчик проверяет этот ACK и прекращает передачу, если получен. Таким образом, ожидаемое среднее количество требуемых передач уменьшается в два раза. И тогда есть также Phase Optimization - он позволяет отправителю синхронизировать начало передачи с ожидаемым временем пробуждения приемника. Но для трансляций не генерируются ACK, и оптимизация фазы не работает.

Еще одна возможная причина для неожиданно длинных передач - это отказ от проверки CCA. Перед передачей пакета радиокассета сначала проверяет, свободен ли носитель; если это не так, он будет поддерживать некоторое время и повторять попытку.

+0

Благодарим за ваше полное описание. Я уже подозревал, что проверка CCA на 8 Гц, потому что продолжительность 250 мс - это двойной период. Кажется, что радио не выключено должным образом, и ему нужно дождаться следующей проверки радио, прежде чем повторять попытку. –