Come aggiornare il firmware senza interromperne l'esecuzione
Contributo di Editori nordamericani di DigiKey
2020-04-16
Le applicazioni basate su sensori per Internet delle cose (IoT) si stanno espandendo, così come le dimensioni e la complessità del firmware dei microcontroller nell'endpoint IoT. Per accelerare l'esecuzione, il firmware deve diventare più efficiente e questo è uno dei motivi per cui servono aggiornamenti del firmware flash sul campo. Tuttavia, perché l'aggiornamento sia sicuro, di solito occorre interromperne l'esecuzione. Questa operazione può essere ultimata in un minuto o in un'ora, a seconda dell'architettura, delle dimensioni dell'aggiornamento e della velocità della rete. Per le applicazioni critiche un lungo ritardo potrebbe essere inaccettabile.
Questo articolo spiega perché aggiornare il firmware guidato da interrupt sul campo e perché è necessario continuare ad eseguire il firmware dell'applicazione mentre è in corso l'aggiornamento. Introduce poi il microcontroller PIC32MZ2048EFH144T-I/PH di Microchip Technology e mostra come utilizzarlo per eseguire il firmware mentre ne è in corso l'aggiornamento su una rete.
L'importanza degli aggiornamenti del firmware
Il firmware viene aggiornato per quattro motivi principali: per correggere i bug nel codice, per aggiungere o migliorare le funzionalità, per apportare correzioni alla sicurezza del sistema e migliorare l'efficienza del firmware. L'efficienza del codice si misura in base al numero di cicli di clock necessari per eseguire un'attività o un thread specifico. Meno sono i cicli di clock, più il codice è efficiente. Questo accelera l'esecuzione e di solito (ma non sempre) riduce le dimensioni del codice. Ciò è particolarmente vero per gli endpoint basati su sensori IoT, in quanto queste applicazioni sono guidate da interrupt e quindi devono cambiare rapidamente contesto ogni volta che un sensore o una periferica genera un interrupt.
Due fattori che influenzano l'efficienza delle applicazioni IoT guidate da interrupt sono l'efficienza dell'architettura e l'efficienza del codice. Mentre non è pratico cambiare l'architettura di un microcontroller sul campo, è invece pratico e normale aggiornare il firmware del microcontroller per migliorare l'efficienza.
Il firmware basato su sensori è quasi sempre guidato da interrupt. I sensori intelligenti collegati alla porta seriale di un microcontroller possono generare un interrupt al microcontroller per arrestare la normale esecuzione in modo che il firmware possa eseguire la vettorializzazione su una routine di servizio di interrupt per quel particolare sensore. Questo approccio è più efficiente del polling periodico dei sensori per determinare se la lettura del sensore abbia nuovi dati da trasmettere. La strategia di un sensore guidato da interrupt ha il vantaggio che il microcontroller dedica cicli di clock per la lettura del sensore solo quando ci sono dati utili da ricevere. Il polling spreca i cicli di clock quando il firmware deve accedere al sensore per leggere i dati che vengono scartati perché la lettura del sensore non si è aggiornata.
Se i sensori e le attività aumentano, aumentano le subroutine e le routine di interrupt per gestirli, e quindi le dimensioni del codice. Un codice complesso richiede un sistema operativo in tempo reale (RTOS) per gestire tutte queste attività separate. L'RTOS può essere una semplice applicazione firmware scritta dal programmatore del software oppure un prodotto di serie. L'RTOS gestisce le varie attività del firmware per assicurarsi che ognuna di esse inizi e finisca entro il tempo necessario perché l'applicazione funzioni correttamente. Se l'RTOS deve gestire molte attività, per l'applicazione è preferibile che vengano completate entro il minor numero possibile di cicli di clock. In questo modo si evita che si ritardino a vicenda.
Quando viene ricevuto un interrupt, il tempo necessario per completare la sua routine di servizio è per lo più una combinazione di tre fattori:
- I cicli di clock necessari per riconoscere l'interrupt e iniziare la vettorializzazione sulla sua routine di servizio. Se l'attività ha una priorità inferiore a quella dell'attività in corso, verrà ritardata fino al completamento dell'attività corrente. Ciò dipende dall'applicazione.
- I cicli di clock necessari per salvare il contesto dello stato corrente della CPU ed eseguire la vettorializzazione sulla routine di servizio di interrupt. Questo dipende dall'architettura ed esula dal controllo del programmatore del software.
- I cicli di clock necessari per eseguire la routine di servizio di interrupt. Questo dipende sia dalla complessità che dall'efficienza del codice scritto dal programmatore del software.
Quanto più il firmware è efficiente, minori sono le probabilità che si verifichi un conflitto tra le attività che devono essere completate entro un determinato periodo.
Requisiti di memoria per l'aggiornamento del firmware flash
I sistemi che devono essere aggiornati in modo affidabile sul campo richiedono il doppio della memoria di programma flash reputata necessaria per l'applicazione. Questo perché la memoria flash deve essere abbastanza grande da contenere sia il firmware flash esistente sia quello aggiornato. Tuttavia, è comune che i piccoli sistemi che funzionano solo con la memoria flash interna del programma arrestino l'esecuzione del codice mentre è in corso l'aggiornamento del firmware tramite la rete. Tale arresto potrebbe essere inaccettabile per le applicazioni mission-critical ed è contrario all'obiettivo di un firmware efficiente, nel senso che il codice arrestato funziona con un'efficienza pari a zero.
Esecuzione del firmware durante l'aggiornamento flash
Un microcontroller ad alte prestazioni in grado di eseguire il firmware durante l'aggiornamento della memoria flash su chip è PIC32MZ2048EFH144T-I/PH di Microchip Technology (Figura 1). PIC32MZ2048EFH144T-I/PH si basa sull'architettura del core MIPS32 di Classe M con un'unità a virgola mobile (FPU) pensata per complessi endpoint IoT guidati da interrupt. Ha 2 MB di memoria flash di programma e 512 kB di SRAM. Ha anche 160 kB di flash di avvio. Il core PIC32MZ2048EFH144T-I/PH può funzionare fino a 252 MHz in un intervallo di temperatura da -40 a +85 °C e a 180 MHz in un intervallo da -40 a +125 °C. La tensione di funzionamento è appena tra 2,1 e 3,6 V.
Ha nove timer di acquisizione/comparazione a 32 bit per supportare firmware complesso e anche per misurare i segnali esterni.
Figura 1: PIC32MZ2048EFH144T-I/PH a 252 MHz di Microchip Technology si basa sull'architettura MIPS32 di Classe M e ha un'ampia gamma di porte seriali per l'interfacciamento con sensori esterni. (Immagine per gentile concessione di Microchip Technology)
Le porte seriali esterne includono nove porte UART e cinque I2C. Sei porte SPI supportano anche l'interfaccia audio I2S. Un convertitore analogico/digitale (ADC) a 12 bit con 48 ingressi può misurare le tensioni provenienti da sensori analogici di precisione. Grazie al numero di queste porte seriali e di questi ingressi ADC, PIC32MZ2048EFH144T-I/PH può interfacciarsi con molti sensori esterni, ed è quindi idoneo per endpoint IoT complessi basati su sensori. Due porte CAN 2.0b permettono al microcontroller di collegarsi in rete con reti industriali e automotive che utilizzano il comune protocollo CAN.
Una porta Ethernet supporta la connettività di rete 10/100Base-T. Un controller USB 2.0 Hi-Speed supporta un'interfaccia esterna per periferiche aggiuntive o per il debug e supporta anche USB On-The-Go (OTG).
Ognuna di queste periferiche può generare uno o più interrupt. Dato il numero elevato di sensori e sorgenti di interrupt, è necessario mantenere l'efficienza del codice.
Per migliorarla, il core della CPU MIPS32 di Classe M ha 32 registri per uso generale (GPR) a 32 bit. Il miglioramento dell'efficienza si ottiene riducendo gli accessi alla memoria esterna. Oltre al consueto set di bit e a istruzioni chiare, la Classe M supporta anche istruzioni di inversione dei bit a ciclo singolo. Il miglioramento dell'efficienza RTOS si ottiene aumentando l'efficienza della gestione del semaforo. Il core ha anche una pipeline di istruzioni in cinque fasi che migliora l'efficienza riducendo al minimo i conflitti di accesso alla memoria, per cui si ha un maggior numero di istruzioni a ciclo singolo.
MIPS32 di Classe M ha anche sette set di registri shadow GPR. Questo migliora in modo significativo le prestazioni degli interrupt e la commutazione del contesto eliminando i molti cicli di clock richiesti per salvare i GPR sullo stack. Con sette set di registri shadow, il core può nidificare gli interrupt e le commutazioni di contesto a sette profondità prima di dover dedicare cicli di clock per salvare i GPR sullo stack.
PIC32MZ2048EFH144T-I/PH ha due banchi da 1 MB di memoria flash di programma (PFM), detti Banco PFM 1 e Banco PFM 2. Ogni PFM ha la propria memoria flash di boot dedicata (BFM) detta Banco BFM 1 e Banco BFM 2. Non è necessario aggiornare la BFM durante un aggiornamento PFM. Avere due banchi di memoria separati offre numerosi vantaggi. Ad esempio, il microcontroller supporta il dual-boot, quindi all'accensione può essere configurato per il boot da uno dei due banchi di memoria flash. Di conseguenza, può supportare due diverse configurazioni del dispositivo.
I due banchi di flash consentono inoltre l'esecuzione del firmware da un banco di flash e il suo aggiornamento nell'altro banco. Microchip lo chiama Live-Update, noto anche come autoprogrammazione runtime (RTSP). Quando l'RTSP viene avviata in un endpoint IoT attivo che esegue il firmware dal Banco PFM 1, il firmware viene ricevuto via rete in blocchi. Il metodo consigliato per gestire gli aggiornamenti del firmware su una rete è quello di memorizzare il blocco del nuovo firmware nella SRAM. Dopo aver ricevuto un blocco completo, il firmware in esecuzione dal Banco PFM 1 può avviare una sequenza di programmazione dei dati SRAM nel Banco PFM 2. Mentre questo firmware viene programmato, la sua esecuzione dal Banco PFM 1 può continuare.
Al termine della programmazione dei blocchi, il firmware può richiedere il blocco di codice successivo sulla rete e la sequenza si ripete. Questo processo continua fino al completamento del blocco di codice nel Banco PFM 2. Al termine della programmazione, il firmware può configurare PIC32MZ2048EFH144T-I/PH al reset successivo affinché si avvii dal Banco BFM 2 ed eseguire il nuovo firmware nel Banco PFM 2 cancellando il bit SWAP nel registro di configurazione NVMCON (Figura 2). Se il firmware di PIC32MZ2048EFH144T-I/PH deve essere aggiornato di nuovo mentre SWAP=0, può essere eseguito dal Banco PFM 2 mentre contemporaneamente viene aggiornato il Banco PFM 1.
Figura 2: Il microcontroller PIC32MZ2048EFH144T-I/PH ha due banchi indipendenti di PFM. Se SWAP=1, il firmware può essere eseguito dal Banco PFM 1 mentre il Banco PFM 2 viene aggiornato. La cancellazione di SWAP=0 permette al microcontroller di avviarsi dal Banco PFM 2. (Immagine per gentile concessione di Microchip Technology)
Lo stato del bit SWAP può essere modificato sia dalla BFM che dalla PFM a seconda delle esigenze del firmware.
Sviluppo di firmware dual-boot
Per lo sviluppo con il microcontroller PIC32MZ2048EFH144T-I/PH, Microchip Technology mette a disposizione lo starter kit PIC32MZ DM320007 (Figura 3). Questa scheda supporta più porte seriali utilizzando sia connettori dedicati che connettori su basetta. Per il debug viene utilizzata una porta USB host, mentre per l'applicazione può essere utilizzata una porta USB OTG. Un connettore USB-UART/I2C, quando collegato alla porta USB di un PC, crea una porta COM virtuale su un PC host collegato. Il PC host può così comunicare con la porta I2C su PIC32MZ.
Figura 3: Lo starter kit compatto DM320007 di Microchip Technology supporta lo sviluppo e il test di applicazioni USB ed Ethernet con il microcontroller PIC32MZ2048EFH144T-I/PH. Include connettori per USB OTG, USB Host, 10/100 Ethernet e UART/I2C. (Immagine per gentile concessione di Microchip Technology)
Un connettore con basetta di espansione a 40 pin consente di accedere ad altre porte I2C, SPI e UART, oltre che a pin di I/O per uso generale (GPIO) su PIC32MZ EF. Tramite il firmware è possibile configurare tre pulsanti e tre LED.
Conclusione
Gli endpoint dei sensori IoT nei sistemi critici hanno requisiti di memoria più elevati, perché il codice è più complesso. Più il codice è complesso, più è necessario migliorare l'efficienza del firmware per migliorare i tempi di risposta della commutazione di contesto nel firmware. Scegliendo un microcontroller in grado di eseguire in modo efficiente codice guidato da interrupt capace di richiamare e aggiornare contemporaneamente il firmware, gli sviluppatori possono migliorare l'affidabilità di applicazioni IoT critiche senza sacrificare le prestazioni.
Esonero della responsabilità: le opinioni, le convinzioni e i punti di vista espressi dai vari autori e/o dai partecipanti al forum su questo sito Web non riflettono necessariamente le opinioni, le convinzioni e i punti di vista di DigiKey o le sue politiche.

