Contiki帮助:无法理解变量行为

Contiki help: Cannot understand the variable behavior

我有以下 Contiki 代码,我只是试图根据变量 'i' 是奇数还是偶数来切换 LED:

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。我已在这段代码上方声明。

但是,如果我在循环的开头放置两行定时器设置代码,我会一直计数并且没有问题。但在那种情况下,无法看到 LED 开关。

我在这里错过了什么?

请帮忙

Contiki 使用 protothreads 来实现流程。 protothread 没有自己的堆栈,因此 protothread 函数不能正确支持局部变量。特别是,您不能依赖在屈服点之间保留的局部变量的值。 PROCESS_WAIT_EVENT_UNTIL 等宏可能会将执行交给另一个原线程,所以这就是你的问题。

您需要使用关键字 static 声明 i 以在整个 protothread 主体中保留其值。否则你会得到未定义的行为。

例如,这是不好的:

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