-
1. Data: 2011-07-19 20:39:57
Temat: Skrypt linkera, pamięć zewnętrzna i... problem :(
Od: Konop <k...@g...pl>
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...
--
Pozdrawiam
Konop
SEARCH_DIR(.);
/*
+===================================================
==========================+
| format configurations
+===================================================
==========================+
*/
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm");
OUTPUT_ARCH(arm);
/*
+===================================================
==========================+
| stacks sizes
+===================================================
==========================+
*/
/* Handler mode (core exceptions / interrupts) can use only main stack */
/* Thread mode can use main stack (default) or process stack - selected
in CONTROL special register */
__main_stack_size = 2048;
__process_stack_size = 4096;
PROVIDE(__main_stack_size = __main_stack_size);
PROVIDE(__process_stack_size = __process_stack_size);
/*
+===================================================
==========================+
| available memories definitions
+===================================================
==========================+
*/
MEMORY
{
rom (rx) : org = 0x08000000, len = 512k
ram (rwx) : org = 0x20000000, len = 64k
eram (rwx): org = 0x60000000, len = 512k
}
__rom_start = ORIGIN(rom);
__rom_size = LENGTH(rom);
__rom_end = __rom_start + __rom_size;
__ram_start = ORIGIN(ram);
__ram_size = LENGTH(ram);
__ram_end = __ram_start + __ram_size;
__eram_start = ORIGIN(eram);
__eram_size = LENGTH(eram);
__eram_end = __eram_start + __eram_size;
PROVIDE(__rom_start = __rom_start);
PROVIDE(__rom_size = __rom_size);
PROVIDE(__rom_end = __rom_end);
PROVIDE(__ram_start = __ram_start);
PROVIDE(__ram_size = __ram_size);
PROVIDE(__ram_end = __ram_end);
PROVIDE(__eram_start = __eram_start);
PROVIDE(__eram_size = __eram_size);
PROVIDE(__eram_end = __eram_end);
/*
+===================================================
==========================+
| entry point
+===================================================
==========================+
*/
ENTRY(Reset_Handler);
/*
+===================================================
==========================+
| put data in sections
+===================================================
==========================+
*/
SECTIONS
{
.text :
{
. = ALIGN(4);
__text_start = .;
PROVIDE(__text_start = __text_start);
. = ALIGN(4);
KEEP(*(.vectors));
. = ALIGN(4);
*(.text .text.* .gnu.linkonce.t.*);
. = ALIGN(4);
*(.glue_7t .glue_7);
. = ALIGN(4);
*(.rodata .rodata.* .gnu.linkonce.r.*);
. = ALIGN(4);
*(.ARM.extab* .gnu.linkonce.armextab.*); /* exception unwinding
information */
. = ALIGN(4);
*(.gcc_except_table); /* information used for stack unwinding
during exception */
. = ALIGN(4);
*(.eh_frame_hdr); /* additional information about .ex_frame
section */
. = ALIGN(4);
*(.eh_frame); /* information used for stack unwinding during
exception */
. = ALIGN(4);
KEEP(*(.init));
. = ALIGN(4);
__preinit_array_start = .;
KEEP(*(.preinit_array));
. = ALIGN(4);
__preinit_array_end = .;
__init_array_start = .;
KEEP(*(SORT(.init_array.*)));
. = ALIGN(4);
KEEP(*(.init_array));
. = ALIGN(4);
__init_array_end = .;
KEEP(*(.fini));
. = ALIGN(4);
__fini_array_start = .;
KEEP(*(.fini_array));
. = ALIGN(4);
KEEP(*(SORT(.fini_array.*)));
. = ALIGN(4);
__fini_array_end = .;
. = ALIGN(4);
__text_end = .;
PROVIDE(__text_end = __text_end);
} > rom AT > rom
. = ALIGN(4);
__exidx_start = .;
PROVIDE(__exidx_start = __exidx_start);
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*);
} > rom AT > rom /* index entries for section unwinding */
. = ALIGN(4);
__exidx_end = .;
PROVIDE(__exidx_end = __exidx_end);
.data :
{
. = ALIGN(4);
__data_init_start = LOADADDR (.data);
PROVIDE(__data_init_start = __data_init_start);
__data_start = .;
PROVIDE(__data_start = __data_start);
. = ALIGN(4);
*(.data .data.* .gnu.linkonce.d.*)
. = ALIGN(4);
__data_end = .;
PROVIDE(__data_end = __data_end);
} > ram AT > rom
.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
.bss :
{
. = ALIGN(4);
__bss_start = .;
PROVIDE(__bss_start = __bss_start);
. = ALIGN(4);
*(.bss .bss.* .gnu.linkonce.b.*)
. = ALIGN(4);
*(COMMON);
. = ALIGN(4);
__bss_end = .;
PROVIDE(__bss_end = __bss_end);
} > ram AT > ram
.stack :
{
. = ALIGN(8);
__stack_start = .;
PROVIDE(__stack_start = __stack_start);
. = ALIGN(8);
__main_stack_start = .;
PROVIDE(__main_stack_start = __main_stack_start);
. += __main_stack_size;
. = ALIGN(8);
__main_stack_end = .;
PROVIDE(__main_stack_end = __main_stack_end);
. = ALIGN(8);
__process_stack_start = .;
PROVIDE(__process_stack_start = __process_stack_start);
. += __process_stack_size;
. = ALIGN(8);
__process_stack_end = .;
PROVIDE(__process_stack_end = __process_stack_end);
. = ALIGN(8);
__stack_end = .;
PROVIDE(__stack_end = __stack_end);
} > ram AT > ram
. = ALIGN(4);
__heap_start = .;
PROVIDE(__heap_start = __heap_start);
. = ALIGN(4);
__heap_end = __ram_end;
PROVIDE(__heap_end = __heap_end);
.stab 0 (NOLOAD) : { *(.stab) }
.stabstr 0 (NOLOAD) : { *(.stabstr) }
/* DWARF debug sections.
* Symbols in the DWARF debugging sections are relative to the beginning
* of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
.note.gnu.arm.ident 0 : { KEEP(*(.note.gnu.arm.ident)) }
.ARM.attributes 0 : { KEEP(*(.ARM.attributes)) }
/DISCARD/ : { *(.note.GNU-stack) }
}
PROVIDE(__text_size = __text_end - __text_start);
PROVIDE(__exidx_size = __exidx_end - __exidx_start);
PROVIDE(__data_size = __data_end - __data_start);
PROVIDE(__bss_size = __bss_end - __bss_start);
PROVIDE(__stack_size = __stack_end - __stack_start);
PROVIDE(__heap_size = __heap_end - __heap_start);
-
2. Data: 2011-07-19 20:57:34
Temat: Re: Skrypt linkera, pamięć zewnętrzna i... problem :(
Od: Michoo <m...@v...pl>
W dniu 19.07.2011 22:39, Konop pisze:
> 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.
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
--
Pozdrawiam
Michoo
-
3. Data: 2011-07-19 21:13:49
Temat: Re: Skrypt linkera, pamięć zewnętrzna i... problem :(
Od: Konop <k...@g...pl>
> 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:
No ale ja wiem, co to jest skrypt linkera, jak działa pamięć i nie
pomijam podstaw jak działają mikrokontrolery ;)...
> - 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
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 :)
--
Pozdrawiam
Konop
-
4. Data: 2011-07-19 21:57:36
Temat: Re: Skrypt linkera, pamięć zewnętrzna i... problem :(
Od: Portal <m...@p...onet.usun.to.pl>
Konop wrote:
> umieszczałem tą sekcję w różnych miejscach pliku
W tym również za wszystkimi deklaracjami sekcji umieszczonych w ram tzn.
za PROVIDE(__heap_end = __heap_end); ?
Pozdr
Portal
-
5. Data: 2011-07-20 06:09:38
Temat: Re: Skrypt linkera, pamięć zewnętrzna i... problem :(
Od: Zbych <a...@o...pl>
W dniu 2011-07-19 22:39, Konop pisze:
> 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ć
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
-
6. Data: 2011-07-20 11:25:01
Temat: Re: Skrypt linkera, pamięć zewnętrzna i... problem :(
Od: Michoo <m...@v...pl>
W dniu 19.07.2011 23:13, 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:
>
> No ale ja wiem, co to jest skrypt linkera, jak działa pamięć i nie
> pomijam podstaw jak działają mikrokontrolery ;)...
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.
> 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... .
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?
--
Pozdrawiam
Michoo
-
7. Data: 2011-07-20 20:44:42
Temat: Re: Skrypt linkera, pamięć zewnętrzna i... problem :(
Od: Konop <k...@g...pl>
W dniu 20.07.2011 13:25, Michoo 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.
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...
> 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?
>
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 ;););)...
--
Pozdrawiam
Konop
-
8. Data: 2011-07-20 20:45:23
Temat: Re: Skrypt linkera, pamięć zewnętrzna i... problem :(
Od: Konop <k...@g...pl>
W dniu 19.07.2011 23:57, Portal pisze:
> Konop wrote:
>> umieszczałem tą sekcję w różnych miejscach pliku
>
> W tym również za wszystkimi deklaracjami sekcji umieszczonych w ram tzn.
> za PROVIDE(__heap_end = __heap_end); ?
>
> Pozdr
> Portal
Tak jest - nie pomogło :(
--
Pozdrawiam
Konop
-
9. Data: 2011-07-20 20:53:08
Temat: Re: Skrypt linkera, pamięć zewnętrzna i... problem :(
Od: Konop <k...@g...pl>
> 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.
Faktycznie, zjadłem tą kropkę...
> 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
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...
--
Pozdrawiam
Konop
-
10. Data: 2011-07-21 05:50:42
Temat: Re: Skrypt linkera, pamięć zewnętrzna i... problem :(
Od: Zbych <a...@o...pl>
W dniu 2011-07-20 22:53, 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.
>
> Faktycznie, zjadłem tą kropkę...
>
>> 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
>
> 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...
>
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.