mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Little oder Big Endian im mega64?


Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

wo finde ich Informationen darüber, ob der atmega64 (bzw. die Familie) 
Little oder Big Endian verwendet?
Das Gleiche für den H8S/2367 von Hitachi...?

Grüße

Christian

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Christian (Gast)

>wo finde ich Informationen darüber, ob der atmega64 (bzw. die Familie)
>Little oder Big Endian verwendet?

AFAIK Little Endian. Sieht man an den merkwürdigen HEX-Dumps.

http://www.mikrocontroller.net/articles/Digitaltec...

Spielt aber kaum eine Rolle. In ASM machst du das sowieso alles "per 
Hand", in C macht es der Compiler.

MFG
Falk

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

Bewertung
0 lesenswert
nicht lesenswert
Es gibt nicht viele Stellen, wo man das beim AVR überhaupt mitkriegt:
- Anordnung der Bytes im Flash bei Zugriff per LPM,
- Reihenfolge der Return-Adresse auf dem Stack,
- 16bit-Werten in benachbarten Registern.

Wenn man das zusammenrechnet, ist AVR zu zwei Dritteln little-endian, zu 
einem Drittel big-endian.

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja, ich arbeite viel auf der Bitebene. Und da muss ich schon wissen, 
ob ich Little oder Big-Endian verwende, wenn ich mit meinen Masken 
arbeite...

Ich habe nämlich die gleichen Masken auf einem PC genutzt um die vom µC 
generierten Daten auszuwerten, und bin da ganz schön auf die Sch*** 
gestürtzt, bis ich mein Problem fand:

mein damaliger µC verwendete Big Endian... (MSB first), und im PC war 
dann leider das LSB first... Dumm, dass die Maske nicht automatisch mit 
gedreht wurde ;)

Worum es mir eigentlich geht: Ich muss doch irgendwo auf den 
Herstellerseiten eine Info darüber finden... Sowas kann doch nicht mit 
Try & Error herausgefunden werden, oder?

Grüße

Christian

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

Bewertung
0 lesenswert
nicht lesenswert
Klar findet man das. Die Doku zum LPM Befehl klärt 2 der 3 erwähnten 
Fragen, nur die Return-Adresse ist undokumentiert.

Autor: chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das hängt vom C compiler ab, nicht vom Mikrocontroller, auch wenn die 
Registerstructur eines Micros da sehrwohl einen Einfluß hat, LSB mit 
niederer
oder höherer Addresse bei 16bit Timern usw.

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

Bewertung
0 lesenswert
nicht lesenswert
Warum du keine klare Antwort " ... ist little-endian" von Atmel erwarten 
darfst: Das Problem stellt sich überwiegend nicht, weil es bei AVRs 
keinen einzigen Befehl gibt, der im SRAM mit Werten grösser als 8 Bit 
arbeitet, wenn man von der erwähnten Return-Adresse mal absieht. In 
diesem Sinne sind AVRs also ist-mir-egal-mach-es-wie-du-willst-endian.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Christian (Gast)

>Naja, ich arbeite viel auf der Bitebene. Und da muss ich schon wissen,
>ob ich Little oder Big-Endian verwende, wenn ich mit meinen Masken
>arbeite...

Nööö. Man muss nur bei Daten mit mehr als ein Byte RICHTIG drauf 
zugreifen. Ein Compiler macht das automatisch, in ASM muss man halt 
aupassen.

>mein damaliger µC verwendete Big Endian... (MSB first), und im PC war
>dann leider das LSB first... Dumm, dass die Maske nicht automatisch mit
>gedreht wurde ;)

Hat dennoch nix mit den Masken zu tun, sondern mit dem Datenzugriff.

0xABCD ist immer 0xABCD, egal ob Little oder Big Endian.

>Worum es mir eigentlich geht: Ich muss doch irgendwo auf den
>Herstellerseiten eine Info darüber finden... Sowas kann doch nicht mit
>Try & Error herausgefunden werden, oder?

