7 votos

STM32 Modo de suspensión: Interrupción se ejecuta pero la CPU permanece en WFI

Soy bastante nuevo en la arquitectura ARM y estoy trabajando con una tabla que contiene STM32F0 microcontrolador y un módem de RF, el cual envía una interrupción cada vez que recibe un mensaje. Estoy tratando de implementar un modo de sueño en un microcontrolador para ahorrar energía, pero no acabo de entender por qué se comporta de la manera que lo hace.

Empecé con un simple programa que te pone la CPU en modo de suspensión en el inicio de la ejecución. A continuación, espera a que la externa de interrupción para despertarlo, ejecutar la interrupción y continuar con el programa principal. En el ISR puedo cambiar un LED en el pin PA0 cada vez que se llama a la rutina, pero luego usar el pin PA1 en el main() que se activa o desactiva y el LED de encendido y apagado con un breve retraso, lo que indica que el microcontrolador sale del modo de suspensión.

Mi código, básicamente, se parece a esto:

int main()
{
    periph_init();
    modem_init();

    HAL_PWR_EnterSLEEPMode(0,1);

    while(1)
    {
        HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_1);
        Delay();
    }
}

Y el ISR por la EXTI

void EXTI0_1_IRQHandler(void)
{
    HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_0);

    // Some other stuff

    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);
}

Los binarios armv6 Arquitectura Manual de Referencia indica lo siguiente con respecto a la Espera De la Interrupción en la página B1-243:

Cuando un procesador emite un WFI la instrucción de suspender la ejecución y entrar en un estado de baja potencia. Puede permanecer en ese estado hasta que el procesador detecta una de las siguientes WFI de despertador eventos:

  • Un reset.

  • Asíncrono de excepción en una prioridad que, si PRIMASK.La PM se establece en 0, sería adelantarse a cualquier activo actualmente excepciones.

  • Si la depuración está habilitada, un evento de depuración.

  • Una APLICACIÓN DEFINIDA WFI activación de eventos.

Si mi interpretación es correcta, la segunda línea se aplica en este caso. Lo que significa, que la llamada a cualquier interrupción independientemente de su prioridad despertaba el procesador, ya que el WFI llamaron de la principal. Para información, todas las medidas de interrupción de prioridades se establece en 0, excepto para la EXTI, que se establece en -1.

Ahora bien, esto es lo que en realidad sucede. El LED en PA0 alterna de forma adecuada, lo que indica que el ISR efectivamente ejecutar. Pero el LED en PA1 permanece apagado, lo que significa que al finalizar el ISR, la CPU permanece en un WFI. Esto es confirmado incluso durante la depuración, mientras que insertar un breakpoint en la rutina de servicio de interrupción. Después de dejar que el código se ejecute, con éxito se detiene en el breakpoint. Si puedo continuar la depuración con un paso a paso de la función, el programa salta a la WFI instrucción (en la que sigue a la principal, ya que la depuración puede causar a terminar el WFI).

Mi pregunta es, ¿por qué la CPU volver a la WFI cuando la interrupción claramente se llama? Dado a mi entender, si la CPU está en WFI, se debe continuar con esta operación donde lo dejó tan pronto como cualquier interrupción llamado.

8voto

berendi Puntos 316

Compruebe si el SLEEPONEXIT bits en SCB->SCR está configurado. Establecer que para el 1 de haría exactamente lo que he descrito:

Bit 1 SLEEPONEXIT

Configura el sueño-en-salida al regresar de Controlador el modo a modo de Subproceso. Se establece este bit a 1 habilita una interrupción impulsado por aplicación para evitar regresar a un vacío de la aplicación principal.

0: no dormir cuando regresan a modo de Subproceso.

1: Entrar en el sueño, o el sueño profundo, en regreso de una rutina de servicio de interrupción.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X