Hoy en día, cada vez más dispositivos integrados admiten actualizaciones automáticas remotas sin necesidad de descargadores, lo que hace que el mantenimiento de los dispositivos sea muy cómodo. Para habilitar las actualizaciones remotas de un dispositivo, necesitamos escribir un código de programa que admita el proceso de actualización. Este programa se conoce comúnmente como BootLoader.
En esencia, el código del programa del dispositivo se divide en dos partes: el BootLoader y la APP. El BootLoader se encarga de actualizar la APP e iniciar su ejecución. La APP, por su parte, se encarga de implementar las funciones operativas del dispositivo, albergando esencialmente la funcionalidad central del mismo.
En el caso de los microcontroladores de la serie Cortex-M, para lograr una transición segura del BootLoader a la APP se requieren ciertas configuraciones. Este artículo toma como ejemplo los microcontroladores STM32 para describir los pasos de configuración clave necesarios para implementar una transición satisfactoria del BootLoader a la APP.
BootLoader Saltar a la aplicación
Paso 1: Partición Flash
Durante la fase de programación y diseño, es importante particionar la memoria Flash en función de los requisitos específicos de la aplicación. Esto implica determinar dónde se almacenarán el BootLoader y la APP, así como el espacio asignado a cada uno. La ubicación del almacenamiento afecta directamente a la ejecución y las transiciones del programa.
Una de las estrategias de actualización más sencillas consiste en disponer de un BootLoader y una APP. El BootLoader se encarga de las transiciones y facilita las actualizaciones de la APP. Este artículo utiliza esta estrategia de actualización como ejemplo para la explicación.
Para los microcontroladores STM32, la dirección asignada para el inicio del programa es 0x8000000.
El BootLoader se puede almacenar en la dirección 0x8000000, y el espacio asignado se puede ajustar en función del tamaño específico de la memoria Flash del chip, por ejemplo, 0x10000 o 64 KB.
La dirección de almacenamiento de la aplicación se coloca después del BootLoader, concretamente en la dirección 0x8010000. El espacio restante en la memoria Flash se puede asignar a la aplicación.
Paso 2: Configuración del proyecto BootLoader
La configuración del proyecto BootLoader implica varios pasos. Utilizando MDK como ejemplo, el programa BootLoader se almacena en la memoria FLASH en la dirección 0x8000000 con un tamaño de 0x10000.

Al realizar la transición a la aplicación utilizando código de programa, tenga en cuenta los siguientes puntos:
- Verifique la validez de la dirección superior de la pila, es decir, si la dirección de inicio de la aplicación es válida.
if(((*(__IO uint32_t *)APP_FLASH_ADDR) & 0x2FFE0000) == 0x20000000)
- Desactive todas las interrupciones para evitar perturbaciones durante la transición que podrían provocar excepciones.
- Obtenga la dirección de inicio del programa APP, que se almacena como la segunda palabra (dirección de inicio + 4, datos almacenados en Flash).
- Inicialice el puntero de pila (la primera palabra del área de código de usuario contiene la dirección superior de la pila).
- Convierta la dirección inicial de la APP en un tipo de puntero de función y realice la transición.
El código específico para la transición es el siguiente:
/* Define type */
typedef void (*pFunction)(void);
/* APP flash address */
#define APP_FLASH_ADDR (0x8010000)
void jump_to_app(void)
{
uint32_t JumpAddress;
pFunction Jump_To_Application;
/* Check if the stack top address is valid */
if(((*(__IO uint32_t *)APP_FLASH_ADDR) & 0x2FFE0000) == 0x20000000)
{
/* Disable all interrupts to prevent disturbances during transition */
__disable_irq();
/* The second word in the user code area is the program's start address (reset address) */
JumpAddress = *(__IO uint32_t *) (APP_FLASH_ADDR + 4);
/* Initialize the user application's Stack Pointer */
__set_MSP(*(__IO uint32_t *) APP_FLASH_ADDR);
/* Type conversion */
Jump_To_Application = (pFunction) JumpAddress;
/* Transition to the APP */
Jump_To_Application();
}
}
Paso 3: Configuración del proyecto APP
Del mismo modo, el proyecto APP requiere ciertas configuraciones. Utilizando MDK como ejemplo, el programa APP se almacena en la memoria FLASH en la dirección 0x8010000 con un tamaño de 0x30000.

La configuración del programa APP implica los siguientes pasos:
- Reubicar la tabla de vectores Flash interna en la APP modificando SCB->VTOR.
- Una vez que la APP comienza a ejecutarse, es esencial habilitar las interrupciones en la función de inicialización para garantizar una ejecución fluida del programa. De lo contrario, podrían producirse anomalías en el programa.
Normalmente, en el archivo de inicio se llama a la función SystemInit(). Esta función configura la información de la interfaz de la memoria Flash.
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET

Modifique el valor de la definición de macro VECT_TAB_OFFSET a 0x10000.

Una vez iniciado el programa APP, es fundamental habilitar las interrupciones globales. Puede colocar el siguiente código en la sección de inicialización:
/* Enable interrupts */
__enable_irq();
APP Saltar al BootLoader
Durante el funcionamiento del dispositivo, la aplicación está ejecutándose y procesando funciones comerciales. Si desea actualizar la aplicación, debe cambiar de la aplicación al BootLoader. Entonces, ¿cómo se realiza el salto de la aplicación al BootLoader? Hay dos métodos:
- Modo hardware, apagar el dispositivo y reiniciarlo o pulsar el botón de reinicio
- Modo de software: restablecer la MCU mediante control de software
En el modo de software, se pueden añadir comandos de control al código de la aplicación y, cuando la aplicación recibe el comando de salto (o comando de actualización), se reiniciará la MCU. El siguiente código puede reiniciar la MCU:
/* reset chip */
HAL_NVIC_SystemReset();