Der AVR ist ein 8-Bitter, da stellt sich die Frage so gut wie gar nicht.
Aussnahmen wurden genannt.

MFG
Falk

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"ist-mir-egal-mach-es-wie-du-willst-endian"
Das ist ja nett formuliert.

Na mal schauen. Ich muss es irgendwie in der Doku begründen, warum ich 
die Bitmasken auf dem PC drehen musste. Ich wollte halt vorher nur 
sicher gehen, dass der µC auch Big Endian hat, damit ich in der Doku 
keinen Mist zusammen-begründe ;)

Grüße

Christian

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

Bewertung
0 lesenswert
nicht lesenswert
Für Daten hat er aber gerade kein Big Endian von Haus aus, sondern
nur für die Returnadressen auf dem Stack.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian wrote:

> Worum es mir eigentlich geht: Ich muss doch irgendwo auf den
> Herstellerseiten eine Info darüber finden...

Nein.
Der AVR ist ein 8-Bitter und damit ein No-endian.

Wie nun ein C-Compiler aus 2 Bytes einen 16Bit-Wert zusammenbastelt, ist 
seine persönliche Freiheit.
Der AVR-Hersteller kann das also garnicht festlegen.


In der Regel ist eine Datenübertragung (UART, CAN) auch 8Bittig und 
damit No-Endian.
Man muß also im Protokoll festlegen, in welcher Reihenfolge die Bytes 
übertragen werden.

Auf PC- und AVR-Seite verwende ich zur Übertragung Code, der endian 
unabhängig ist und schon gibts nie Probleme:

int8_t hi;
int8_t lo;
int16_t word;
...
hi = word>>8;
lo = word;
...
word = lo | (hi>>8);



Peter

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ok, weil die Frage mit den Masken aufkam:

so sieht meine Maske im Mikrocontroller aus:
typedef struct
{
  union                        /* Status des Telegramms            */
  {
    unsigned char Byte;                /* Byte-Zugriff                  */
    struct                      /* Bit-Zugriff                  */
    {
      unsigned char BELEGT:    1;        /* 1: Speicher ist belegt            */
                            /* 0: Speicher ist nicht belegt          */
      unsigned char SENDEN:    1;        /* 1: Telegramm kann gesendet werden      */
                            /* 0: Telegramm kann noch nicht gesendet werden  */
      unsigned char RESERVIERT5:  1;
      unsigned char RESERVIERT4:  1;
      unsigned char RESERVIERT3:  1;
      unsigned char FILTERBEREIT:  1;        /* 1: Telegramm vollständig            */
                            /* 0: Telegramm unvollständig          */
      unsigned char RICHTUNG:    1;        /* 0: Telegramm vom BC              */
                            /* 1: Telegramm vom FM              */
      unsigned char KANAL:    1;        /* 0: Telegramm vom FM_A            */
                            /* 1: Telegramm vom FM_B            */
        }Bit;
    }Status;
}maske_uC;

und so muss die Maske für den PC aussehen:
typedef struct
{
  bool inUse;
  union
  {
    unsigned char BYTE;              //  Byte-Zugriff
    struct
    {
      unsigned char KANAL:    1;      //  0 == Kanal A, 1 == Kanal B
      unsigned char RICHTUNG:    1;      //  0 == Master, 1 == Slave
      unsigned char RESERVIERT2:  1;        
      unsigned char RESERVIERT3:  1;
      unsigned char RESERVIERT4:  1;
      unsigned char RESERVIERT5:  1;
      unsigned char SENDEN:    1;      //  0 == nicht Senden, 1 == Senden (in der PC-Software ohne Bedeutung)
      unsigned char RESERVIERT7:  1;
    }Bit;                    //  Bit-Zugriff
  }Status;
}maske_PC;

Ich musste die Reihenfolge der Bits der Maske ändern, da die Maske sonst 
bei dem gleichen Byte-Wert andere Ergebnisse ausgespuckt hat...

Beide Codeabschnitte werden vom Gcc kompiliert... Jedoch einmal für den 
x86 und einmal für den µC.

