RTV forum PL | NewsGroups PL

Jak rozwiązać problem przesunięcia pamięci dla struktury ARM7 w gcc?

Maly problem

NOWY TEMAT

elektroda NewsGroups Forum Index - Elektronika Polska - Jak rozwiązać problem przesunięcia pamięci dla struktury ARM7 w gcc?

Artur
Guest

Tue Jun 05, 2007 1:45 pm   



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.
--
Artur

Mister
Guest

Tue Jun 05, 2007 1:58 pm   





Artur
Guest

Tue Jun 05, 2007 3:00 pm   



Użytkownik "Mister" <noweprojekty@wp.pl> napisał w wiadomości
news:f43muo$g2u$1@nemesis.news.tpi.pl...
[quote:fb2a5203a8]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?

http://sig9.com/articles/gcc-packed-structures

Nie w tym problem. Wyglada na to, ze np. zapis strh r1,[r0,#1] jest[/quote:fb2a5203a8]
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

Adam Dybkowski
Guest

Thu Jun 07, 2007 10:04 pm   



Artur pisze:

Quote:
Dla uC ARM7 i gcc.
[...]
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.

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
http://www.amwaw.edu.pl/~adybkows/

Uwaga: przed wysłaniem do mnie maila usuń cyfry z adresu.

Waldemar
Guest

Thu Jun 07, 2007 10:19 pm   



Adam Dybkowski schrieb:
Quote:
Artur pisze:

Dla uC ARM7 i gcc.
[...]
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.

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.

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

Adam Dybkowski
Guest

Fri Jun 08, 2007 12:23 am   



Waldemar pisze:

Quote:
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.

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.

Nie próbowałem dodawać atrybutu 'packed'. Napisałem w jaki sposób
kompilator zachowuje się domyślnie (arm-elf-gcc 3.4.3).

--
Adam Dybkowski
http://www.amwaw.edu.pl/~adybkows/

Uwaga: przed wysłaniem do mnie maila usuń cyfry z adresu.

elektroda NewsGroups Forum Index - Elektronika Polska - Jak rozwiązać problem przesunięcia pamięci dla struktury ARM7 w gcc?

NOWY TEMAT

Regulamin - Zasady uzytkowania Polityka prywatnosci Kontakt RTV map News map