2012-12-29 22 views
5

Ho un problema con un hardfault che appare in momenti apparentemente casuali in cui un puntatore punta a un indirizzo A5 o FF (il mio spazio di memoria consentito è lontano sotto a 80000000 e oltre). Sembra essere sempre lo stesso puntatore con questi due valori.Il puntatore ha assegnato in modo casuale valori misteriosi (A5A5A5A5 e FFFFFFFF) su uno stm32 utilizzando freeRTOS causando un errore.

sto usando un sistema embedded in esecuzione un processore STM32F205RE che comunica con un/bluetooth/chip GPS fm chiamato cg2900 dove si verifica questo errore.

Utilizzando un debugger, è possibile notare che il puntatore punta rispettivamente all'indirizzo A5 e FF durante alcuni test. Tuttavia sembra accadere a volte casuali, a volte riesco a eseguire il test per un'ora senza un fallimento mentre altre volte si blocca 20 secondi.

Io corro FreeRTOS come scheduler per passare da compiti diversi (uno per radio, una per bluetooth, una per altra manutenzione periodica) che potrebbe interferire in qualche modo.

Quale può essere la causa di questo? Poiché è in esecuzione hardware personalizzato, non è possibile escludere che si tratti di un problema hardware (potenzialmente). Qualche suggerimento (nessun gioco di parole) su come affrontare il debug del problema?

EDIT:

Dopo ulteriori indagini, sembra che sia molto casuale in cui si blocca, non solo tale puntatore specifica. Ho usato un gestore hardfault per ottenere i seguenti valori di questi registri (tutti i valori in esadecimale):

semi-lungo periodo prima di schianto (minuti):

R0 = 1 
R1 = fffffffd 
R2 = 20000400 
R3 = 20007f7c 
R12 = 7 
LR [R14] = 200000c8 subroutine call return address 
PC [R15] = 1010101 program counter 
PSR = 8013d0f 
BFAR = e000ed38 
CFSR = 10000 
HFSR = 40000000 
DFSR = 0 
AFSR = 0 
SCB_SHCSR = 0 

brevissimo termine prima di crash (secondi):

R0 = 40026088 
R1 = fffffff1 
R2 = cb3 
R3 = 1 
R12 = 34d 
LR [R14] = 40026088 subroutine call return address 
PC [R15] = a5a5a5a5 program counter 
PSR = fffffffd 
BFAR = e000ed38 
CFSR = 100 
HFSR = 40000000 
DFSR = 0 
AFSR = 0 
SCB_SHCSR = 0 

un altro corto (secondi):

R0 = 0 
R1 = fffffffd 
R2 = 20000400 
R3 = 20007f7c 
R12 = 7 
LR [R14] = 200000c8 subroutine call return address 
PC [R15] = 1010101 program counter 
PSR = 8013d0f 
BFAR = e000ed38 
CFSR = 1 
HFSR = 40000000 
DFSR = 0 
AFSR = 0 
SCB_SHCSR = 0 

Dopo un lunghissimo periodo (1 ora +):

R0 = e80000d0 
R1 = fffffffd 
R2 = 20000400 
R3 = 2000877c 
R12 = 7 
LR [R14] = 200000c8 subroutine call return address 
PC [R15] = 1010101 program counter 
PSR = 8013d0f 
BFAR = 200400d4 
CFSR = 8200 
HFSR = 40000000 
DFSR = 0 
AFSR = 0 
SCB_SHCSR = 0 

sembra bloccarsi nello stesso punto la maggior parte del tempo. Ho regolato la memoria in base ai suggerimenti precedenti, ma ho ancora lo stesso problema.

Grazie per il vostro tempo!

Cordiali saluti

+1

Questi sembrano byte magici failsafe. Sei sicuro di non avere un puntatore ciondolante, un NULL non qualificato o un array locale restituito da qualche parte? –

+0

@ H2CO3 Sì, sembrano davvero dei byte magici. Il puntatore è alla base di un array (ambito globale) e ho già una condizione che controlla che non scriva al di fuori di esso. Il puntatore stesso non viene mai assegnato una volta che è stato inizializzato alla base dell'array. – ChewToy

