Я нашел проблему: радиоприемник не выключен должным образом после передачи пакета.
В конце функции 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;
}
Потребление тока во время передачи пакета выглядит как сейчас:
Примечание: время строба был уменьшен намеренно 10ms с:
#define STROBE_TIME RTIMER_ARCH_SECOND/100
Эта объясните, почему существует только три строба передачи для широковещательного сообщения.
Продолжительность строба составляет 3 мс. Это означает, что скорость передачи данных составляет ~ 140 кбит/с (?).
Благодарим за ваше полное описание. Я уже подозревал, что проверка CCA на 8 Гц, потому что продолжительность 250 мс - это двойной период. Кажется, что радио не выключено должным образом, и ему нужно дождаться следующей проверки радио, прежде чем повторять попытку. –