2015-08-06 20 views
6

Dato il seguente codice:Perché non ci deve essere più di un accesso in lettura con tipo volatile all'interno di un punto di sequenza?

static volatile float32_t tst_mtr_dutycycle; 
static volatile uint8_t tst_mtr_direction; 
static volatile uint32_t tst_mtr_update; 

void TST_MTR_Task(void) 
{ 
    if (tst_mtr_update == 1U) 
    { 
     tst_mtr_update = 0; 

     MTR_SetDC(tst_mtr_dutycycle, tst_mtr_direction); 
    } 
} 

ho trovato problemi con MISRA C 2012 Rule-13.2 e ho deciso di fare qualche ricerca. Ho trovato qui (http://archive.redlizards.com/docs/misrac2012-datasheet.pdf) che:

non è posta alcuna accesso più di un lettura con il tipo di volatili-qualificata entro punto una sequenza

La cosa qui è che io porto' Sono stato in grado di trovare un esempio o una spiegazione che chiarisca il motivo per cui non ci deve essere più di un accesso in lettura con tipo di tipo volatile all'interno di un punto di sequenza.

Ho bisogno di trovare una soluzione per il codice di violazione ma non mi è chiaro cosa fare.

Ora so che non ci deve essere più di un accesso in lettura con tipo di tipo volatile all'interno di un punto di sequenza. La domanda è, perché? e ho bisogno di sapere perché per implementare una soluzione e per spiegare a tutti qui perché sto cambiando il codice.

Saluti.

risposta

4

La giustificazione per la regola è:

(Obbligatorio) Il valore di un'espressione ei suoi effetti collaterali persistenti sarà lo stesso in tutto consentito valutazione ordini

Se più di una variabile qualificata volatile viene letta tra i punti di sequenza, quindi non è specificato che viene letto per primo. Leggere una variabile volatile è un effetto collaterale.

La soluzione è quella di ordinare in modo esplicito la legge:

void TST_MTR_Task(void) 
{ 
    if (tst_mtr_update == 1U) 
    { 
     tst_mtr_update = 0; 

     float32_t dutycycle = tst_mtr_dutycycle; 
     uint8_t direction = tst_mtr_direction; 
     MTR_SetDC(dutycycle, direction); 
    } 
} 
+0

Perfetto !! Grazie! Questa risposta può aiutarmi anche con altri problemi. Mi mancava la parte degli effetti collaterali della regola. – m4l490n

+0

C'è qualcosa che non mi è molto chiaro. Perché la lettura di una variabile volatile è un effetto collaterale? – m4l490n

+1

@ m4l490n perché questo è ciò che è "volatile" - specifica che le scritture e le letture non possono essere memorizzate nella cache o riordinate.Un esempio potrebbe essere un registro hardware, in cui le letture possono restituire valori diversi su letture successive e provocare azioni arbitrarie. – ecatmur

2

Non ci sono punti di sequenza tra il recupero gli argomenti di una chiamata di funzione. Quindi l'ordine che vengono recuperati non è definito dallo standard. OTOH, il compilatore deve mantenere l'ordine di accesso agli oggetti volatili, quindi questa è una contraddizione.

Fetch le variabili da temps non volatili e usare quelli per la chiamata di funzione:

float32_t t1 = tst_mtr_dutycycle; 
uint8_t t2 = tst_mtr_direction; 
MTR_SetDC(t1, t2); 

Nota questo è in realtà un problema per lo standard C e non solo legato al MISRA-conformità.

Come sembra che tu abbia più problemi relativi alla conformità standard, potresti voler mantenere lo standard sotto il cuscino.

+0

Grazie per aver chiarito che "Non ci sono punti di sequenza tra il recupero degli argomenti di una chiamata di funzione". – m4l490n

+1

@ m4l490n: http://port70.net/~nsz/c/c11/n1570.html#Cp1 – Olaf

+0

Grazie, lo controllerò. – m4l490n