
In genere, quando si programma un microcontrollore, bisogna utilizzare un programmatore per quel particolare microcontrollore. Oltre ad essere costoso, può avere altri svantaggi, come lunghi periodi di programmazione o troppe interconnessioni tra il microcontrolloreed il programmatore stesso; alcuni programmatori non sono in grado di programmare i circuiti. A volte il micro non è disponibile mentre è montato nel prodotto finale, infatti potrebbe risiedere in un alloggiamento plastico o metallico, e disponibili solo alcune interfacce standard su un connettore.
Molti di questi problemi sono indirizzati da un bootloader. Per un hobbista, a volte sembra troppo costoso spendere decine di euro (e qualche volta anche centinaia) per qualche dispositivo. Nei laboratori universitari, potrebbe non essere pratico avere un programmatore per ogni banco di lavoro, e la soluzione migliore è di dare agli studenti dei microcontrollori che possiedono già in memoria il programma bootloader. Nell’industria automobilistica, molte unità di controllo elettronico (ECU) sono incapsulate in alloggiamenti che lasciano davvero pochi piedini accessibili, ma tra questi piedini generalmente c’è un’interfaccia CAN disponibile, che hanno reso CAN basato sui bootloader molto popolare in questo ambiente.
Quindi, il bootloader deve essere programmato nella memoria di programma del microcontrollore una sola volta, usando un programmatore convenzionale. Dopo di ciò il microcontrollore può essere programmato senza un programmatore. Una volta nel microcontrollore, il bootloader è programmato in modo che ogni volta, dopo il reset, inizia ad essere eseguito come un programma regolare. Prima di tutto, in base al tipo di bootloader, si mette “in ascolto” su una specifica interfaccia in attesa di byte.
Ad esempio, un bootloader UART si metterà in ascolto sul buffer UART del micro, controllando se ci sono bytes in arrivo. Se i bytes iniziano ad arrivare, il bootloader li catturerà e li scriverà nella memoria del programma nella sequenza in cui li riceve e in locazioni predefinite. Una volta che tutti ibytes sono stati ricevuti, il bootloader esegue un salto all’inizio della zona di memoria che ha ricevuto e il programma “normale” sarà eseguito. In figura è mostrato come un normale programma può essere programmato nella memoria di 8KB di un micro:

Ma nel caso in cui si voglia usare un bootloader, bisogna prima scriverlo nella memoria come un programma normale. Quindi, come primo passo, il bootloader viene inserito nella memoria di programma. Una buona locazione per il bootloader è la fine dello spaizo di memoria, ma una parte di esso si deve comunque trovare alle prime locazioni di memoria, in modo che il bootloader si avvierà dopo il reset del micro.

Una volta che il bootloader è al suo posto, e il micro è stato resettato, il bootloader inizierà ad ascoltare su una delle interfacce del micro (come UART, SPI, I2C, CAN, ECC) per i bytes in ingresso. A volte, “ascoltare” non è il modo giusto per descrivere questo, dato che il bootloader potrebbe necessitare di generare degli impulsi di clock sulla linea del clock SPI, oppure potrebbe dover inizializzare il protocollo I2C. Se i dati vengono ricevuti nel formato che si aspetta il bootloader, esso inizia a scrivere i byte in ingresso nella memoria di programma. Tuttavia, a causa del fatto che alcune locazioni del vettore di reset sono occupate dal codice del bootloader stesso, i dati del programma in arrivo che normalmente verrebbero scritti lì devono essere riallocati ad un indirizzo conosciuto (EFFFh nel nostro esempio):

una volta che il programma in arrivo è stato scritto nella memoria flash del programma, il bootloader eseguirà un salto all’indirizzo conosciuto EFFFh, e il programma che è stato inviato al micro sarà eseguito. Nel caso in cui nessun dato verrà fornito dall’interfaccia stabilita, il bootloader aspetterà per un certo periodo di tempo, e poi eseguirà un salto ad una locazione di memoria data, basandosi sull’idea che l’utente voglia eseguire un programma che è stato scritto nella memoria di programma nel passo precedente.
quindi i passi generali in un bootloader funzionante sono:

- -passo 1: subito appena dopo il reset, il bootloader prende il controlo ed esegue un salto all’area di memoria dove è presente il proprio codice.- Il codice presente lì inizia l’ascolto sull’interfaccia esterna scelta per i dati in ingresso.
-passo 2: i dati in ingresso sono scritti nella memoria di programma come se fossero scritti da un programmatore, tranne per i primi bytes, che normalmente sarebbero stati scritti nel vettore di reset.
-passo 3: una volta che tutti i dati di ingresso sono stati scritti, il bootlader esegue un salto alla prima istruzione del programma ricevuto.
L’esempio precedente è solo uno dei modi in cui potrebbe funzionare un bootloader. Ci sono altri modi dedicati, in base al micro, per esempio, potrebbe avere un’area dedicata nella memoria del programma per un bootloader. Il PIC18F52 (datasheet) è solo un esempio di dove il bootloader verrà scritto all’inizio della memoria di programma:

