Big endian kontra little endian, czyli konflikt intere

Oct 16, 2007 4 Replies

Witam wszystkich Aktualnie zczytuję z pewnego urządzenia pakiety danych po RSie do ATMegi



128. Dane są binarne i zawierają liczby 8,16 i 32 bitowe. Wszystko by było fajnie, gdyby to urządzenie pracowało w standardzie little-endian, a niestety tak nie jest. Tu mam takie pytanie, czy jest jakaś funkcja(operator), która z automata zamienia kolejność bajtów? Piszę tu, nie na pl.comp.lang.c, ponieważ AVR to 8 bitowiec i takie rzeczy mogą być bardziej specyficzne dla kompilatora avr-gcc. Właściwie funkcja to nie najlepszy pomysł, ale makro było by idealne wklejając wstawkę z assemblera. Przeszukałem google i oprócz informacji, że problem istnieje nie znalazłem właściwie nic. Obecnie robię to w ten sposób: Tworze strukturę danych z polami w odwrotnej kolejności niż w oryginale nadchodzą. Bufor przeznaczony na pakiet wypełniam od końca do początku. W ten sposób po przypisaniu zmiennej wskaźnikowej (typu struktury) adresu ostatniej komórki mogę bez problemu odwoływać się do poszczególnych pól poprzez: zmienna->pole16b; I to działa bez problemu, ale nie wydaje mi się to "estetycznym" rozwiązaniem. Może wyważam już otwarte drzwi? Jak wy do takiego problemu podchodzicie?

Pozdrawiam


poczytaj o "pragma pack" - zasadniczo sluzy do ustawiania alignmentu ale niektore kompilatory pozwalaja ustawic w ten sposob endian. (Alignment - kolejny problem przy wysylaniu struktury binarnie - kompilator "zakragla" rozmiary skladnikow do DWORD dodajac puste pola

- np. struktura {BYTE,DWORD} bedzie miec nie 5 a 8 bajtow). GRG

Czasem przydaje mi sie cos takiego do zmiany endianowości dla int:

for (i=0;i<xxx;i++) Buff[i] = dev->data_buffer[ (i ^ 1)];

czy dla long: for (i=0;i<xxx;i++) Buff[i] = dev->data_buffer[ (i ^ 3)];

MiSter

Proponuję zapoznać się z pojęciem unii w języku C. Powinno pomóc. Dane należy wpisać bajtowo, odczytać można w słowie 16 lub 32 bitowym. Pozdrawiam, K.

Wersja przenośna (bez użycia unii):

unsigned char buf[42]; unsigned int little_int = buf[0]<<8 | buf[1]; unsigned long little_long = buf[0]<<24 | buf[1]<<16 | buf[2]<<8 | buf[3];

Join the Discussion

Have something to add? Share your thoughts — no account required.

Didn't find your answer?

Ask the community — no account required