Vielleicht ist nun meine Frage nachvollziehbar ;)

Grüße

Christian

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

Bewertung
0 lesenswert
nicht lesenswert
Peter Dannegger wrote:

> Der AVR ist ein 8-Bitter und damit ein No-endian.

Er ist ziemlich no-endian, ja, aber viele 8-Bitter sind das nicht und 
fast alle haben irgendwo 16bit Werte verbuddelt, meist im Code. 8051 
kennst du selber, 65xx/68xx,8080/Z80,Z8 haben das querdurch in Code und 
Daten. Völlig frei von jeder hardwareseitigen Vorgabe war m.W. nur 
SC/MP.

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

Bewertung
0 lesenswert
nicht lesenswert
@Christian: Und genau solche Mätzchen vermeidet man elegant mit der 
Danegger'schen Methode, indem man die Daten in einer definierten 
Reihenfolge überträgt, unabhängig von der maschinell bevorzugten 
Reihenfolge.

Das mag etwas aufwendiger sein, erspart aber einigen Ärger.

Und bei Bitfeldern begiebt man sich voll in Abhängigkeit vom Compiler. 
Das darf der nämlich in weiten Grenzen machen wie er will.

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Berichtigung:

Das High-Byte muß natürlich nach links geschoben werden:

int8_t hi;
int8_t lo;
int16_t word;
...
hi = word>>8;
lo = word;
...
word = lo | (hi<<8);



Peter

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

Bewertung
0 lesenswert
nicht lesenswert
Andreas Kaiser wrote:

>> Der AVR ist ein 8-Bitter und damit ein No-endian.
>
> Er ist ziemlich no-endian, ja, ...

...und die Stellen, an denen er selbst eine Endianess vorgibt, hast
du ja bereits im dritten Posting ganz oben genannt.  Will wohl bloß
keiner wahr haben.

Autor: Michael Wilhelm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kann man, da es hier ja um Bitfelder geht, das beim GCC evtl. 
einstellen? beim IAR habe ich eine Pragma-Direktive, die mir das Bitfeld 
"umdreht".

MW

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

Bewertung
0 lesenswert
nicht lesenswert
Michael Wilhelm wrote:

> Kann man, da es hier ja um Bitfelder geht, das beim GCC evtl.
> einstellen?

Gewissermassen. Da der GCC quelloffen ist, bleibt es dir unbenommen, 
eine eigene Version zu erstellen, die deinen Wünschen entspricht. ;-)

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Christian (Gast)

>Ok, weil die Frage mit den Masken aufkam:

>so sieht meine Maske im Mikrocontroller aus:

Also innerhalb eines BYTES wird gar nichts gedreht, weder bei Big noch 
Little Endian. ABER, da nicht festgelegt ist, WO im Byte der Compiler 
die Bits hinlegen soll, kann er das ad libidum machen. Was zwei 
verschiedene Compiler auch tun.

-> Solche Unions und Bitfummelein manch man anders. Über #defines und 
Bitmasken.

>Beide Codeabschnitte werden vom Gcc kompiliert... Jedoch einmal für den
>x86 und einmal für den µC.

Naja, die haben zwar den gleichen Namen aber unter der Haube 
verschiedene Back ends.

MFG
Falk

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg Wunsch wrote:

> ...und die Stellen, an denen er selbst eine Endianess vorgibt, hast
> du ja bereits im dritten Posting ganz oben genannt.  Will wohl bloß
> keiner wahr haben.

Es gibt Stellen, z.B. in den 4 Registerpaaren oder wie ein Call Adressen 
pusht, die indirekt nen Endian haben.

Es kostet aber kein einziges Byte mehr, wenn der Compiler für 
SRAM-Variablen den Endian andersrum festlegt, da die immer nur byteweise 
gelesen werden können.

Daher bin ich der Meinung, der Endian des AVR ist nirgends in Stein 
gemeißelt, sondern der Compiler kann ihn nach belieben festlegen.


Peter

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian wrote:

