Избегайте состояния гонки при проверке, а затем спать - PullRequest
1 голос
/ 24 марта 2020

Возьмем следующий пример кода:

static volatile bool pending = false;

void __attribute__((interrupt(TIMER0_A0_VECTOR))) TIMER0_A0_ISR (void)
{
    pending = true;        
}

int main(void)
{
    while(true) {
        if (!pending)
            sleep();
        pending = false;
        // do stuff
    }
}

Предположим, что функция ожидания переводит оборудование в спящий режим, а прерывание вызывает аппаратные средства, так что функция ожидания возвращается сразу после прерывания.

Здесь есть условие гонки: если прерывание происходит после оператора if, но перед сном, мы спим до следующего прерывания. Это проблема в моем реальном аналоге этого кода. Как я могу избежать этой проблемы?

Я работаю с msp430g2433.

1 Ответ

2 голосов
/ 24 марта 2020

Чтобы убедиться, что проверка и переход в спящий режим выполняются атомарно, вы должны отключить прерывания вокруг них. Это также требует, чтобы вы go одновременно спали и снова включали прерывания, но на MSP430 это легко сделать: логи c яснее:

while (true) {
    int status_bits = GIE;
    _bic_SR_register(status_bits); // disable interrupts
    if (!pending)
        status_bits |= LPM1_bits;
    _bis_SR_register(status_bits); // enable interrupts, go to sleep if needed

    pending = false;
    // do stuff
}
...