Benvenuti a un nuovo appuntamento con la Rubrica Firmware Reload di Elettronica Open Source. In questa Rubrica del blog EOS abbiamo raccolto gli articoli tecnici della vecchia rivista cartacea Firmware, che contengono argomenti e temi passati ancora di interesse per Professionisti, Makers, Hobbisti e Appassionati di elettronica. I nuovi processori di casa ATMEL della linea SAM4L garantiscono una maggiore efficienza per tutte le applicazioni che richiedono una notevole flessibilità in termini prestazionali ma, nello stesso tempo, hanno la necessità di nuove risposte dai diversi sistemi operativi: efficienza e affidabilità, due voci che devono condividere gli stessi obiettivi.
Introduzione
La nuova serie SAM4L di Atmel deve, ma per gli obiettivi aziendali lo dovrà anche in futuro, garantire un vero punto focale per tutte le applicazioni che hanno la necessità di condividere e supportare un carico funzionale che sia in grado di offrire risposte a diverse tipologie di usi. I nuovi processori hanno l’obiettivo, infatti, di fornire, in termini di potenza, per via del Cortex-M4 e con la tecnologia picoPower, una soluzione prestazionale davvero interessante. Il prodotto Atmel assicura in modalità attiva - Lowest power in active mode - un valore intorno ai 90 A/MHz insieme alla modalità di sospensione con totale conservazione della RAM di appena 1,5 A. Non solo, la serie SAM4L assicura anche un valore attorno ai 700 nA in backup mode con una tensione di alimentazione operativa tra 1,68 V e 3,6 V. Non è tutto: secondo i dati forniti da Atmel il processore offre un tempo di riattivazione di soli 1,5 s, a questo riguardo la Figura 1 mostra il suo diagramma a blocchi interno. Il target ideale del processore Atmel è di certo pensato per tutte quelle applicazioni dove è richiesta una notevole reattività nelle fluttuazioni dell’alimentazione, insieme ad una capacità elevata di elaborazione del segnale: di certo stiamo parlando dei segmenti sanitari o consumer.
La Tabella 1 mostra le diverse caratteristiche che può offrire questa nuova tecnica messa a punto da una azienda che è, di fatto, leader nel suo settore.
È possibile, ad ogni modo, per evidenziare il ruolo della tecnologia picoPower di casa Atmel, citare la presenza di memoria flash - tra 128 e 256 kB - o la capacità di utilizzare in ambito controller LCD con la possibilità di gestire fino a 4 x 40 segmenti o anche la presenza della tecnologia QTouch, sempre di Atmel, che permette di sfruttare il rilevamento tattile capacitivo. Atmel, allo scopo di consentire ai progettisti un approccio graduale e di assicurare una valutazione delle caratteristiche tecniche, ha messo a punto un kit di lavoro, in altre parole il pacchetto ATSAM4L-EK. La scheda permetterebbe, insieme ad una valutazione della bontà del processore, di ridurre il “time-to-market” perché può consentire al progettista di sviluppare e mettere a punto in tempi relativamente veloci l’applicazione da inserire poi nel design finale. Il costruttore garantisce, in questo contesto, la presenza di un vero ambiente di lavoro: da un debugger embedded a una circuiteria dedicata per misurare il consumo energetico dell’applicazione, fino alla possibilità di pilotare le varie periferiche presenti. Non solo, visto che in questi anni si stanno sempre più diffondendo soluzioni di espansioni dedicate come i vari shield presenti sul mercato, la casa costruttrice ha anche pensato di offrire schedine di espansione per aggiungere nuove funzionalità quali accelerometri, Wi-Fi o ZigBee. La domanda, però, è una sola: come sfruttare le prerogative di questo processore per ottenere il massimo anche da un sistema operativo? In effetti, la quasi totalità dei dispositivi embedded dispongono di un piccolo kernel al fine di ottimizzare le risorse e le attività computazionali; non solo, uno dei kernel maggiormente utilizzati è senza dubbio FreeRTOS, per diversi motivi. Infatti, FreeRTOS è sufficientemente piccolo per essere utilizzato nei sistemi embedded e non è offerto, almeno nella configurazione commerciale, a un prezzo esorbitante. In che modo è possibile sfruttare il sistema operativo per ottenere il maggiore beneficio per la nostra applicazione? Un aspetto da non sottovalutare è la possibilità di sopprimere il tick di sistema per minimizzare il consumo di un’applicazione qualsiasi che sfrutta le potenzialità del nuovo processore Atmel, poiché SAM4L è stato pensato in modo specifico per essere utilizzato in tutte quelle condizioni che richiedono bassi consumi. Per un utilizzatore è importante inserire il processore di casa Atmel in un ambiente operativo dove i vari modi di funzionamento previsti non rappresentano un problema implementativo, ma semmai una nuova opportunità. Infatti, ogni sistema operativo, o micro kernel, per sequenziare le sue attività ha la necessità di utilizzare un timer di sistema, il tick. Questo tick interrompe l’applicazione cliente a un quanto temporale predefinito al momento dell’inizializzazione (boot) del kernel. A volte, però, può succedere che per particolari attività non ci siano task utenti da prevedere rendendo inutile e dispendioso ricorrere a un tick di questo genere.
LOW POWER MODE: LA SOLUZIONE CON SAM4L
Atmel con questo prodotto ha pensato di offrire una soluzione flessibile poiché consente, grazie a differenti configurazioni opportunamente selezionabili, di ottimizzare il consumo ricorrendo al Power Manager Backup (PMB), si veda a questo proposito la Figura 2.
Al power-up o dopo un reset, il processore (serie SAM4L8/L47L2) si trova in modalità RUN0, mentre il Power Management (PM) può essere utilizzato per intervenire sulle frequenze di lavoro. In effetti, in base alla documentazione fornita dal costruttore, in questa modalità solo il clock strettamente necessario è utilizzato al fine di garantire la normale esecuzione del software: in questo contesto è grazie al ricorso del Power Management (PM) che è possibile regolare le frequenze di clock e abilitare/disabilitare gli eventuali clock associati ai diversi moduli funzionali. L’utente ha la possibilità di scegliere quattro modi di funzionamento, Power Save Mode, al fine di ottimizzare il consumo, in altre parole la scelta è ristretta tra SLEEP, WAIT, RETENTION e BACKUP. In SLEEP mode, il core del Cortex-M4 è fermo, stato STOPPED, mentre, in modo opzionale, i diversi clock associati alle periferiche possono, a discrezione dell’applicazione, essere tenuti in esecuzione. In pratica, in questa modalità è possibile ottimizzare il consumo ricorrendo ad un risparmio selettivo grazie alla possibilità di disabilitare il clock per tutte le periferiche di tipo sincrono attraverso il registro BPM.PMCON.SLEEP. A questo proposito, la Figura 3 offre uno schema riassuntivo sui diversi sub-mode ottenibili.
In base alle indicazioni del costruttore, si rileva che a questo modo operativo si accede attraverso l’istruzione WFI o, in alternativa, grazie al setting del bit SLEEPONEXIT del registro SCR del Cortex-M4. In questo caso, l’utilizzatore deve configurare alcuni bit presenti nei registri del core, ovvero BPM.PMCON.SLEEP, mettere a zero il bit SCR.SLEEPDEEP e BPM.PMCON.RET con BPM.PMCON.BKUP. Al contrario, in WAIT mode, per inciso questa modalità permette di ottenere dei consumi molto bassi, tutte le sorgenti di clock sono arrestate, così come il core e tutte le periferiche ad eccezione del modulo funzionale che utilizza la frequenza di 32 kHz, nel caso in cui venga abilitato. Questa particolare configurazione risulta essere la più bassa soluzione per i consumi ogni qualvolta si deve assicurare il cosiddetto SleepWalking. Per il RETENTION mode, possiamo dire che il comportamento è simile al WAIT MODE, almeno nella parte di clock functionality.
È possibile entrare in WAIT o RETENTION mode ricorrendo all’istruzione WFI solo alla presenza di una particolare configurazione dei registri, in altre parole SCR.SLEEPDEEP a 1, BPM.PSAVE.BKUP a zero e il bit BPM.PMCON.RET in RETENTION o WAIT mode. Infine, nel modo di BACKUP il Core è spento, il dominio di backup è mantenuto, al contrario, alimentato. Questa modalità permette di ottenere il più basso consumo di potenza possibile in un sistema che sta eseguendo periodici wake-up al fine di eseguire compiti dedicati (attività di multitasking), ma che non richiede un tempo di avvio veloce. La parte Core è powered-off, la memoria SRAM interna e il contenuto dei registri interni del core sono persi. Il clock da 32 kHz (RC32K o OSC32K) è mantenuto in esecuzione, se abilitato, per alimentare i moduli che hanno la necessità di un clock di riferimento. Per questa particolarità, e per ogni particolare funzionamento del low power mode, può essere utile consultare la Sezione 6 “Tecniche Low Power” in SAM4L della documentazione di riferimento, mentre la Figura 4 pone in evidenza le relazioni tra le diverse modalità in uso.
FREERTOS, UNA PERFETTA INTESA
FreeRTOS è, senza dubbio, un kernel pensato per applicazioni embedded e può vantare diverse caratteristiche che lo candidano ad essere un vero punto di riferimento, così come pochi altri. Non solo, può vantare una dimensione ridotta, un facile uso ed è, cosa non per nulla secondaria, stato pensato per applicazioni real-time. Nella realtà, un processore non è sempre utilizzato al massimo, o meglio, può capitare, per un certo intervallo temporale, di non fare nulla perché magari si sta aspettando un evento o si entra in una particolare modalità operativa. A questo riguardo, i costruttori di sistemi operativi propongono di mettere in esecuzione un task tipico, idle task che, sostanzialmente, non consuma risorse. Infatti, tipicamente si invoca l’idle task che non fa nulla e si pone il processore in un low power state. Ogni kernel in uso ha sue prerogative con impatti diretti sui consumi.
È chiaro che in una situazione di questo tipo il risparmio di CPU è molto dipendente dall’implementazione poiché si entra/esce dalla modalità di low power in modo periodico in relazione diretta con il tick di sistema. In realtà, occorre anche considerare la frequenza dello stesso tick di sistema; infatti, se la frequenza fosse troppo alta, il risparmio ottenibile da un continuo cambio di contesto potrebbe vanificare l’eventuale aspetto positivo ottenibile. Ad ogni modo, ogni kernel, come abbiamo detto, richiede un suo approccio con determinate limitazioni e non è pensabile fare considerazioni troppo generiche, ma è necessario calarsi nel contesto operativo in uso e tenere presenti le singole caratteristiche del proprio kernel, così come stiamo facendo. Infatti, per via di una particolare modalità di funzionamento, in un idle task si arresta l’interrupt periodico durante il periodo di inattività, ovvero periodi in cui non ci sono attività, task, di applicazione che possono prendere il controllo della CPU, ma solo in seguito, ovvero quando il tick è riattivato, si esegue una rettifica al fine di correggere le inconsistenze incorse in questi particolari frangenti. Fermare l’interrupt di sistema permetterebbe al microcontrollore di rimanere in uno stato di risparmio energetico finché non si verifica un interrupt o assicurare transizioni di sistema operativo, come ad esempio elaborare la coda READY. A tal proposito la Figura 5 pone in evidenza questo particolare criterio: il tick di sistema si ferma tra T1 e T2, l’intervallo temporale dove microcontrollore può rimanere in uno stato di risparmio energetico per lungo tempo e risparmiare così più energia.
Ora, però, il problema è un altro: come implementare una gestione di questo tipo in ambito RTOS? O, in particolare, che cosa si potrebbe fare in FreeRTOS? Per fortuna, in FreeRTOS una gestione di questo tipo è fattibile grazie a particolari facility che possiamo sfruttare. Infatti, costruire una gestione di questo tipo è abbastanza facile per via della presenza di alcuni parametri nel kernel stesso. È possibile, ad esempio, ricorrere alla definizione di configUSE_ TICKLESS_IDLE presente in FreeRTOSConfig.h: impostando il valore a 1 si abilita una gestione di questo tipo in modo totalmente trasparente rispetto a un utente finale. In questo contesto, quando si abilita questa funzionalità, il kernel invoca portSUPPRESS_ TICKS_AND_SLEEP in presenza di due condizioni. Per prima cosa il task identificato come idle task deve essere l’unica unità computazionale in grado di essere eseguita, dal momento che tutte le altre attività, o task, a livello applicativo sono o bloccate (Blocked state) o messe nello stato di sospeso (Suspended state). Non solo, è anche necessario considerare i periodi di clock inattivi, ossia occorre tenere presente il numero dei periodi, n, che dovranno passare prima del momento in cui il kernel stesso si preoccuperà di attivare una nuova transizione.
Questo numero n dovrà essere impostato nella definizione configEXPECTED_ IDLE_TIME_BEFORE_SLEEP presente in FreeRTOSConfig.h. Il parametro xExpectedIdleTime per la funzione portSUPPRESS_TICKS_AND_SLEEP() rappresenta il numero totale di tick di sistema prima che un task sia spostato nello stato Ready. Il valore del parametro rappresenta, quindi, il tempo in cui il microcontrollore può rimanere tranquillamente in uno stato di inattività con il tick di sistema fermo. In ambito FreeRTOS esistono due particolari soluzioni: implementare questa gestione ricorrendo a SysTick o con AST, ovvero con l’Asynchronous timer. Nel primo caso si ricorre al classico tempo di sistema, o Tick di sistema, implementato e gestito in modo tradizionale; infatti, in SAM4L FreeRTOS si utilizza un timer a 24 bit, ossia SysTick, che conta a partire da un valore di reload impostato a zero. Grazie a questo timer, un evento periodico può essere facilmente gestito insieme al cambio del contesto tra i vari task presenti nel sistema. Il Listato 1 pone in evidenza il gestore del clock di sistema insieme alla corretta gestione del bit configUSE_ TICKLESS_IDLE.
void SysTick_Handler( void ) { /* If using preemption, also force a context switch. */ #if configUSE_PREEMPTION == 1 portNVIC_INT_CTRL_REG = portNVIC_PENDSVSET _BIT; #endif /* If using tickless mode, reset the systick load register. */ #if configUSE_TICKLESS_IDLE == 1 portNVIC_SYSTICK_LOAD_REG = ulTimerReloadValueForOneTick; #endif ( void ) portSET_INTERRUPT_MASK_FROM_ISR(); { vTaskIncrementTick(); } portCLEAR_INTERRUPT_MASK_FROM_ISR( 0 ); }
Listato 1 - Possibile gestore della funzionalità SysTick |
Per questa particolare implementazione si dovrebbe anche considerare la funzione vPortSuppressTicksAndSleep(): una funzione con un solo parametro che identifica il numero dei tick di sistema prima che il task venga spostato in uno stato di READY, ossia in ready queue. Il codice per la funzione non è per nulla banale poiché sarà necessario ricalcolare lo sleep time, la riconfigurazione del timer SysTick sempre in accordo a questo sleep time, gestire la modalità di low power e dimensionare il tempo di CPU speso dal task in questa modalità, e ricalcolare il tick da tenere come base dei tempi successivamente all’evento considerato. Tutti questi passi, però, per fortuna, sono stati già previsti in FreeRTOS. Secondo le specifiche di FreeRTOS rimane a carico dell’utente l’abilitazione o meno di questa funzionalità operativa ricorrendo alla definizione di configUSE_TICKLESS_IDLE. In effetti, grazie a questo kernel il processore entra in modalità low power in modo automatico e trasparente qualora non ci siano task applicativi in esecuzione e dove il tempo minimo di blocco delle attività dell’applicazione non fosse inferiore a configEXPECTED_IDLE_TIME_BEFORE_ SLEEP presente in Config.h.
Occorre però precisare che esiste potenzialmente un rischio; infatti, tutto questo presuppone che il processore si trovi in una situazione di low power mode e non in Wait Mode o Retention mode. In questo caso, un wake-up potrebbe non bastare perché il timer di sistema potrebbe anche non essere più risvegliato in situazioni dove si presenta una modalità di low power più spinta. Altra cosa se ricorressimo all’AST; in questo caso, il processore entrerebbe in low power mode utilizzando la configurazione di AST e rimarrebbe in questo stato per un tempo indeterminato fino a quando non scade il contatore AST. Precisiamo però che se il calendar mode fosse utilizzato nell’applicazione, allora la funzionalità di tickless non potrebbe essere presa in considerazione fino a quando si utilizza il counter mode in AST. Si ricorda che SAM4L può vantare un solo modulo AST che non potrà funzionare in modalità calendar e counter nello stesso tempo.
IN CONCLUSIONE
In questo articolo abbiamo esaminato alcuni aspetti che possiamo tenere presenti per sfruttare al massimo la nuova famiglia di casa Atmel, ma per ricavare il necessario al fine di definire le nostre nuove piattaforme di lavoro bisogna conoscere in modo più completo sia il sistema operativo (o kernel) che stiamo utilizzando, sia il processore, perché questi due mondi non possono essere considerati in modo disgiunto.