Справка Contiki: Не могу понять поведение переменной

У меня есть следующий код Contiki, где я просто пытаюсь переключить светодиоды на основе переменной «i», которая является нечетной или четной:

while (1) {
    etimer_set(&et, CLOCK_SECOND * 2);
    PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
    i++;
    printf("i is %2d\n",i);
    if ((i % 2) == 0) {
        printf("Now go green.......\n");
        leds_on(LEDS_GREEN);
        leds_off(LEDS_RED);
    } else {
        printf("Reds again.......\n");
        leds_on(LEDS_RED);
        leds_off(LEDS_GREEN);
    }
}

Поведение, когда я запускаю его на CC2650, довольно странное. Он всегда печатает i равно 1. i было объявлено над этим кодом.

Однако, если я помещаю код установки таймера из двух строк в начало цикла, я считаю до конца и не имею проблем. Но в этом случае светодиодные переключатели не видны.

Что мне здесь не хватает?

Пожалуйста помоги


person Venkata Rahul Satuluri    schedule 24.09.2016    source источник


Ответы (1)


Contiki использует протопотоки для реализации процессов. У протопотока нет собственного стека, поэтому функции протопотока не поддерживают должным образом локальные переменные. В частности, вы не можете полагаться на то, что значение локальных переменных сохраняется в точках текучести. И такие макросы, как PROCESS_WAIT_EVENT_UNTIL, могут передать выполнение другому протопотоку, так что это ваша проблема.

Вам нужно объявить i с ключевым словом static, чтобы сохранить его значение во всем теле протопотока. В противном случае вы получите неопределенное поведение.

Например, это плохо:

int i ;
i = 13;
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
printf("i=%d\n", i); // undefined behaviour

Пока это нормально:

int i ;
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
i = 13;
printf("i=%d\n", i); // prints 13

А также это, так как i здесь помещается в один из разделов глобальной памяти:

static int i ;
i = 13;
PROCESS_WAIT_EVENT_UNTIL(etimer_expired(&et));
printf("i=%d\n", i); // prints 13
person kfx    schedule 24.09.2016
comment
Большое спасибо. Ты сделал это! - person Venkata Rahul Satuluri; 24.09.2016