STM32F4xx bootloader & interrupts

3

Estoy tratando de escribir un gestor de arranque para un STM32F4xx (actualmente para la placa de descubrimiento STM32F429). Mi aplicación debe comenzar en la dirección 0x08020000 mientras que el cargador de arranque se inicia en 0x08000000 (inicio de flash).

Creé la aplicación con CubeMX, cambié el ORIGEN FLASH en el archivo del vinculador a 0x08020000 y el VECT_TAB_OFFSET a 0x20000 en el archivo system_stm32f4xx.c (esto cambia el VTOR a 0x08020000). Mi aplicación solo parpadea un LED y funciona como se esperaba en esta nueva dirección cuando se inicia desde el IDE.

while(true) {
    HAL_Delay(200);
    HAL_GPIO_TogglePin(GPIOG, GPIO_PIN_13);
}

En lugar de escribir el gestor de arranque inmediatamente (en realidad lo hice y no funcionó) usé la utilidad ST-Link e hice algunas cosas: verifiqué que todo, junto con la aplicación, se borró (0xff). Reajusté la CPU y configuré manualmente la PC a 0x08021924 (este es el Reset_Handler según el archivo de mapas de la aplicación). Cuando paso lentamente por la aplicación, puedo ver lo siguiente: El SP está escrito correctamente (ya que es parte del código del ensamblador de inicio de CubeMX). El VTOR está configurado correctamente a 0x08020000 (leí el SCB manualmente en la dirección 0xE000ED00, el tercer valor es el VTOR) y después de un tiempo la aplicación se repite dentro de HAL_GetTick & Función HAL_Delay (leí el PC y lo comparé con el archivo de mapa). Incluso veo que la aplicación lee el uwTick (en la dirección 0x20000020 en mi caso), que nunca se incrementa, y por lo tanto, HAL_Delay se desactiva para siempre. así que mi conclusión es:

Las interrupciones parecen no funcionar correctamente

en este caso, el SysTick ... A pesar de un VTOR correcto y la aplicación parece funcionar bien. Cuando sustituyo HAL_Delay con un Busy_Delay (que solo consiste en un bucle de millones de NOP), el LED parpadea. Cuando lo inicio manualmente a través del método mencionado (o un gestor de arranque escrito manualmente con saltos a la dirección correcta), la aplicación se ejecuta normalmente (porque es muy probable que nada dependa de interrupciones en este breve ejemplo).

¿Qué me falta para escribir un gestor de arranque que funcione (con interrupciones de trabajo)?

    
pregunta Freya Thor

1 respuesta

2

Creo que encontré un eslabón perdido.

En lugar de saltar al Reset_Handler en sí, el salto a Reset_Handler + 1 ayuda. Esto establece el LSB en 1 y da una indicación de que es un código de pulgar. Para los manejadores de IRQ, está documentado en el Centro de información ARM / a>.

La mayoría (si no todos) los saltos en el código generado desde C tienen un LSB 0 de cero (y las interrupciones aún funcionan), no entiendo por qué es necesario configurar el LSB en mi caso. Quizás: Normalmente, los saltos son relativos (pero dentro del depurador se traducen en direcciones con un LSB de 0), pero el salto al cargador de arranque es una dirección que se carga primero con un registro y que también se salta.

    
respondido por el Freya Thor

Lea otras preguntas en las etiquetas