Skrypt linkera, pamięć zewnętrzna i..

Jul 19, 2011 10 Replies

Witam



Piszę program na STM32, kompilator to gcc (CodeSorcery). Mam podłączoną zewnętrzną pamięć RAM. Chciałbym w niej umieścić kilka zmiennych (duże bufory), reszta zmiennych ma być w wewnętrznej pamięci RAM. Próbowałem więc przerobić skrypt linkera (od Freddiego Chopina) tak, aby uwzględniał tę pamięć zewnętrzną. Zrobiłem to dopisując do MEMORY wpis: eram (rwx): org = 0x60000000, len = 512k



Dalej oczywiście __eram_start, end itp. Następnie tworzę sekcję .extram:



.extram : { . = ALIGN(4); __eram_start = .; PROVIDE(__eram_start = __eram_start); . = ALIGN(4); *(.extram) . = ALIGN(4); __eram_end = .; PROVIDE(__eram_end = __eram_end); } > eram AT > eram


Nie znam się za dobrze na skryptach linkera, więc to trochę taka moja radosna twórczość na podstawie innych sekcji. Ale próbowałem różnych zabiegów, z AT>eram, bez, umieszczałem tą sekcję w różnych miejscach pliku itp... i cały czas ten sam problem:



W programie deklaruję zmienne:unsigned char Buffer[(128*1024)] __attribute__ ((section("extram")));



(łącznie jest tych buforów 512kB)



Projekt.elf section `extram' will not fit in region `ram' Projekt.elf section `extram' will not fit in region `rom' region `ram' overflowed by 464976 bytes region `rom' overflowed by 8316 bytes



Czemu on mi wciska ten "extram" do RAMu lub ROMu?? Co należy zrobić, żeby to się kompilowało?? Prosiłbym chociaż o informację, czego szukać lub z czym kombinować.. Dodam, że zmienne oczywiście nie są inicjalizowane jakimiś wartościami, nie muszą być nawet zerowane (strata czasu, a program jest odporny na obecne tam śmieci).



Poniżej cały skrypt linkera...


W dniu 19.07.2011 22:39, Konop pisze:

Jeżeli chcesz mieć to zrobione bez uczenia się co to jest skrypt linkera, jak działa pamięć w procesorach i ogólnie pomijając podstawy "jak działają mikrokontrolery" to możesz to zrobić mniej więcej tak:

- nie ruszasz skryptów linkera

- definiujesz wskaźniki na bufory w ram char *Buffer1,*Buffer2;

- w programie inicjalizujesz pamięć zewnętrzną i przypisujesz pod te wskaźniki odpowiednie wartości Buffer1=EXT_RAM_START; Buffer2=EXT_RAM_START+BUFFER1_SIZE; //etc

- używasz normalnie buforów

No ale ja wiem, co to jest skrypt linkera, jak działa pamięć i nie pomijam podstaw jak działają mikrokontrolery ;)...

Wiem. Ale chciałem to zrobić trochę "kulturalniej" i się czegoś dowiedzieć przy okazji ;)... Jak definiujesz zmienne, to jednak kompilator pilnuje, aby nie przekroczyć pamięci itp... Metodą j.w. niestety, trzeba trochę uważać. W tej chwili mam to zrobione tak, jak piszesz i jeśli nie poznam rozwiązania - nic się nie stanie, zostawię to tak, jak jest... . Ale dzięki za odzew :)

W tym również za wszystkimi deklaracjami sekcji umieszczonych w ram tzn. za PROVIDE(__heap_end = __heap_end); ?

Pozdr Portal

W dniu 2011-07-19 22:39, Konop pisze:

Jak już używasz nazw z kropkami to używaj ich konsekwentnie. Dyrektywa AT służy do umieszczania obrazu inicjalizacyjnego w ROM. W twoim przypadku sekcja w pamięci zewnętrznej nie jest inicjalizowana.

W skrócie: W programie zadeklaruj bufor tak: char buff[65536] __attribute__ ((section(".extram")));

A w skrypcie linkera dodaj sekcję: MEMORY { rom (rx) : org = 0x08000000, len = 128k ram (rwx) : org = 0x20000000, len = 20k eram (rwx) : org = 0x60000000, len = 512k }

i napisz co ma w niej lądować:

.extram : { . = ALIGN(4); __eram_start = .; . = ALIGN(4); *(.extram) . = ALIGN(4); __eram_end = .; } > eram

W dniu 19.07.2011 23:13, Konop pisze:

To dlaczego chcesz zainicjalizować opisaną sekcję? Ani nie masz na to miejsca w rom, ani nie ma to sensu. No i jeszcze jeżeli dobrze widzę to włożyłeś ją w srodek sekcji data.

To zrób tę sekcję bez jakiejkolwiek inicjalizacji - NOLOAD - zazwyczaj tak się robi .bss i stos, ale u Ciebie widze inaczej - masz skrypt os st, czy skad?

W dniu 20.07.2011 13:25, Michoo pisze:

No właśnie nie chcę ;)... ale jedyne, czego nie znam, to składnia skryptów linkera ;)... A dlaczego w środek data?? Mam data, potem extram, potem bss...

Próbowałem dawać (NOLOAD) ale nie pomagało ;)... Może faktycznie jest w środku... Skrypt mam ze strony Freddiego Chopina, taki człowiek, co dobrze zna ARMy ;)... na jego stronie można znaleźć wiele ciekawych rzeczy :D Skryptu od ST nie mam, gdyż oni nie pomagają ludziom używających darmowych narzędzi ;););)...

Faktycznie, zjadłem tą kropkę...

Dzięki za rady. Zrobiłem tak, jak napisałeś, poprawiłem kropkę, przeniosłem tą sekcję trochę dalej - i w sumie to działa, ale nie wiem czemu mam takie coś:

arm-none-eabi-size -B -t --common (... lista plików .o ...) text data bss dec hex filename (...) 2056 524288 40 526384 80830 out/hardware.o (...) 44172 524308 73 568553 8ace9 (TOTALS)

Tzn. nie wiem, czy to dobrze, że dane te są wliczane do sekcji data ;)... Wolę się upewnić :P...

W dniu 2011-07-20 22:53, Konop pisze:

Nie powinny być wliczane do data. Pewnie wstawiłeś .extram :{...} do sekcji z danymi. Wstaw to na sam koniec za heap. Sprawdziłem te ustawienia u siebie i wszystko mi działało.

Tak też zrobiłem od razu, niestety dalej dostaję: $ arm-none-eabi-size -B out/Projekt.elf

text data bss dec hex filename 11724 524308 6396 542428 846dc out/Projekt.elf

Ale to wina sposobu wyświetlania, gdyż jak wywołam z -A, to: $ arm-none-eabi-size -A out/Projekt.elf

out/Projekt.elf : section size addr .text 11724 134217728 .data 20 536870912 .bss 252 536870932 .stack 6144 536871184 .extram 524288 1610612736 [...] Total 7445621

Czyli widać, że wszystko jest OK. Przepraszam za zamieszanie.

Join the Discussion

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

Didn't find your answer?

Ask the community — no account required