Como projetar um BootLoader para MCU da série STM32?

BootLoader é uma palavra comum para muitas pessoas e é até mesmo usada com frequência. Por exemplo, precisamos dela ao atualizar o sistema online, executando o programa na memória externa. Nesta publicação, apresentaremos como projetar um programa BootLoader para MCU da série STM32.

Princípio básico do BootLoader

Como queremos implementar um programa BootLOader para STM32, primeiro precisamos entender os princípios básicos do programa BootLOader.

Como sabemos, o programa BootLOader deve realizar a orientação do sistema, que é a função básica do programa BootLOader. Para a série MCU STM32, o programa será executado a partir do endereço inicial da memória Flash interna após o sistema ser iniciado. Em seguida, entre no programa aplicativo e execute-o de acordo com a ordem estabelecida. Nesse momento, o BootLoader e o programa aplicativo estão integrados, conforme mostrado na figura:

BootLoader and APP start independently
BootLoader and APP start independently

Mas, às vezes, não queremos que o aplicativo seja executado diretamente, como quando queremos implementar IAP para o sistema; ou não queremos que o aplicativo seja executado em nosso Flash interno; ou o aplicativo é executado no Flash interno, mas queremos que o aplicativo seja executado a partir do endereço Flash interno que especificamos e assim por diante. Nesses casos, precisamos de um programa BootLoader separado. O sistema primeiro inicia o programa BootLoader e entra na execução do programa aplicativo depois que o sistema está pronto, conforme mostrado na figura:

BootLoader and APP run at the same time (APP is stored in internal Flash)
BootLoader and APP run at the same time (APP is stored in internal Flash)

Na imagem acima, armazenamos o aplicativo no local especificado da memória Flash interna, o que, obviamente, atende a algumas de nossas necessidades, como o IAP do sistema. É claro que também podemos armazenar o programa aplicativo na memória Flash externa e, então, o programa BootLoader salta para a memória Flash externa para executar o programa aplicativo, mas a premissa é que a memória Flash externa adquira o programa de execução. O processo específico é o seguinte:

BootLoader and APP run at the same time (APP is stored in external Flash)
BootLoader and APP run at the same time (APP is stored in external Flash)

Claro, isso é só um exemplo, e só precisamos mudar o endereço para memórias diferentes. Quanto às funções a serem implementadas no programa BootLoader, isso depende do uso. Em princípio, podemos adicionar qualquer função que quisermos, como detecção de hardware, atualização do sistema e assim por diante.

Projeto do BootLoader para STM32

Planejamento Rápido

Usamos o STM32F407IGT6 como MCU alvo, que tem 1M de Flash e 192K de SRAM. Dividimos a Flash em duas partes, uma é a área do programa de inicialização (0x0800 0000 – 0x0800 3FFF) com um tamanho de 16K bytes, e o restante é a área do programa aplicativo (0x0800 4000 – 0x080F FFFF). A distribuição específica é a seguinte:

Flash Division of MCU - Bootloader and APP
Flash Division of MCU - Bootloader and APP

Deixamos o programa BootLoader ocupar 16K de espaço de armazenamento. Mas ele pode operar todo o espaço de armazenamento Flash.

Estrutura do BootLoader

Vamos considerar a estrutura do programa BootLoader. O principal objetivo do nosso projeto do programa BootLoader é atualizar o programa aplicativo. Então, quais são as principais funções que precisam ser implementadas no programa BootLoader? Há vários aspectos que devem ser incluídos. Um deles é a configuração básica, como o relógio, etc., que implementamos no programa principal; o outro é a operação do Flash, e definitivamente verificaremos e gravaremos o Flash quando atualizarmos o programa aplicativo; é o programa de controle de salto, precisamos executar o programa aplicativo no final, e a função de salto é essencial. É claro que pode haver outras necessidades de acordo com diferentes requisitos. Especificamente, conforme mostrado na figura abaixo:

BootLoader Program Functions
BootLoader Program Functions

Na figura acima, além das três implementações básicas de assinatura, também adicionamos a função de obtenção de arquivos IAP. Essa parte da função também é necessária, mas pode haver uma grande diferença em diferentes modos. Porque a maneira de obter arquivos pode ser vários tipos de comunicação, como porta Ethernet, porta serial, etc. Também pode ser vários tipos de memória, como cartão SD, disco U e assim por diante. Portanto, embora essa função seja essencial, o método de implementação é muito flexível. Na implementação subsequente, analisaremos questões específicas em detalhes.

