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.