www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik C Programmierung: switch Anweisung mit zwei Argumenten?


Autor: Bastler0815 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
bei einem Beispielprogramm von TI bin ich über eine switch - Anweisung 
gestolpert, der 2 Argumente übergeben werden. Kann mir das jemand 
erklären?
Es steht dabei, dass es eine effiziente Implementierung wäre, aber ich 
werde nicht so ganz schlau daraus.



// Timer_A3 Interrupt Vector (TAIV) handler
#pragma vector=TIMERA1_VECTOR
__interrupt void Timer_A(void)
{
  switch (TAIV, 10)        // Efficient switch-implementation
  {
    case  2:                                // TACCR1
      P1OUT ^= 0x01;                        // Toggle P1.0
      TACCR1 += 50000;                      // Add Offset to TACCR1
      break;
    case  4: break;                         // TACCR2 not used
    case 10: break;                         // Overflow not used
  }
}

Autor: lucem (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Garantiert kein ANSI-C konformes Verhalten.
Kann es sein, dass das eine Spracherweiterung von TI auf dem hauseigenen 
Compiler ist?

Autor: Bastler0815 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es sollte lt. Beschreibung auch mit IAR laufen:
//  Built with CCE Version: 3.2.0 and IAR Embedded Workbench Version: 
3.41A

Autor: yalu (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Doch, das ist Standard-C. Der Ausdruck a,b evaluiert sowohl a als auch
b und liefert als Ergebnis b. In diesem Fall wird (vielleicht zu
Debug-Zwecken) immer in case 10 verzweigt.

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ob das ganze ANSI-(oder wie auch immer)konform ist, weiß ich nicht.
Es ist jedenfalls eine Spezialität des IAR-Compilers, der unter 
bestimmten Voraussetzungen aus der switch-Anweisung einen optimierten 
Code generiert.

In neueren Versionen müsste es eigentlich heißen:
// Timer_A3 Interrupt Vector (TAIV) handler
#pragma vector=TIMERA1_VECTOR
__interrupt void Timer_A(void)

switch (__even_in_range(TAIV, 10))          // Efficient switch-implementation
  {
    case  2:                                // TACCR1
      P1OUT ^= 0x01;                        // Toggle P1.0
      TACCR1 += 50000;                      // Add Offset to TACCR1
      break;
    case  4: break;                         // TACCR2 not used
    case 10: break;                         // Overflow not used
  }

Der TIMERA1_VECTOR hat mehrere Quellen, wobei in TAIV vermerkt ist, 
welche Quelle gerade in der ISR bearbeitet wird. Es ist hierbei bekannt, 
dass der Wert in TAIV maximal 10 sein kann (->...(TAIV,10)...) und 
geradzahlig ist (__even_in_range).
Dann kann eine Sprungtabelle angelegt werden, auf die einfach 
zugegriffen werden kann, indem der aktuelle TAIV-Wert auf den Program 
Counter addiert wird. Die Sprungtabelle verzweig dann in die 
unzterschiedlichen cases.
Das ist alles ;-)

Autor: Bastler0815 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Viele Dank,
das hilft mir weiter!

Funktioniert das dann auch so mit dem CCE - Compiler?

Autor: Stefan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Den CCE kenne ich nicht.
Ich denke aber, dass das (zumindest in dieser Notation) nur im IAR 
funktioniert. Vielleicht hat der CCE aber einen ähnlichen "Mechanismus". 
Da sollte aber dessen User-Guide weiterhelfen...

Autor: I_ H. (i_h)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das scheint schon Ansi-C zu sein, der gcc mäkelt jedenfalls auch net. 
Ist übrigens teils schon witzig was der C Standard hergibt, der 
Klassiker:
        n = (anzahl + 3) / 4;
 
        switch(anzahl % 4) {
        case 0:        do { ziel[stelle] = quelle[stelle]; stelle++;
        case 3:             ziel[stelle] = quelle[stelle]; stelle++;
        case 2:             ziel[stelle] = quelle[stelle]; stelle++;
        case 1:             ziel[stelle] = quelle[stelle]; stelle++;
                       } while(--n > 0);
        }

Autor: routy (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
weia. ich werde wohl alt... werde mir mal dr. kawasakis gehirndauerlauf 
holen... ;-)

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
I_ H. wrote:

> Das scheint schon Ansi-C zu sein, der gcc mäkelt jedenfalls auch net.

Er wird aber dabei etwas völlig anderes tun. ;-)  Wie yalu schon
geschrieben hat, wird er zwar das Register TAIV auswerten, aber
anschließend fest zum Wert 10 in der switch-Anweisung verzweigen.

In der aktuellen IAR-Doku findet man darüber auch nichts mehr, sondern
nur die weiter oben beschriebene (Pseudo-)Funktion __even_in_range(),
die ganz offensichtlich eigens für diese Eigenheit der MSP430s
gezimmert worden ist (und die es dann auch nur bei der MSP430-Version
gibt).

Autor: Jorge (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es handelt sich um den Komma Operator und den gibts eigentlich nur bei 
C++ (nicht überladbar) oder beim normalen C mit Herstellerspezifischen 
Erweiterungen ist glaube ich nicht ANSI konform.

Autor: Andreas K. (a-k)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jorge wrote:

> Es handelt sich um den Komma Operator und den gibts eigentlich nur bei
> C++ (nicht überladbar)

Ist normales C seit K&R.

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas Kaiser wrote:

>> Es handelt sich um den Komma Operator und den gibts eigentlich nur bei
>> C++ (nicht überladbar)
>
> Ist normales C seit K&R.

Nur halt nicht in dieser etwas eigenwilligen semantischen Ausdeutung
da ganz oben. ;-)  Aber daher haben sie's ja offenbar auch korrigiert
und stattdessen den korrekten Weg mit __even_in_range() gewählt.

Autor: Peter (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Es handelt sich um den Komma Operator und den gibts eigentlich nur bei
> C++ (nicht überladbar)

type& operator , ( type )
{
}

Der MS-compiler kann das, ob es sinn macht ist eine andere Frage.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.