Come progettare un BootLoader per MCU della serie STM32?

BootLoader è una parola comune per molte persone e viene persino utilizzata frequentemente. Ad esempio, ne abbiamo bisogno quando aggiorniamo il sistema online, eseguendo il programma nella memoria esterna. In questo post, introdurremo come progettare un programma BootLoader per MCU della serie STM32.

Principio base di BootLoader

Dato che vogliamo implementare un programma BootLOader per STM32, dobbiamo prima comprendere i principi base del programma BootLOader.

Come sappiamo, il programma BootLOader deve realizzare la guida del sistema, che è la funzione base del programma BootLOader. Per l’MCU della serie STM32, il programma verrà eseguito dall’indirizzo di partenza della memoria Flash interna dopo l’avvio del sistema. Quindi entra nel programma applicativo e lo esegue in base all’ordine stabilito. In questo momento, il BootLoader e il programma applicativo sono integrati, come mostrato nella figura:

BootLoader and APP start independently
BootLoader and APP start independently

Ma a volte, non vogliamo che l’applicazione venga eseguita direttamente, ad esempio quando vogliamo implementare IAP per il sistema; o non vogliamo che l’applicazione venga eseguita nella nostra Flash interna; o l’applicazione viene eseguita nella Flash interna, ma vogliamo che l’applicazione venga eseguita dall’indirizzo Flash interno che specifichiamo e così via. In questi casi abbiamo bisogno di un programma BootLoader separato. Il sistema avvia prima il programma BootLoader, e entra nell’esecuzione del programma applicativo dopo che il sistema è pronto, come mostrato nella 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)

Nell’immagine sopra, memorizziamo effettivamente l’applicazione nella posizione specificata della Flash interna, il che ovviamente serve a soddisfare alcune delle nostre esigenze, come l’IAP di sistema. Naturalmente, possiamo anche memorizzare il programma applicativo nella Flash esterna, quindi il programma BootLoader salta alla Flash esterna per eseguire il programma applicativo, ma il presupposto è che la Flash esterna acquisti il programma di esecuzione. Il processo specifico è il seguente:

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)

Naturalmente, questo è solo un esempio, e dobbiamo solo modificare l’indirizzo per memorie diverse. Per quanto riguarda le funzioni da implementare nel programma BootLoader, dipende dall’utilizzo. In linea di principio, possiamo aggiungere qualsiasi funzione desideriamo, come il rilevamento hardware, l’aggiornamento del sistema e così via.

Progettazione di BootLoader per STM32

Pianificazione Flash

Utilizziamo STM32F407IGT6 come MCU di destinazione, che ha 1M Flash e 192K SRAM. Dividiamo la Flash in due parti, una è l’area del programma di avvio (0x0800 0000 – 0x0800 3FFF) con una dimensione di 16K Byte, e il resto è l’area del programma applicativo (0x0800 4000 – 0x080F FFFF). La distribuzione specifica è la seguente:

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

Facciamo occupare 16K di spazio di archiviazione al programma BootLoader. Ma può operare sull’intero spazio di archiviazione Flash.

Struttura BootLoader

Consideriamo la struttura del programma BootLoader. Lo scopo principale della nostra progettazione del programma BootLoader è aggiornare il programma applicativo. Quindi quali sono le funzioni principali che devono essere implementate nel programma BootLoader? Ci sono diversi aspetti che devono essere inclusi. Uno è la configurazione di base, come il clock, ecc., che implementiamo nel programma principale; l’altro è il funzionamento della Flash, e controlleremo e scriveremo sicuramente la Flash quando aggiorniamo il programma applicativo; È il programma di controllo del salto, dobbiamo eseguire il programma applicativo alla fine, e la funzione di salto è essenziale. Naturalmente, potrebbero esserci altre esigenze in base a esigenze diverse. Specificamente come mostrato nella figura seguente:

BootLoader Program Functions
BootLoader Program Functions

