Esegui il codice una volta nella vita di un programma C incorporato


8

Come posso eseguire uno snippet di codice solo una volta nella vita di un programma? Può essere spento e acceso più volte. L'unica opzione per eseguire nuovamente lo snippet di codice deve essere nuovamente il flashing della scheda.

Il codice è una sezione di calibrazione che non voglio eseguire di nuovo. Se uso EEPROM o Flash imposteremo un Flag su true o False. Quindi quando leggiamo per la prima volta quella posizione di memoria quale sarebbe il valore casuale in quell'area di memoria?

Qual è il metodo migliore per implementarlo in C incorporato?


5
Usa una bandiera e salva questa bandiera su eeprom (o sul flash). In ogni istante leggi la bandiera di eeprom. La prima volta dell'istante, il valore del flag forzerà l'esecuzione della funzione. Successivamente è possibile modificare il valore del flag e salvarlo di nuovo su eeprom. Tutte le altre volte il valore del flag non forzerà l'esclusione della funzione.
hoo2,

2
non è chiaro cosa stai chiedendo.
old_timer

2
Qual è la tua motivazione dietro impedire l'esecuzione del codice una seconda volta? È importante che il codice non possa essere retroingegnerizzato, nel qual caso l'impostazione di un flag per bypassarlo potrebbe non essere abbastanza sicura? Eseguire il codice una seconda volta danneggerebbe l'hardware? È una cosa UX, come visualizzare un messaggio tutorial la prima volta che si utilizza il sistema, nel qual caso potrebbe essere auspicabile che la funzione "reset di fabbrica" ​​(se presente) attivi nuovamente il codice?
Micheal Johnson,

5
Generalmente è una buona idea consentire la ricalibrazione nel caso in cui qualcosa venga incasinato la prima volta o il sistema debba essere ricalibrato per una configurazione diversa o per compensare l'invecchiamento dell'hardware ecc. Io, ad esempio, tendo a rovinare la calibrazione prima volta perché non so cosa dovrei fare.
Micheal Johnson,

3
Che ne dici di impostare il codice in modo che ci sia un modo per comandarlo per l'esecuzione (cioè inviare qualcosa tramite una porta seriale). In questo modo, non è necessario preoccuparsi della memoria non volatile e è possibile attivare la calibrazione durante la produzione in modo controllato.
alex.forencich,

Risposte:


18

Il microcontrollore potrebbe disporre di alcune EEPROM, memoria OTP, bit dei fusibili dell'utente, in cui è possibile impostare un flag.

Non esiste un "miglior metodo in C incorporato", la scrittura di memoria non volatile è diversa in ogni microcontrollore.

modificare:

VELOCE

I contenuti della memoria flash vengono cancellati durante la programmazione del dispositivo. Dopo la programmazione, tutti i byte che non sono stati scritti contengono 0xFF. Consultare la scheda tecnica per trovare un'area che può essere programmata in modo sicuro dall'interno del firmware in esecuzione.

EEPROM

Sebbene non sia garantito nei fogli dati, tutte le EEPROM che ho visto finora contenevano 0xFF: s quando venivano spedite dalla fabbrica (tranne quelle preprogrammate con un indirizzo MAC univoco, ma questo è esplicitamente documentato). Alcuni dispositivi / software di programmazione sono in grado di cancellare o programmare anche contenuti EEPROM. Alcuni possono essere protetti da scrittura, in modo permanente o reversibile.

OTP

La memoria programmabile una volta contiene sempre valori iniziali ben definiti, documentati nel foglio dati.

È sempre una buona idea includere un buon checksum come CRC32 con i dati scritti, per proteggere dalla corruzione dei dati causata da parti difettose, errori di trasmissione, raggi cosmici, qualunque cosa.


Se uso EEPROM o Flash imposteremo un Flag su true o False. Quindi quando leggiamo per la prima volta quella posizione di memoria quale sarebbe il valore casuale in quell'area di memoria.
ganeshredcobra,

