Maly problem

Jun 05, 2007 5 Replies

Dla uC ARM7 i gcc. Jest np. cos takiego:



typedef struct{ unsigned short a; unsigned short b; }struktura;



struktura * st;



char * buff = (char*)malloc(100); memcpy(buff,"to sa jakies dane",13); st = (struktura*)(buff+13); st->a = 0x0006;



Problem polega na tym, ¿e za ka¿dym razem, gdy struktura jest przesunieta w buforze o nieparzysta liczbe bajtow starszy bajt zmiennej a struktury zachodzi na ostatni bajt danych wczesniej zapisanych. Nie wiem czemu tak jest, bo program po skompilowaniu wyglada dobrze, st->a wypada tam gdzie powinno, ale procesor wykonuje to tak, ¿e zapisuje do pamieci o jeden bajt wyzej. Moze wie ktos z czego to wynika i jak problem rozwiazac bo ja juz nie mam pomyslow. Napisalem dokladnie to samo w MS Visual C++ na PC i tam jest ok.



Klasyka... A packed nie pomaga?

formatting link
Mister

U¿ytkownik "Mister" snipped-for-privacy@wp.pl napisa³ w wiadomo¶ci news:f43muo$g2u$ snipped-for-privacy@nemesis.news.tpi.pl...

Nie w tym problem. Wyglada na to, ze np. zapis strh r1,[r0,#1] jest wyrownywany do strh r1,[r0], podobnie np. str r1,[r0,#3] daje str r1,[r0]. Wlasnie strh generuje kompilator w moim przypadku i stad to przesuniecie. Dziwne, ze nie uwzglednia tego.

Artur pisze:

[...]

Zdecydowana większość procesorów z jądrem ARM7TDMI nie może zapisać lub odczytać niewyrównanej danej do/z pamięci. Czyli słowa 32-bitowe muszą być zawsze umieszczone pod adresem z zerowymi 2 najmłodszymi bitami, słowa 16-bitowe pod adresem z wyzerowanym najmłodszym bitem (parzystymi). Próba dostępu pod niewyrównany adres kończy się wyjątkiem.

Kompilator próbuje temu zaradzić (tam gdzie może) i odpowiednio rozpycha struktury. Na przykład struktura:

struct { unsigned char a; unsigned long b; }

zajmie 8 bajtów, bo pole b musi być wyrównane do wielokrotności 4 bajtów licząc od początku struktury. Oczywiście można wymusić dostęp do dowolnego adresu przez rzutowanie i inne zabiegi, ale skończy się on wyjątkiem (np. w AT91SAM7S256 czy AT91RM9200). Nie wiem, jakiego używasz ARMa, w którym nie dostajesz wyjątku tylko błędne działanie programu.

Adam Dybkowski schrieb:

czyli dupa nie kompilator. Kompilator powinien, w przypadku użycia packed structure przerobić kod na mało efektywny, ale prawidłowy kod dostępu. Znaczy czytanie słowa i dostęp do bajtu/uint16 itd. Przy wpisywaniu tak samo: czytaj słowo, wpisz bajt na odpowiednie miejsce, wpisz spowrotem słowo.

Waldek

Waldemar pisze:

Nie próbowałem dodawać atrybutu 'packed'. Napisałem w jaki sposób kompilator zachowuje się domyślnie (arm-elf-gcc 3.4.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