2012-01-10 21 views
11

Sto facendo un po 'di sviluppo in C con un chip STM32F107 e, ad un certo punto, il dispositivo ha iniziato a reimpostarsi quando chiamo una funzione specifica. Non ho un debugger e il mio debug è solo testo su una porta seriale.Come eseguire il debug delle reimpostazioni impreviste in un dispositivo STM32?

Ho usato alcuni altri microcontrollori in cui sono stato in grado di accedere a un registro per vedere la causa del reset, ma non riesco a trovare un equivalente per questo dispositivo. Sono a conoscenza delle eccezioni hardware del Cortex-M3, ma non so se uno di questi viene attivato perché non riesco a mandare del testo su usart quando sono all'interno di quei gestori (forse perché il mio TX le funzioni usano le interruzioni?).

Così, ho deciso di chiedere alle persone con più esperienza di me in questo dispositivo: cosa si fa solitamente per eseguire il debug di situazioni come queste?

EDIT

Uno degli sviluppatori attivato il cane da guardia WWDG ed è stato resettare l'hardware prima che potessi ottenere la mia informazioni dai gestori degli errori. È stato un errore grave dovuto alla chiamata di una funzione da un puntatore che puntava verso il punto sbagliato. Tuttavia, terrò questa domanda nella speranza che qualcuno possa fornire maggiori dettagli (o materiale a riguardo) per puntare al codice C dai registri salvati, diciamo, un Hard Fault (idea @dwelch).

risposta

11

Il Cortex M3 offre eccellenti funzioni di gestione dei guasti che semplificheranno la vita. Quando si verifica un errore, vengono automaticamente memorizzati diversi registri come PC e LR, mentre i registri di stato degli errori segnalano l'errore bus, ecc.

È necessario implementare un buon gestore degli errori (ad esempio, il gestore degli errori gravi qui: http://blog.frankvh.com/2011/12/07/cortex-m3-m4-hard-fault-handler/) per stampare i registri impilati ed eseguire il debug dei registri di stato dei guasti.

È necessario utilizzare l'UART per la stampa, basta scrivere la propria versione personalizzata di printf per l'utilizzo dal gestore degli errori che non dipende dagli interrupt. Basta scrivere byte direttamente per accedere al registro dati Tx e interrogare per il completamento dei byte.

1

Dato che non hai un debugger, ti suggerirei di trovare alcune periferiche sul microcontrollore per aiutarti. Forse hai un LED che puoi attivare o un semplice pin GPIO che non è in uso e che puoi collegare ad un oscilloscopio. Se si imposta un pin GPIO abbastanza lentamente (non più veloce di 1 Hz e forse più lentamente a seconda del misuratore) è possibile utilizzare un voltmetro anziché un oscilloscopio. Inserisci il codice per alternare il LED o il pin GPIO in ciascuno dei gestori di eccezioni uno alla volta finché non lo rintracci. Se hai più di un pin GPIO disponibile puoi accelerare il processo. Puoi anche scrivere un wrapper per la funzione specifica che sta causando il reset. La funzione wrapper invierà un elenco di interrupt che vengono abilitati appena prima dell'esecuzione della funzione di interruzione. In questo modo non devi perdere tempo a testare quelli che non sono abilitati.

Un vantaggio dei pin GPIO in questo caso è che non richiedono un interrupt. È meglio stare lontano da tutto ciò che richiede un'interruzione (come la USART in questo caso). Se il ripristino è causato da un'eccezione con priorità più alta, il codice di debug non verrà mai eseguito.

È anche comune che il ripristino sia causato da un puntatore non inizializzato. Un puntatore a funzione impostato su zero farebbe sembrare l'esecuzione molto simile a un reset. In questo caso, il codice di inizializzazione USART viene probabilmente eseguito prima che un byte possa essere completamente trasmesso da USART, il che renderebbe l'USART inutile come strumento di debug in questa istanza.

1

Quando si dice reset, penso che in termini di si colpisce il vettore di reset, non uno degli interrupt o gestori.Stai dicendo che ripristina il chip e avvia nuovamente il tuo software o stai dicendo che è sospeso da qualche parte? o hai la tabella vettoriale tutto punto sul vettore di reset?

Come procedere dipende da cosa si sta realmente vedendo, è necessario essere più chiari o specifici, o forse si vuole aiutare a capirlo.

Normalmente mappo i vettori non utilizzati su una semplice riga di codice che si dirama su se stesso. Più tardi potrò rimappare alcuni di essi in codice reale.

la corteccia-m è molto bella in quanto è possibile indicare il codice C. Se pensi di avere un'eccezione, punta a una routine che afferra qualcosa che ti aiuta a capire in quale modalità ti trovi, il registro dei collegamenti potrebbe avere quell'informazione, o un csr da qualche parte, stampalo e vai in un ciclo infinito . Riempi le parti inutilizzate della tabella vettoriale con l'indirizzo a questa funzione di debug generica.

Da lì è necessario capire perché si sta verificando tale eccezione, potrebbe essere qualcosa come un accesso non allineato, ad esempio. Potrebbe essere che tu abbia generato un'interruzione quando provi a inizializzare un dispositivo prima di impostare completamente il gestore, chissà.

modifica la tua domanda con più risposte o informazioni mentre lavori attraverso questo.

0

La cosa "giusta" da fare, purtroppo non è pratica con un STM32. Ciò significherebbe inserire un grosso gestore di eccezioni che abbia conoscenza del codice sorgente e che possa scaricare lo stack e fornire lo stack di chiamate completo e il numero di riga che causano l'errore. Ciò richiederebbe l'aggiunta di tutte le informazioni di debug dalla tua applicazione alla memoria flash dell'STM32, e ciò non è pratico.

Ci sono modi per ingannare l'IDE a volte per fornire lo stack di chiamate. Darei i dettagli ma ho dimenticato di scriverli, quindi ho dimenticato. Penso che debba cambiare manualmente il puntatore dello stack da un registro ombra a un altro.

Quello che faccio di solito è mettere un punto di interruzione nel vettore dell'eccezione di errore grave, e quindi guardare tutti i registri quando il punto di interruzione colpisce. Considera le prove forensi di un omicidio, fatte con esplosivi plastici. I valori dei registri ti daranno idee. I valori di registro che iniziano con 0x20000000 sono gli indirizzi RAM. I valori di registro che iniziano con 0x08000000 sono indirizzi Flash. Apri il disassemblatore e digita quegli indirizzi. Probabilmente andrà direttamente alla variabile o alla funzione in quelle posizioni di memoria. Se ciò non aiuta, guarda il puntatore dello stack. Guarda le posizioni di memoria nel puntatore dello stack e fai lo stesso trucco. Ho sempre trovato abbastanza shrapnel per localizzare la funzione in cui si stava verificando l'eccezione.

3

A parte ciò che è stato menzionato sui gestori di interrupt per il debug, alcuni ST micros hanno anche un registro di origine di reset che è possibile leggere all'accensione (ovvero dopo un reset). Per la famiglia di corteccia M (m0/m3/m4) il registro è RCC_CSR. http://www.st.com/web/en/resource/technical/document/reference_manual/DM00031020.pdf

Sfortunatamente non si sarebbe in grado di sapere se le specifiche, come ad esempio un errore grave, ma sarebbe dire se il watchdog (finestra o indipendente) era scattato.