+0

se potessi aggiungere del codice reale, sarebbe di grande aiuto. –

risposta

1

gira che il problema è stato causato dalla memoria. Poiché eseguivo il processore con la massima velocità (120 Mhz) e un'alimentazione a 1,8 volt (progettata principalmente per 3 volt), avevo alcune condizioni di gara con la memoria. Risolto usando uno stato di attesa più alto.

4

Nel suo commento si parla che questo puntatore viene esplicitamente assegnato una volta poi mai scritto. In tal caso, dovresti almeno dichiararlo const e utilizzare l'inizializzazione anziché l'assegnazione, ad es.

arraytype* const ptr = array ; 

che consentirà al compilatore di rilevare eventuali scritture esplicite. Tuttavia è più probabile che il puntatore sia corrotto da un errore di codifica non correlato.

Il debug su chip Coretx-M3 supporta i punti di accesso ai dati; dovresti impostare un tale punto di interruzione sul puntatore in questione in modo che tutti gli accessi in scrittura siano intrappolati. Avrai una pausa sull'inizializzazione, poi su quella sulla modifica - intenzionale o meno.

Possibili cause sono l'overrun di un array adiacente o di una pila di fili.

+0

Grazie per il tuo feedback! Il motivo per cui non è una costante è che il codice può utilizzare un paio di buffer separati a seconda dell'attuale set di funzionalità sul dispositivo specifico in esecuzione. Solo per scopi di debug ho provato a farlo const per ora e comunque il compilatore sembra ancora accettare il codice, quindi non sembra essere il problema almeno. – ChewToy

+0

Per quanto riguarda i breakpoint di accesso ai dati, come potrei attivarli? Non sono stato in grado di trovare alcun dettaglio su google o sul sito web ST/documenti. Sto usando l'editor Ride7 e debugging attraverso un Rlink Pro, ma non riesco a trovare questa funzionalità all'interno dell'IDE. Qualcuno ha qualche raccomandazione o esempio su come impostarlo manualmente (tramite codice asm o qualcosa del genere)? – ChewToy

+0

@ChewToy: Non ho usato RIDE, ma Google suggerisce forse: * Debug-> comandi avanzati-> breakpoint avanzati *. Suggerisco di consultare il manuale del prodotto; la capacità può essere specifica dell'obiettivo e/o del debugger. – Clifford

3

Se si è tentato di spostare l'array e continua con lo stesso problema,

poi qualche compito è straripante.

Come lei ha ricordato, si sta utilizzando FreeRTOS, e perché il comportamento è casuale è probabile che qualcosa non va con le impostazioni STACK_SIZE nelle chiamate a xTaskCreate

Questo di solito accade quando la dimensione allocata è meno di quello che davvero bisogno.

Se si legge la documentazione relativa a usStackDepth, si è notato che rappresenta un moltiplicatore e non il numero di byte.

io personalmente escluderei problemi hardware nel vostro bordo embedded e mi concentrerò sui problemi di configurazione del FreeRTOS

+0

Grazie per la tua risposta! Potrebbe essere il caso. Ho effettivamente usato xTaskCreate come se fosse la dimensione in numero di byte! Vedrò di approfondire la questione con alcuni test quando torno al lavoro dopo la vigilia di Capodanno – ChewToy

+0

Ho effettivamente avuto il problema che stavi suggerendo, ma non sembrava aiutare. Ho ancora gli stessi problemi di prima. Anche se sono ancora d'accordo sul fatto che sembra un overflow – ChewToy

+0

Guardando i dati che hai aggiunto, ho notato che il tuo "link register" fa sempre riferimento a una posizione RAM, e una volta si riferisce alla porta DMA1 ... questo mi fa pensa che l'inizializzazione del trasferimento DMA sia interrotta da un'attività con priorità più alta, quindi dovresti proteggere il tuo codice in una sequenza xSemaphoreTake (...) ~ xSemaphoreGive (...) Puoi leggere ulteriori informazioni su [mutex] (http: // www.freertos.org/Real-time-embedded-RTOS-mutexes.html). – RTOSkit