Hallo, Ich habe die Demo "msp430x20x3_ta_uart2400.c" verwendet. Läuft prima. Ich bekomme jedoch immer beim Compilieren die Warung: Warning[Pa082]: undefined behavior: the order of volatile accesses is undefined in this statement ... Gemeint ist die Zeile "while (CCR0 != TAR)" der nachstehenden Funktion. // Function Transmits Character from RXTXData Buffer void TX_Byte (void) { BitCnt = 0xA; // Load Bit counter, 8data + ST/SP while (CCR0 != TAR) // Prevent async capture CCR0 = TAR; // Current state of TA counter CCR0 += Bitime; // Some time till first bit RXTXData |= 0x100; // Add mark stop bit to RXTXData RXTXData = RXTXData << 1; // Add space start bit CCTL0 = CCIS0 + OUTMOD0 + CCIE; // TXD = mark = idle while ( CCTL0 & CCIE ); // Wait for TX completion } Was hat dies zu bedeuten? Wie kann ich die Warung vermeiden? Gruss Klaus.
@ Klaus Ra. (klara) >Warning[Pa082]: undefined behavior: the order of volatile accesses is >undefined in this statement ... >Gemeint ist die Zeile "while (CCR0 != TAR)" der nachstehenden Funktion. >Was hat dies zu bedeuten? Na das, was dort steht. Die Reighenfolge des flüchtigen Zugriffs ist undefiniert. CCR0 und TAR sind Register. Auf beide muss ein Lesezugriff direkt ausgeführt werden (volatile). Aber der Vergleich sagt nicht, welcher von beiden Werten zuerst gelesen wird (Reihenfolge, order). Das kann bisweilen undefinierte Ergebnisse haben, zumal TAR sich laufend ändert. >Wie kann ich die Warung vermeiden? Zunächst ist dein Konstrukt sehr merkwürdig, um nicht zu sagen Käse.
1 | while (CCR0 != TAR) // Prevent async capture |
2 | CCR0 = TAR; // Current state of TA counter |
Du prüfst, ob sie verschieden sind, Wenn ja, dann wird CCR0=TAR zugewiesen. Wenn TAR läuft ist das eine Endlosschleife, denn beim nächsten Vergleich ist TAR schon weitergelaufen. Ausser TAR läuft mit Prescaler. Sauber wird der Vergleich durch Zwischenvariablen, damit wird die Reihenfolge des Zugriffs eindeutig definiert.
1 | uint16_t tmp_TAR; |
2 | uint16_t tmp_CCR0; |
3 | |
4 | tmp_TAR = TAR; |
5 | tmp_CCR0 = CCR0; |
6 | |
7 | while(tmp_CCR0 != tmp_TAR) { |
8 | CCR0= = TAR; |
9 | tmp_TAR = TAR; |
10 | tmp_CCR0 = CCR0; |
11 | }
|
Was aber logisch hier sowieso egal ist, weil so oder so am Ende CCR0==TAR ist. Also reicht ein
1 | CCR0= = TAR; |
MFG Falk
Hallo Falk, vielen Dank für Deine Antwort. Mir fällt es noch schwer so manche Demo's nachzuvollziehen. Im "MSP430x2xx Family Userguide", slau144d.pdf, wird der Prozessor beschrieben. Es wäre schön, wenn man dabei gleich noch ein paar Beispiele gebracht hätte. Und in der IAR Workbench gibt es diverse Headerfiles. Es fällt schon schwer zwischen IAR und TI die richtigen Schlüsse zu ziehen. Als Beispiel sei hier nur allein mein Problem zu sehen: CCR0 TAR. CCR0 gibt es nicht, aber ein TACCR0. Und dann doch in Figure 12-1 taucht auch einmal CCR0 auf. Auch ja, einen 16-bit Timer nennen sie wohl TAR. Das Ganze läuft wohl wieder auf "Versuch" und "Irrtum" hinaus. Hast Du vielleicht ein paar Tipps? Gruss Klaus.
Naja, TAR ist das Timer-Register vom Timer A. Warum die da noch ein define für das CCR0 drin haben, ist mir auch unklar, TACCR0 wäre die korrekte Bezeichnung. Übrigens sind die Header-Files so gestaltet, dass man die Register-Bezeichnungen aus den User-Guides direkt verwenden kann. Und die Demos sind ja immer für den IAR Compiler. Und bisher haben alle funktioniert, die ich getestet hab.
Naja, das CCR / TACCR ist "historisch gewachsen". Ich glaube bis zum Stand slau049b des User Guides hießen die Register CCx. Danach dann Timerbezogen TACCRx, TBCCRx usw. In den Headern sind die alten CCR-Bezeichner noch drin, ich denke mal aus Kompatibilitätsgründen.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.