Atualmente, cada vez mais dispositivos incorporados suportam atualizações automáticas remotas sem a necessidade de downloaders, tornando a manutenção dos dispositivos altamente conveniente. Para habilitar atualizações remotas para um dispositivo, precisamos escrever um código de programa que suporte o processo de atualização. Esse programa é comumente chamado de BootLoader.
Essencialmente, o código do programa do dispositivo é dividido em duas partes: o BootLoader e o APP. O BootLoader é responsável por atualizar o APP e iniciar sua execução. O APP, por outro lado, é responsável por implementar as funções operacionais do dispositivo, essencialmente abrigando a funcionalidade central do dispositivo.
Para microcontroladores da série Cortex-M, a transição segura do BootLoader para o APP requer determinadas configurações. Este artigo usa os microcontroladores STM32 como exemplo para descrever as principais etapas de configuração necessárias para implementar uma transição bem-sucedida do BootLoader para o APP.
BootLoader Ir para o aplicativo
Passo 1: Partição Flash
Durante a fase de programação e design, é importante particionar a memória Flash com base nos requisitos específicos da aplicação. Isso envolve determinar onde o BootLoader e o APP serão armazenados, bem como o espaço alocado para cada um. Essa localização de armazenamento afeta diretamente a execução e as transições do programa.
Uma das estratégias de atualização mais simples envolve ter um BootLoader e um APP. O BootLoader lida com as transições e facilita as atualizações do APP. Este artigo usa essa estratégia de atualização como exemplo para explicação.
Para microcontroladores STM32, o endereço mapeado para a inicialização do programa é 0x8000000.
O BootLoader pode ser armazenado no endereço 0x8000000, e o espaço alocado pode ser ajustado com base no tamanho específico do Flash do chip, por exemplo, 0x10000 ou 64 KB.
O endereço de armazenamento do APP é colocado após o BootLoader, especificamente no endereço 0x8010000. O espaço restante na Flash pode ser alocado para o APP.
Passo 2: Configuração do projeto BootLoader
A configuração do projeto BootLoader envolve algumas etapas. Usando o MDK como exemplo, o programa BootLoader é armazenado na memória FLASH no endereço 0x8000000 com um tamanho de 0x10000.

Ao fazer a transição para o APP usando código de programa, considere os seguintes pontos:
- Verifique a validade do endereço superior da pilha, ou seja, se o endereço inicial do APP é válido.
if(((*(__IO uint32_t *)APP_FLASH_ADDR) & 0x2FFE0000) == 0x20000000)
- Desative todas as interrupções para evitar perturbações durante a transição que possam levar a exceções.
- Obtenha o endereço inicial do programa APP, que é armazenado como a segunda palavra (endereço inicial + 4, dados armazenados na Flash).
- Inicialize o ponteiro da pilha (a primeira palavra na área do código do usuário contém o endereço superior da pilha).
- Converta o endereço inicial do APP em um tipo de ponteiro de função e execute a transição.
O código específico para a transição é o seguinte:
/* 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();
}
}
Etapa 3: Configuração do projeto APP
Da mesma forma, o projeto APP requer determinadas configurações. Usando o MDK como exemplo, o programa APP é armazenado na memória FLASH no endereço 0x8010000 com um tamanho de 0x30000.

A configuração do programa APP envolve as seguintes etapas:
- Relocalize a tabela vetorial Flash interna no APP modificando SCB->VTOR.
- Após o APP começar a ser executado, é essencial habilitar as interrupções na função de inicialização para garantir a execução suave do programa. Não fazer isso pode levar a anomalias no programa.
Normalmente, no arquivo de inicialização, a função SystemInit() é chamada. Essa função configura as informações de interface do Flash.
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET

Modifique o valor da definição da macro VECT_TAB_OFFSET para 0x10000.

Após o início do programa APP, é fundamental habilitar as interrupções globais. Você pode colocar o seguinte código na seção de inicialização:
/* Enable interrupts */
__enable_irq();
APP Saltar para o BootLoader
Durante o funcionamento do dispositivo, o APP está em execução e processando funções comerciais. Se você deseja atualizar o APP, é necessário alternar do APP para o BootLoader. Então, como fazer o APP saltar para o BootLoader? Existem dois métodos:
- Modo de hardware, desligar o dispositivo e reiniciar ou pressionar o botão de reinicialização
- Modo de software, reinicializar o MCU através do controle de software
No modo de software, os comandos de controle podem ser adicionados ao código do APP e, quando o APP recebe o comando de salto (ou comando de atualização), o MCU será reiniciado. O código a seguir pode reiniciar o MCU:
/* reset chip */
HAL_NVIC_SystemReset();