2
Durante la produzione, ripristinare la EEPROM (o con un programmatore, se possibile, o eseguendo un piccolo programma tergicristallo, lampeggiarlo, accenderlo normalmente per alcuni secondi, quindi caricare il programma di produzione).
Nick T,

13

Tu hai detto:

L'unica opzione per eseguire quel codice deve eseguire nuovamente il flashing della scheda.

Altri hanno detto di usare EEPROM per memorizzare un flag per indicare quando è stata eseguita la funzione run_once (). Tuttavia, questo ha un inconveniente che è che se si esegue il reflash del microcontrollore, il flag ran_it_once in EEPROM è già stato impostato e la funzione run_once () non verrà eseguita. Se il tuo microcontrollore ha incorporato EEPROM, potrebbe essere possibile cancellare il flag ran_it_once quando esegui il riflash del microcontrollore, se il programmatore lo supporta.

Un modo migliore è avere numeri di versione sia nella EEPROM che nel codice. Quando il codice viene eseguito all'accensione, dovrebbe leggere il numero di versione da EEPROM e confrontarlo con il numero di versione memorizzato nel codice. Se non corrispondono, viene chiamata la funzione run_once () e l'atto finale del codice run_once () è scrivere il numero di versione del firmware in EEPROM. Ogni volta che si modifica il codice sorgente del firmware è necessario incrementare il numero di versione incorporato in esso.


1
Ciò avrebbe effettivamente lo stesso problema di un flag booleano se tutto ciò che l'utente facesse fosse eseguire il reflash del microcontrollore e dovesse essere nuovamente eseguito (in quello scenario). Risolverebbe sicuramente il problema se il firmware fosse aggiornato e dovesse essere rieseguito.
Taegost,

8

Scegli un microcontrollore che può scrivere / cancellare la propria memoria del programma. Dopo aver eseguito il codice in questione, fare in modo che l'ultima parte di detto codice sostituisca la prima istruzione con un salto che lo ignori. Opzionalmente, puoi anche cancellare il resto (magari sostituirlo con nop), in modo che non ci siano assolutamente zero possibilità che venga mai eseguito di nuovo.

Questo messaggio si autodistruggerà in 5..4 ...


1
Per quanto intelligente possa essere questa risposta, penso che sia inutilmente complesso. Forse potrebbe usare una nota che specifica che probabilmente dovrebbe essere usato solo se la memoria persistente al di fuori della memoria del codice non è disponibile?
skrrgwasme,

Anche se sono possibili altre soluzioni, penso che sia più facile da capire rispetto ad altre.
Giosuè,

1
Anche se fossero possibili altre soluzioni, penso che questo sarebbe molto difficile da capire a livello di codice sorgente.
un CVn del

La maggior parte dei PIC ha solo 35 istruzioni ... cosa potrebbe andare storto? ;)
rdtsc,

5

Dato che stai usando questo codice per la calibrazione, il mio suggerimento sarebbe quello di creare un processo esplosivo che esegua il codice di calibrazione come primo stadio e non lo abbia nemmeno sulla versione di produzione finita della scheda. Questo è simile alla risposta di apalopohapa, tranne diverso nel senso che avresti due carichi di programma separati: avere un processo di esplosione che fa lampeggiare il primo carico di programma che esegue tutte le calibrazioni e ne sputa i dati. Quindi prendere quei dati e incorporarli nei dati del secondo caricamento del programma.

Un vantaggio di questo approccio è che minimizzi assolutamente la quantità di spazio di archiviazione di cui hai bisogno: non è necessario archiviare il tuo codice una sola volta, solo i dati che genera. Avendo un processo esplosivo che carica due programmi separati, ti isola anche un po 'dai bug nel codice di inizializzazione che potrebbero indugiare altrimenti. Hai anche una certa flessibilità aggiuntiva se desideri rieseguire il tuo codice di calibrazione: invece di dover scrivere un codice aggiuntivo per cancellare qualsiasi bit indica che il tuo codice è stato eseguito (che potrebbe essere già stato cancellato accidentalmente), devi semplicemente rieseguire il tuo processo di scoppio.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.