2015-08-06 17 views
6

den folgenden Code Gegeben:Warum darf es innerhalb eines Sequenzpunkts nicht mehr als einen Lesezugriff mit einem Typ mit flüchtiger Qualifizierung geben?

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); 
    } 
} 

ich Probleme mit MISRA C 2012 Regel 13.2 und ich beschlossen, einige der Forschung zu machen gefunden. Ich fand hier (http://archive.redlizards.com/docs/misrac2012-datasheet.pdf), dass:

es wird innerhalb einer Sequenz Punkt nicht mehr als ein Lesezugriff mit flüchtigem qualifiziertem Typ sein hier

Die Sache, dass ich haven ist‘ Ich konnte ein Beispiel oder eine Erklärung finden, die deutlich machen, warum es innerhalb eines Sequenzpunkts nicht mehr als einen Lesezugriff mit einem Typ mit flüchtiger Qualifizierung geben darf.

Ich muss eine Lösung für den verletzenden Code finden, aber mir ist nicht wirklich klar, was zu tun ist.

Ich weiß jetzt, dass es nicht mehr als einen Lesezugriff mit flüchtigen qualifizierten Typ innerhalb eines Sequenzpunktes geben soll. Die Frage ist, warum? und ich muss wissen warum, um eine Lösung zu implementieren und jedem hier zu erklären, warum ich den Code ändere.

Grüße.

Antwort

4

Die Begründung für die Regel lautet:

(Erforderlich) Der Wert eines Ausdrucks und seine anhaltende Nebenwirkungen das gleiche unter allen zulässig sein soll Bewertungsaufträge

Wenn mehr Da eine flüchtige qualifizierte Variable zwischen den Sequenzpunkten gelesen wird, ist sie nicht spezifiziert, was zuerst gelesen wird. Das Lesen einer flüchtigen Variablen ist ein Nebeneffekt.

Die Lösung ist ausdrücklich auf, um die für lautet:

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

Perfekt !! Vielen Dank! Diese Antwort kann mir auch bei anderen Problemen helfen. Mir fehlte der Nebeneffekt der Regel. – m4l490n

+0

Da ist etwas, was mir nicht ganz klar ist. Warum ist das Lesen einer volatilen Variablen ein Nebeneffekt? – m4l490n

+1

@ m4l490n, denn dafür steht "volatile" - es gibt an, dass Schreib- und Lesevorgänge nicht zwischengespeichert oder neu angeordnet werden können.Ein Beispiel wäre ein Hardware-Register, in dem Lesevorgänge bei aufeinanderfolgenden Lesevorgängen unterschiedliche Werte zurückliefern und zu willkürlichen Aktionen führen können. – ecatmur

2

Es sind keine Sequenzpunkte zwischen den Argumenten eines Funktionsaufrufs zu holen. Die Reihenfolge, in der sie abgerufen werden, ist vom Standard nicht definiert. OTOH, muss der Compiler die Reihenfolge der Zugriffe auf flüchtige Objekte beibehalten, also ist dies ein Widerspruch.

die Variablen in der nichtflüchtigen temps Fetch und die für den Funktionsaufruf verwenden:

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

Hinweis dies für Standard-C tatsächlich ein Problem ist und nicht nur im Zusammenhang mit MISRA-Compliance.

Da Sie scheinbar mehrere Probleme hinsichtlich der Standard-Compliance haben, möchten Sie vielleicht die standard unter Ihrem Kopfkissen aufbewahren.

+0

Vielen Dank für die Klärung, dass "Es gibt keine Sequenzpunkte zwischen dem Abrufen der Argumente eines Funktionsaufrufs". – m4l490n

+1

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

+0

Danke, ich werde das überprüfen. – m4l490n