Опасность спящего режима FreeRTOS при использовании MSP430f5438 - PullRequest
2 голосов
/ 12 марта 2010

Я написал пустой хук, показанный здесь

void vApplicationIdleHook( void )
{
    asm("nop");
    P1OUT &= ~0x01;//go to sleep lights off!
    LPM3;// LPM Mode -  remove to make debug a little easier...
    asm("nop");
}

Это должно привести к выключению светодиода, и MSP430 переходит в спящий режим, когда нечего делать. Я включаю светодиод во время некоторых задач.

Я также удостоверился, что изменил бит режима ожидания в SR при выходе из любого прерывания, которое могло бы разбудить MCU (за исключением тикера планировщика isr в portext.s43. Макрос в iar -

__bic_SR_register_on_exit(LPM3_bits);   // Exit Interrupt as active CPU

Однако, похоже, что перевод MCU в режим сна вызывает нерегулярное поведение. Светодиод остается включенным всегда, хотя, когда я включаю его, он отключается на пару циклов команд, когда я пробуждаю mcu через одно из прерываний (UART), а затем снова включаю. Если я закомментирую инструкцию LPM3, все пойдет по плану. Индикатор не светится большую часть времени и включается только при выполнении задачи.

Я использую MSP4f305438

Есть идеи?

1 Ответ

3 голосов
/ 16 марта 2010

Возможно, проблема в вызове __bic_SR_register_on_exit (LPM3_bits). Этот макрос изменяет биты LPM в стеке SR, поэтому он должен знать, где найти сохраненный SR в стеке. Я считаю, что __bic_SR_register_on_exit () разработан для стандартного фрейма стека прерываний, генерируемого компилятором при использовании директивы __interrupt. Однако вытесняющая RTOS, как FreeRTOS, использует свой собственный кадр стека, обычно больше, чем кадр стека, сгенерированный компилятором, поскольку RTOS должна хранить полный контекст. В этом случае __bic_SR_register_on_exit (), вызываемый из ISR, может , а не найти SR в стеке. Хуже того, это может повредить некоторые другие сохраненные значения регистра в стеке.

Для упреждающего ядра я бы не вызывал __bic_SR_register_on_exit () из ISR. Следствием этого является то, что обратный вызов в режиме ожидания вызывается только один раз и никогда больше, потому что каждый раз, когда RTOS выполняет переключение контекста обратно к задаче ожидания, побочным эффектом является восстановление SR с включенными битами LPM. Это вызывает спящий режим (что вам и нужно), но ваш светодиод не будет переключаться.

Миро Самек state-machine.com

...