2009-06-06 9 views
23

Anche se ci sono molti framework di test unitari che supportano C, sono un po 'perplesso su come scrivere test unitari per codice microcontrollore (PIC nel mio caso, ma penso che la domanda sia più generale di quello).Modelli di test unitario per microcontrollore Codice C

Gran parte del codice scritto per i microcontrollori ruota attorno alla scrittura di valori di configurazione e dati nei registri, nella lettura dei dati in arrivo dai registri e nella risposta agli eventi di interrupt. Mi chiedo se qualcuno può fornire alcune indicazioni sul modo più efficace per farlo.

+0

Potrebbe qualcuno con rep sufficiente si prega di aggiungere il tag "embedded" a questa domanda? Grazie. –

risposta

29

Scrivi;

"Gran parte del codice scritto per i microcontrollori ruota attorno alla scrittura di valori di configurazione e dati nei registri, nella lettura dei dati in arrivo dai registri e nella risposta agli eventi di interrupt".

Sono d'accordo che questo è spesso il caso nella pratica, ma in realtà non penso che sia una buona cosa, e penso che ripensare un po 'le cose ti aiuterà con i tuoi obiettivi di test.

Forse perché i programmatori di microcontrollori possono raggiungere e toccare l'hardware ogni volta che vogliono, molti (la maggior parte?) Di loro hanno preso l'abitudine di fare proprio questo, attraverso il loro codice. Spesso questa abitudine viene seguita senza discussioni, forse perché così tante persone che fanno questo tipo di lavoro sono EE, non scienziati informatici con la formazione e l'inclinazione. Lo so, sono partito da me in questo modo.

Il punto che sto cercando di fare, è che i progetti di microcontrollore possono e devono essere ben progettati come qualsiasi altro progetto software. Una parte molto importante del buon design consiste nel limitare l'accesso hardware ai driver hardware! Separa tutto il codice che scrive registri, risponde agli interrupt, ecc. In moduli che forniscono al resto del tuo software un accesso piacevole, pulito e astratto all'hardware. Testare i moduli del driver sul bersaglio usando analizzatori di stati logici, oscilloscopi, banchi di prova personalizzati o qualsiasi altra cosa che abbia senso.

Un punto davvero importante è che ora il resto del software, si spera che la maggior parte di esso, sia ora solo codice C che è possibile eseguire e testare su un sistema host. Sul sistema host i moduli hardware vengono estrapolati in modo da fornire visibilità su ciò che sta facendo il codice sotto test. È possibile utilizzare gli approcci di test unitari mainstream su questo codice. Ciò richiede alcuni preparativi e lavoro, ma se sei ben organizzato puoi creare un sistema riutilizzabile che possa essere applicato a tutti i tuoi progetti. I potenziali benefici sono enormi. Ho scritto un po 'di più su queste idee qui;

[http://discuss.joelonsoftware.com/default.asp?joel.3.530964.12][1]

+4

Buon punto. Posso aggiungere: abituarsi a usare uint16_t, uint8_t e così via (invece di solo int, char) in modo che i tipi siano più prevedibili quando si passa dalla piattaforma integrata al PC e anche tra diverse piattaforme incorporate. –

+3

Problemi con questa risposta: l'astrazione del driver hardware crea un sovraccarico significativo, spesso inaccettabile, a meno che non venga scritto nell'assembler. ma mescolare C e assembler è un enorme mal di testa - non solo l'architettura PIC con cui lavorare una PITA, il compilatore salta attraverso i cerchi che si destreggiano tra le diverse banche di registri ecc. che è una seria PITA enorme per scrivere assemblatore lungo il lato. – Jodes

0

Esiste forse qualche tipo di modalità di loopback in modo da poter utilizzare il controller stesso per generare eventi da testare?

3

Un approccio a questo potrebbe essere l'utilizzo di un emulatore. Ho lavorato su un emulatore AVR e una delle idee per usarlo è proprio il codice di test unitario. L'emulatore implementa CPU e registri, interrupt e varie periferiche, e (nel mio caso) byte scritti sull'UART emulato passano al normale stdout dell'emulatore. In questo modo, il codice di test dell'unità può essere eseguito nell'emulatore e scrivere i risultati del test sulla console.

Ovviamente, è necessario assicurarsi che l'emulatore stia implementando correttamente il comportamento della CPU reale, altrimenti i test dell'unità in cima a ciò non possono essere considerati attendibili.

2

Scrivi versioni fittizie del tuo registro per accedere a funzioni/macro. Si noti che ciò presuppone che il proprio codice utilizzi un insieme comune di funzioni di accesso ai registri e non roba ad-hoc come *(volatile int*)0xDEADBEEF = 0xBADF00D ovunque.

Chiama i gestori di interrupt direttamente dal codice di test (potrebbe essere problematico su alcune architetture ¹), un "interrupt software", se disponibile, o da un gestore di interrupt timer se è necessario eseguirli in modo asincrono. Questo potrebbe richiedere il wrapping del codice di abilitazione/disabilitazione degli interrupt nelle funzioni/macro che puoi prendere in giro.

¹ 8051 viene in mente: almeno con il compilatore Keil 8051, non è possibile chiamare direttamente le funzioni di interrupt. Questo potrebbe essere risolto con il preprocessore C.