Ovviamente, in qualche caso, non solo il vettore di reset dovrà essere mappato, ma anche tutti i vettori degli interrupt. Questo è fatto facilmente su un micro che ha solo due vettori di interrupt (uno per quelli con priorità alta e uno per quelli con priorità bassa), ma potrebbe non essere così pratico su altri micro, dove i vettori di interrupt per ogni sorgente di interrupt hanno indirizzi differenti (come sulla buon vecchia architettura 8051).
Ora spendiamo qualche parola sui tipi di bootloader.
Il tipo più usato è il bootloader UART. Questo significa che dopo ogni reset il micro inizia ad ascoltare sull’interfaccia UART per i dati in ingresso. Sono ampiamente usati oggi dato che è un’interfaccia comune per molti micro controller. Questo tipo di bootloader semplicemente rimuove la necessità di un programmatore. Serve soltanto un software per pc (facile ed economico da trovare/realizzare) e un cavo seriale, provvisto di interfaccia UART. Gradualmente, dopo l’apparizione dell’interfaccia USB sui micro, sono nati i bootloader USB. Eseguono le stesse funzioni e sono molto pratici da utilizzare.
Un altro tipo speciale di bootloader è il bootloader SPI/I2C. In genere, il modo di funzionare è simile ad ogni altro bootloader, ma invece di mettersi in ascolto sull’interfaccia UART/USB prova a leggere i dati da una memoria EEPROM collegata con un’interfaccia I2C o SPI. Questi bootloader sono progettati per permettere il facile aggiornamento di un software sul campo. È possibile collegare la memoria SPI su uno zoccolo, e un cambiamento di firmware significherebbe semplicemente sostituire un circuito integrato. Ovviamente, per poter fare ciò, bisogna avere accesso fisico alla EEPROM in questione.
Il bootloader CAN è largamente usato nell’industria automobilistica. Molti dei dispositivi che si trovano in un auto oggigiorno hanno una porta CAN, che èe accessibile da due piedini su un connettore. Per questo motivo, sono stati sviluppati i bootloader che lavorano con l’interfaccia CAN dei micro, perciò è possibile aggiornare un firmware di un dispositivo senza aprire il suo alloggiamento o senza rimuoverlo dal circuito, grazie alle specifiche di rete native dell’interfaccia CAN. Così da permettere aggiornamenti sul campo di software per automobili e anche piccole correzioni per coprire i bug delle auto che sono state vendute con essi. In modo che la prossima volta che portiamo l’automobile in un garage “autorizzato” ci pensiamo due volte quando vediamo il tecnico collegare un “tester” nella nostra auto. Potrebbe riscrivere il software fissando alcuni bug di cui non eravamo neanche a conoscenza.
Post dal 8 aprile 2009

Potete leggere la versione in lingua inglese qui: What a Microcontroller Bootloader Is and How It Works?
L’articolo tratta molto bene ed in dettaglio le problematiche relative alla realizzazione di un bootloader per sistemi embedded. L’avvento della tecnologia flash, unitamente alla funzionalita’ offerta dal bootloader, ha permesso di eseguire l’upgrade di un’applicazione embedded direttamente sul campo, senza necessariamente dover “metter mano” al circuito.
Alcune board memorizzano il bootloader su un componente flash separato da quello che ospita l’applicazione: cio’ avviene tipicamente nei casi in cui il supporto di memoria (ad esempio schedina SD o CF) debba offrire la possibilita’ di essere sostituito.
In altri casi, tipicamente nei sistemi “low cost”, boot loader e applicazione condividono la stessa flash, tipicamente quella integrata nei microcontrollori. In questi casi, viene sfruttata la possibilita’ offerta dal componente di proteggere selettivamente alcuni settori di flash (quelli riservati al bootloader) in modo tale che programmazioni errate non compromettano la sicurezza del sistema.
valerio
L’articolo è sempre nostro: http://dev.emcelettronica.com/…
scritto da un nostro collaboratore su mia indicazione.
Quello che tu segnali è solo uno dei tanti blog che ci copia, tra l’altro hanno anche lasciato il link al nostro datasheet, sempre sul server emcelettronica.com ma ora non più attivo.
Detto questo trovo però irritante che invece di segnalarci la cosa dobbiamo venire attaccati….