Nella figura sopra, oltre alle tre implementazioni di base della firma, abbiamo aggiunto anche la funzione di ottenimento dei file IAP. Questa parte della funzione è necessaria, ma potrebbe esserci una grande differenza in diverse modalità. Poiché il modo di ottenere i file può essere vari tipi di comunicazione come porta Ethernet, porta seriale, ecc. Può anche essere vari tipi di memoria, come scheda SD, disco U, ecc. Pertanto, sebbene questa funzione sia essenziale, il metodo di implementazione è molto flessibile. Nell’implementazione successiva, analizzeremo i problemi specifici in dettaglio.

Implementazione di BootLoader

Ora, abbiamo determinato la divisione di Flash e compreso il flusso di lavoro di base di BootLoader. Successivamente, discuterò come implementare un programma BootLoader.

Codifica di BootLoader

Sappiamo che quando il chip viene acceso, esegue prima il programma BootLoader, quindi salta all’area del programma applicativo per eseguire il programma applicativo. Pertanto, quando scriviamo il programma BootLoader, giudichiamo prima se il sistema ha requisiti IAP. Se c’è una richiesta IAP, entrerà in modalità IAP. Al termine, salterà al programma applicativo per l’esecuzione. Se non c’è una richiesta IAP, salterà direttamente al programma applicativo per l’esecuzione. Il processo specifico è il seguente:

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

Per quanto riguarda l’elaborazione di IAP, ci saranno diversi metodi di elaborazione in diverse situazioni. Qui vediamo principalmente il programma di controllo del salto. Innanzitutto, definire il primo indirizzo dell’applicazione e dichiarare un tipo di puntatore a funzione. dettagli come segue:

				
					#define ApplicationAddress 0x08004000 //Application first address definition

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

Alcune persone potrebbero chiedere cosa definisce un tale tipo di puntatore a funzione, perché alla fine saltiamo alla funzione Reset_Handler, quindi dobbiamo avere un puntatore a funzione che possa puntare a questa funzione. Successivamente, possiamo implementare il programma di 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();
   }
}
				
			

Elaborazione App

Dopo aver realizzato la codifica di BootLoader, se vogliamo saltare all’App per l’esecuzione corretta, dobbiamo modificare di conseguenza l’App. Ci sono 2 modifiche importanti. Se l’applicazione è un programma bare-metal, dobbiamo abilitare l’intervallo globale prima di configurare il clock.

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

Allo stesso tempo, è necessario modificare anche l’indirizzo di offset della tabella vettoriale di mid-end. Per lo STM32F07 che utilizziamo, può essere modificato direttamente nel file system_stm32f4xx.c.

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

Quindi, dobbiamo anche apportare le modifiche necessarie nell’ambiente di sviluppo, prendendo come esempio l’IAR EWARM V8.4 che utilizziamo. Modificare le impostazioni della tabella vettoriale di interrupt e dell’area di archiviazione Flash nel file icf. I dettagli sono i seguenti:

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

Dopo aver completato la configurazione di cui sopra, possiamo scaricare il programma applicativo e il programma BootLoader per realizzare il salto corretto.

Riepilogo

In questo articolo, abbiamo appena implementato un semplice programma BootLoader. Dopo aver scaricato sull’MCU di destinazione, il salto viene realizzato e anche il programma applicativo viene eseguito normalmente, il che dimostra che il nostro progetto è corretto e varie funzioni possono essere aggiunte su questa base per realizzare la corrispondente applicazione IAP.

Va notato che abbiamo disabilitato l’interrupt globale nel programma BootLoader e ricordati di abilitare l’interrupt globale prima che l’applicazione inizializzi il clock di sistema, altrimenti SystemTick non funzionerà e si verificherà un errore hardware (hardfault). Tuttavia, se l’App è in esecuzione su RTOS, potrebbe essere sbagliato attivare l’interrupt, il che richiede attenzione.

Condividi con:

Torna in alto

Instant Quote