Embedded_52 - page 63

EMBEDDED
52 • MAGGIO • 2014
63
SOFTWARE
C LANGUAGE
thread di esecuzione e una o più routine ISR hanno
accesso all’oggetto.
• Accesso mediante procedura di trigger: come accade
nel caso di un dispositivo hardware mappato in memo-
ria per il quale verificarsi di un accesso ha un effetto sul
dispositivo stesso.
• Accesso modificato; in questo caso i contenuti di un
oggetto possono variare in maniera non nota al compilatore.
A questo punto è utile chiedersi quale garanzia viene
fornita dal compilatore se si utilizza la variabile volatile
in una dichiarazione di oggetto. La garanzia è sostan-
zialmente il fatto che tutti gli accessi in lettura e scrit-
tura sono mantenuti.
In funzione dell’architettura del sistema target sarebbe
anche possibile ottenere tutti gli accessi completi ed
eseguiti nell’ordine fornito nella mac-
china astratta: inoltre tutti gli accessi
sono di tipo atomico (in altre parole non
possono essere interrotti).
Prendendo ad esempio il codice riportato
in figura 1, bisogna chiedersi se è sicuro
in termini di thread e interrupt, dato che
l’accesso all’oggetto volatile può avveni-
re da differenti contesti di esecuzione.
Sia il caricamento dalla memoria sia
l’immagazzinamento nella memoria del
valore dell’oggetto vol sono di natura
atomica in quanto si tratta di un’architet-
tura load/store a 32 bit. Ma l’istruzione
sorgente non è atomica. Esiste quindi
la possibilità che si verifichi una commutazione di con-
testo o un interrupt in un punto qualunque fra le tre
istruzioni che formano l’istruzione vol++.
Per superare le problematiche del tipo appena descritto
è dunque necessario:
• Non fare mai l’ipotesi che volatile sia sinonimo di
atomico a eccezione se non nel caso di determinati
accessi in memoria.
• Assicurarsi che il codice che non esegue solo una
lettura o scrittura a livello atomico sia protetto da
adeguate primitive di serializzazione, come un mutex,
oppure mediante la disabilitazione dell’interrupt nel
caso in cui differenti contesti di esecuzione possano
accedere all’oggetto.
• Introdurre nello standard di codifica opportune rego-
le per un corretto uso della variabile volatile e delle
primitive di serializzazione.
• Procedere a un riesame dell’uso di tutti gli oggetti
globali, inclusi gli oggetti statici con visibilità a livello
di file (file-scoped), presenti nel codice esistente.
Dimensioni dello stack
A questo è utile fare alcune considerazioni circa le
dimensioni dello stack (un eterno dilemma per gli
sviluppatori). Se lo stack è sovradimensionato, è
richiesta la presenza di maggiori risorse di memo-
ria RAM, con conseguente incremento dei costi. Se
viceversa lo stack è sottodimensionato, si potreb-
bero produrre eventi anche di natura catastrofica,
incompatibili con un sistema utilizzato in applica-
zioni safety-critical.
Di seguito alcuni utili suggerimenti utili per deter-
minare le dimensioni dello stack:
• Utilizzare, se disponibile, la funzionalità di verifi-
ca dello stack del debugger in run time.
• Riempire la memoria non utilizzata sopra e/o
sotto lo stack con un “magic pattern” che può
essere verificato periodicamente in
run time da una routine di control-
lo dedicata. A causa dei requisiti
previsti dallo standard IEC 60730
relativo agli elettrodomestici, un
fornitore di MCU potrebbe avere
già integrato questa funzionalità
e altre funzioni di self-check della
CPU in una libreria specifica.
• Eseguire un’analisi dell’albero
delle chiamate per determinare la
profondità dello stack nel caso peg-
giore, compreso lo stack utilizzato
dai gestori di interrupt. Se si rie-
samina il codice e si analizzano “a
mano” i file della mappa prodotta dal linker è bene
ricordare che il processo di ottimizzazione influen-
zerà l’utilizzo dello stack.
• L’utente può acquistare o sviluppare tool di sup-
porto, come pure accertarsi che si stia utilizzando
una tool chain in grado di fornire un utile ausilio
nell’analisi sia dell’albero delle chiamate sia della
profondità dello stack.
In sintesi, questi quattro punti riassumono i concet-
ti fin qui espressi:
• Prima di iniziare, prendere confidenza con i
requisiti dello sviluppo software definiti dallo stan-
dard adatto.
• Utilizzare MISRA-C come base per lo standard di
codifica.
• Riesaminare l’utilizzo delle variabili dichiarate
volatili.
• Implementare una strategia di analisi e di test
per l’allocazione dello stack.
Nonostante
i limiti, il linguag-
gio C è ancora
ampiamente
utilizzato
in applicazioni
critiche dal
punto di vista
della sicurezza
1...,53,54,55,56,57,58,59,60,61,62 64,65,66,67,68,69,70,71,72,73,...86
Powered by FlippingBook