Krzysztof B.
Guest
Tue Oct 16, 2007 3:42 pm
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
abert zielonka
Guest
Tue Oct 16, 2007 4:04 pm
On 16 Okt., 16:42, "Krzysztof B." <d...@f.pl> wrote:
Quote:
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;
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
Mister
Guest
Tue Oct 16, 2007 4:14 pm
Quote:
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;
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
John Smith
Guest
Tue Oct 16, 2007 5:29 pm
Quote:
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,
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.
tbird
Guest
Tue Oct 16, 2007 8:57 pm
Krzysztof B. wrote:
Quote:
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?
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];