> Ich musste die Reihenfolge der Bits der Maske ändern, da die Maske sonst
> bei dem gleichen Byte-Wert andere Ergebnisse ausgespuckt hat...

Ja, das ist die persönliche Freiheit des Compilers.

Aber auch dafür gibt es eine Lösung.
Man definiert die Variablen nicht direkt in einer Union, sondern als 
Elemente einer vorher definierten struct.

Dann muß man nur für jeden Compiler einmal die Elemente in dieser struct 
umdefinieren, fertig.


Ein Beispiel (in sbit.h) findest Du hier:

Beitrag "LCD Treiber Routine 4*40"


Wenn mans ganz sauber machen will, definiert man diese Struct in 
Abhängigkeit vom Compilernamen.


Peter

Autor: Kai G. (runtimeterror)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gibt noch ein paar 16-Bit-Befehle, bei denen das Endianesisch zumindest 
für die Assemblerprogrammierung meiner Meinung nach relevant ist:

Bei der Multiplikation gilt:
R0 = Product Low
R1 = Product High
[R1:R0] also Little Endian

Bei ADIW und SBIW gilt ebenfalls:
Rd+1:Rd := Rd+1:Rd +- K
ist Little Endian

Und die Doppelregister
X = [R27:R26]
Y = [R29:R28]
Z = [R31:R30]
auch Little Endian

Da die Register auch im globalen Adressraum eingeblendet werden, kann 
hier meiner Meinung nach schon von einer little endian-Architektur 
gesprochen werden.

Ob man die Stackreihenfolge dann big endian nennt sei mal dahingestellt.

Gruß

Kai

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Peter Dannegger (peda)

>Wenn mans ganz sauber machen will, definiert man diese Struct in
>Abhängigkeit vom Compilernamen.

Wäre es nicht sinnvoller, mit #defines und Bitmasken zu arbeiten?

MFG
Falk

MFG
Falk

Autor: Christian (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sorry, dass ich das jetzt grad noch nicht ganz gerallt
Aber vielleich stehe ich zum Nachmittag auch auf meiner Leitung...

Ich kann doch nicht dem Compiler überlassen, wie rum er meine Bits im 
Speicher hinterlegt?!?

Grüße

Christian

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

Bewertung
0 lesenswert
nicht lesenswert
Christian wrote:

> Ich kann doch nicht dem Compiler überlassen, wie rum er meine Bits im
> Speicher hinterlegt?!?

Gegenfrage: Warum nicht?

Solange du dich immr nur auf ein und derselben Maschine
tummelst und immer denselben Compiler verwendest, ist es
doch (weitgehend) egal. C enthält viele solche Dinge, die
im Ermessen des Compilers bzw. des Compilerbauers liegen.
Das hat sein Gutes denn dadurch bleibt die Sprache von
Besonderheiten einer bestimmten Architektur frei und der
Compilerbauer kann sich für eine bestimmte Architektur
eine optimale Strategie überlegen.
Das hat aber auch sein weniger Gutes, indem man einen Teil
der Kontrolle als Programmierer abgeben muss.

In dem Moment, in dem Datenübertragung auf eine andere
Maschine ansteht, und man die unbedingt binär machen
will, hat man dann meist sowieso das eine oder andere
kleine Problem.

Autor: Stefanie B. (sbs)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>persönliche Freiheit des Compilers.


Aha!

Schützt die Compiler!
Gebt ihnen Wahlrecht ab 18!
Gleichheit für alle!!

;-)

[duck & wech]


-stef

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

Bewertung
0 lesenswert
nicht lesenswert
Stefan B. wrote:
>>>persönliche Freiheit des Compilers.
>
>
> Aha!
>
> Schützt die Compiler!
> Gebt ihnen Wahlrecht ab 18!
> Gleichheit für alle!!

Weils gerade in einem anderen Fred angesprcohen wurde
(und ich der Übeltäter war).

Es muss CompilerInnen heissen :-)

> [duck & wech]

[noch mehr duck aber dafür nicht mehr ganz so schnell wech]

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.