Pracuję nad projektem ARM7TDMI przy użyciu GCC 4.3 i mam pewne trudności informujące kompilator do korzystania z długich połączeń w niektórych przypadkach, ale nie innych.long_calls między RAM i ROM sekcji na gołym metalu ARM z gcc
Proces kompilacji przebiega arm-eabi-gcc
wygenerować relocatable plików obiektowych ELF dla każdego pliku źródłowego .c (najistotniejsze CFLAGS obejmują -Os -ffunction-sections -fdata-sections -mthumb -mthumb-interwork
), a następnie łączy je wszystkie do pliku wykonywalnego ELF (najtrafniejsze LDFLAGS obejmują -Wl,--gc-sections -Wl,-static -Wl,-n -nostdlib
i niestandardowy skrypt linkera) . Następnie plik ELF jest konwertowany do surowego pliku wykonywalnego z arm-eabi-objcopy -O binary
, a niestandardowy bootloader kopiuje go z ROM do pamięci RAM (pojedyncza SRAM z kodem i danymi) podczas uruchamiania. Zatem wszystko, co jest wykonywane z pamięci RAM, .rodata
jest obecne w pamięci RAM, a wszystko dzieje się szybko, całkowicie ignorując ROM po starcie.
Teraz próbuję to zmienić, aby niektóre wybrane fragmenty danych RO i tekst wybranych funkcji mogły działać tylko w pamięci ROM i mieć dostęp do nich w razie potrzeby. Zmodyfikowałem skrypt linkera, aby dowiedzieć się o dwóch nowych sekcjach: ".flashdata"
i ".flashtext"
, które należy umieścić pod stałym adresem w pamięci ROM. I również kropiłam __attribute__((__section__(".flashdata")))
iw całym kodzie C, stosownie, i odtworzyłem proces kompilacji tak, że stary objcopy teraz dodaje -R .flashdata -R .flashtext
, i robię drugi objcopy z -j
dla każdej z tych sekcji, a następnie łączę dwa pliki wyjściowe, aby program ładujący mógł wykonać właściwą czynność, a sekcje pamięci ROM pojawią się w oczekiwanym położeniu mapowanym w pamięci.
To wszystko działa dobrze - mogę printf struny oznaczone w sekcji .flashdata
i mogę nazwać .flashtext
funkcji z kodu wyczerpaniu pamięci RAM (co wie użycie długiej rozmowie z powodu atrybutu __long_call__
obok atrybutu __section__(".flashtext")
). Ta funkcja oparta na pamięci ROM może z powodzeniem wywoływać krótkie połączenia z innymi funkcjami opartymi na pamięci ROM i może powracać do swojego abonenta działającego w oparciu o pamięć RAM.
Problem polega na próbie połączenia z funkcji opartej na pamięci ROM do pamięci RAM, która również musi być długim połączeniem. Nie chcę używać długich połączeń wszędzie, więc nie chcę -mlong_calls w moich CFLAGS. Jeśli zgrupuję wszystkie funkcje, aby żyć w pamięci ROM w pojedynczym rom.c
, mogę zbudować ten jeden plik z -mlong-calls
i wszystko działa. Jednak zdecydowanie wolę tego unikać i utrzymywać funkcje pogrupowane na ogół według celu, po prostu oznaczając kilka tu i tam, stosownie do uruchomienia z pamięci ROM.
Nawiasem mówiąc, nie było to wystarczające w gcc 3.4. Korzystanie z -mlong-calls
sprawiło, że kompilator myślał o właściwej rzeczy, ale nie mógł tego zrobić, ponieważ był gotów wykonać długie skoki ze swoimi pomocnikami _call_via_rX
... które wszystkie żyły w pamięci RAM i mogły być dostępne tylko przez długie połączenie. This was fixed in the linker in gcc 4.0, but not backported to anything in the 3.x tree.
To wspaniałe, że mogę teraz oddzwonić do pamięci RAM, ponieważ używam gcc 4.3. Byłoby jeszcze lepiej, gdybym mógł w jakiś sposób oznaczyć kod w funkcjach opartych na pamięci ROM, aby zmusić go do korzystania z długich połączeń. Jest #pragma long_calls
, ale wpływa ona tylko na deklaracje, więc mógłbym go użyć zamiast __attribute__((__long_call__))
. Niestety nie zmusza on kompilatora do używania długich wywołań dla wszystkich wywoływanych funkcji, gdy jest on włączony.
Po prostu nie należy robić wszystkiego, aby zgrupować cały wolny kod w jednym pliku, poza kontekstem i oddzielić go od innego kodu w kategorii ogólnej. Proszę mi powiedzieć, że jest opcja, której jeszcze nie rozważałem. Dlaczego nie ma sekcji -ffunction lub po prostu fakt, że kod znajduje się w różnych sekcjach (.text
versus .flashtext
) automatycznie naprawiając mój problem?
Nawiasem mówiąc, błąd z linkera, gdy stwierdza, że kompilator użył krótkiej rozmowy, która nie pozostawiła wystarczającej ilości miejsca do zarządzania relokacją, to: relocation truncated to fit: R_ARM_THM_CALL against symbol
foo 'zdefiniowany w sekcji .text.foo w objs/foo.o (and the section
.text.foo is used instead of
.text because of
-function-sections` w CFLAGS).