Implementação do BootLoader

Agora, determinamos a divisão do Flash e compreendemos o fluxo de trabalho básico do BootLoader. A seguir, discutirei como implementar um programa BootLoader.

Codificação do BootLoader

Sabemos que, quando o chip é ligado, ele executa primeiro o programa BootLoader e, em seguida, salta para a área do programa aplicativo para executar o programa aplicativo. Portanto, quando escrevemos o programa BootLoader, primeiro avaliamos se o sistema tem requisitos IAP. Se houver uma solicitação IAP, ele entrará no modo IAP. Após a conclusão, ele irá para o programa aplicativo para execução. Se não houver solicitação IAP, ele irá diretamente para o programa aplicativo para execução. O processo específico é o seguinte:

Flow Chart of IAP Mode in BootLoader Operation
Flow Chart of IAP Mode in BootLoader Operation

Em relação ao processamento do IAP, haverá diferentes métodos de processamento em diferentes situações. Aqui, vamos dar uma olhada principalmente no programa de controle de salto. Primeiro, defina o primeiro endereço do aplicativo e declare um tipo de ponteiro de função. Detalhes a seguir:

				
					#define ApplicationAddress 0x08004000 //Application first address definition

typedef void (*pFunction)(void); //Define the jump function pointer type
				
			

Algumas pessoas podem perguntar o que define esse tipo de ponteiro de função, porque finalmente saltamos para a função Reset_Handler, então devemos ter um ponteiro de função que possa apontar para essa função. Em seguida, podemos implementar o programa de salto.

				
					/*jump to application processing function*/
static void JumpToApplication(void)
{
   uint32_tStackAddr; //Application stack address
   uint32_tResetVector; //The address of the application interrupt vector table
 
   pFunctionJumpToApp; //Define the jump function pointer
 
  __set_PRIMASK(1); //Turn off global interrupt
 
   StackAddr= *(__IO uint32_t*)ApplicationAddress; //0x08004000;
  ResetVector = *(__IO uint32_t*)(ApplicationAddress + 4); //0x08004004;
 
  if((StackAddr&0x2FFC0000)==0x20000000) //Check whether the stack top address is legal.
   {
    __set_MSP(StackAddr); //Initialize the application stack pointer
 
    JumpToApp = (pFunction)ResetVector;
    JumpToApp();
   }
}
				
			

Processamento de aplicativos

Depois de realizar a codificação do BootLoader, se quisermos saltar para a aplicação para que esta funcione corretamente, precisamos de modificar a aplicação em conformidade. Existem duas alterações importantes. Se a aplicação for um programa bare-metal, precisamos de ativar o midrange global antes de configurar o relógio.

				
					/*Enable global interrupt, closed in BootLoader*/
 __set_PRIMASK(0);
				
			

Ao mesmo tempo, o endereço de deslocamento da tabela de vetores mid-end também precisa ser modificado. Para o STM32F07 que usamos, ele pode ser modificado diretamente no arquivo system_stm32f4xx.c.

				
					#define VECT_TAB_OFFSET  0x4000 /*!< Vector Table base offsetfield.
				
			

Em seguida, também precisamos fazer as modificações necessárias no ambiente de desenvolvimento, tomando como exemplo o IAR EWARM V8.4 que usamos. Modifique as configurações da tabela de vetores de interrupção e da área de armazenamento Flash no arquivo icf. Os detalhes são os seguintes:

Linker configuration file editor - Vector Table
Linker configuration file editor - Vector Table
Linker configuration file editor - Memory Regions
Linker configuration file editor - Memory Regions

Após concluir a configuração acima, podemos baixar o programa aplicativo e o programa BootLoader para realizar o salto correto.

Resumo

Neste artigo, implementamos um programa BootLoader simples. Após o download para o MCU de destino, o salto é realizado e o programa aplicativo também está funcionando normalmente, o que mostra que nosso projeto está correto e várias funções podem ser adicionadas com base nisso para realizar o aplicativo IAP correspondente.

Deve-se observar que desativamos a interrupção global no programa BootLoader e lembrar de ativar a interrupção global antes que o aplicativo inicialize o relógio do sistema, caso contrário, o SystemTick não poderá funcionar e ocorrerá uma falha de hardware (hardfault). No entanto, se o aplicativo estiver sendo executado no RTOS, pode ser errado ativar a interrupção, o que requer atenção.

Compartilhar em:

Rolar para cima

Instant Quote