www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Umwandlung Union-Struktur IAR-> ICC AVR


Autor: Jan Pater (fire)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Morgen zusammen

Eine kurze Frage:

Wie müsste die folgende IAR-Anweisung in ICC AVR (oder von mit aus auch 
gcc) aussehen?
00100 __regvar __no_init union _fastTemp{
00101   unsigned int word;
00102   struct{
00103     unsigned char LByte;
00104     unsigned char HByte;  
00105   };
00106 } fastTemp @12;



Mein aktueller Ansatz sieht so aus:
union temp{
    unsigned int word;
     struct egal{
            unsigned char LByte;
        unsigned char HByte; 
    }egal;
  }fastTemp;  

(Den Bezeichner "egal" habe ich gewählt da mir gerade kein anderer Name 
einviel, der Compiler aber keine Struktur ohne Namen erstellen will ^^)

Allerdings verschwindet da dann immer das HByte sobald ich mir das 
Programm im Simulator ansehe.

Autor: Jan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Keiner eine Idee?

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> ... der Compiler aber keine Struktur ohne Namen erstellen will

Will er das nicht? Das ist merkwürdig. Hat Imagecraft da irgendwelche 
Probleme?

Warum wechselst Du von IAR zu Imagecraft?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jan Pater wrote:

> Mein aktueller Ansatz sieht so aus:
>
>
union temp{
>     unsigned int word;
>      struct egal{
>             unsigned char LByte;
>         unsigned char HByte;
>     }egal;
>   }fastTemp;
> 
>
> (Den Bezeichner "egal" habe ich gewählt da mir gerade kein anderer Name
> einviel, der Compiler aber keine Struktur ohne Namen erstellen will ^^)
>
> Allerdings verschwindet da dann immer das HByte sobald ich mir das
> Programm im Simulator ansehe.

Was heist 'verschwinden'? Ein Byte kann nicht verschwinden.

Zum Problem:
Macht der Compiler ein Padding? Sprich schiebt er zwischen
den LByte unf HByte ein zusätzliches Byte ein? Mach doch mal
einen sizeof(fastTemp) und schau dir das Ergebnis an. Werte
ungleich 2 sind beunruhigend.

Ansonsten: Zeig doch mal etwas Code dazu. Obiges ist ja nur
die Deklaration einer Dtaenstruktur. Damit lässt sich
nur schwer feststellen, was denn in deinem Programm schief geht.
Am besten wäre es, wenn du rund um die Datenstruktur ein kleines
Testprogramm schreiben würdest, welches
* minimal ist
* den Fehler zeigt
So werden sie dann am schnellsten geholfen.


Autor: mthomas (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sieht so aus, also wuerden gleich mehrere herstellerspezifische IAR 
Erweiterungen genutzt, die im "aktuellen Ansatz" einfach nicht portiert 
wurden.

Soweit erinnert (habe wenig praktische Erfahrung mit IAR-EWAVR):
__regvar  - C-Variable/Strucutur/Union an ein Hardware-Register binden
__no_init - keine Initialisierung beim Startup (da keine "echte 
Speicheradresse dafür)
@12; - legt Speicheraddresse der Variable/Struct/Union fest.

Das ganze dient wohl dazu, möglichst schnell die beiden Bytes einer 
16-bit Variable bei "13:12" zu lesen/zu schreiben. Statt sich mit 
herstellerspezifischen Erweiterungen herzumzuschlagen, dürfte es 
einfacher und portabler sein, die Funktionalität mit ein paar 
Inline-Funktionen/Makros nachzubilden.


Autor: Jan Pater (fire)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das ganze bezieht sich auf das Atmel-Projekt AVR443.

Zu finden hier: 
http://www.atmel.com/dyn/resources/prod_documents/...

IAR-Quellcode hier: 
http://www.atmel.com/dyn/resources/prod_documents/avr443.zip



Die fastTemp-Variable wird in der PCInt0-Interruptroutine benötigt.

Die sieht so aus:
#pragma interrupt_handler PCINT0_handler:iv_PCINT0
//!
void PCINT0_handler()
{
  unsigned char *pTemp;
  fastTemp.word = ((PIN_HALL & hallMask)>>1);  // Read Hall, Mask Pins, shift to use as pointer offset
//  Line below is desirable performance wise, but causes an internal error in compiler
//  fastTemp.LByte = (PIN_HALL & HALL_MASK)>>1;   // Read Hall, Mask Pins, shift to use as pointer offset

  pTemp = pDrvPattern + fastTemp.word;
//  TCCR0A = fastTemp.HByte; //Disable PWM outputs (and thereby close low side FET)
//  TCCR2A = fastTemp.HByte; //Disable PWM output (and thereby close low side FET)

  PORT_MC = *(pTemp);    //Change drive levels on high side

  TCCR0A = *(pTemp + PATTERN_COM0_OFFSET);    // Reconfigure output compare operation for T0
  TCCR2A = *(pTemp + PATTERN_COM2_OFFSET); // Reconfigure output compare operation for T2
  count--;
}


Wenn ich die Struktur so aufbauen will (also keinen Namen angebe):
union temp{
    unsigned int word;
     struct {
            unsigned char LByte;
           unsigned char HByte; //Hbyte = Zero
    };
  }fastTemp;  

Gibt mir der Compiler die Fehlermeldung:

sensor_three_phase_BLDC.c(108): field name missing


Mit verschwinden meine ich, das ich im AVR-Studio die Struktur über 
einen Watch beobachte.

Sobald aber der erste Programmdurchlauf beendet ist, habe ich nur noch 
das LowByte im Watch, das HByte ist verschwunden.

Autor: Rufus Τ. Firefly (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vollkommen anonyme Strukturen sind eine Erweiterung des C-Standards und 
nicht von jedem Compiler unterstützt.

union tagname_u
{
  unsigned int word;
  struct tagname_s
  {
    unsigned char LByte;
    unsigned char HByte; //Hbyte = Zero
  } name_s;
} name_u;  

Du kannst tagname_s/tagname_u weglassen (sofern Du nirgends weitere 
Instanzen des gleichen Datentyps deklarieren willst), aber nicht 
name_s/name_u.

Wenn AVR-Studio Dinge verschwinden lässt, würde ich annehmen, daß das 
ein Fehler im AVR-Studio-Debugger ist.

Autor: Johnny B. (johnnyb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen

Schlage mich gerade mit dem IAR rum und bin auf diesen thread gestossen.
IAR verwendet leider neuerdings(?) solche anonymen Strukturen und Unions 
in den Headerdateien zu den Mikrocontrollern mit den 
Peripheriedefinitionen.

Frage:
Wie bekommt man mit der obigen Deklaration denn einen Pointer auf LByte 
und HByte?

Ich habs (auf das obige Beispiel angepasst) versucht mit:

unsigned char *PointerAufByte;

PointerAufByte = (unsigned char *)&LByte;

bzw.

PointerAufByte = (unsigned char *)&HByte;

In "PointerAufByte" steht dann aber leider nicht immer was gescheites 
drin.
Hat jemand eine Idee, wie man das machen müsste, damit es immer klappt?

Autor: Johnny B. (johnnyb)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ooooops, es geht genau wie ich oben geschrieben hatte. In einem Define 
hatte ich nur schon vorher etwas falsches definiert gehabt und so waren 
einige Bezeichnungen vertauscht.

Hat sich also erledigt und läuft jetzt.

Schönes Wochenende

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.