RTV forum PL | NewsGroups PL

Zewnętrzna pamięć RAM w projekcie STM32 z GCC: Napotkane trudności z linkowaniem zmiennych!

Skrypt linkera, pamięć zewnętrzna i.. . problem :(

NOWY TEMAT

elektroda NewsGroups Forum Index - Elektronika Polska - Zewnętrzna pamięć RAM w projekcie STM32 z GCC: Napotkane trudności z linkowaniem zmiennych!

Konop
Guest

Tue Jul 19, 2011 8:39 pm   



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(Cool;
__stack_start = .;
PROVIDE(__stack_start = __stack_start);

. = ALIGN(Cool;
__main_stack_start = .;
PROVIDE(__main_stack_start = __main_stack_start);

. += __main_stack_size;

. = ALIGN(Cool;
__main_stack_end = .;
PROVIDE(__main_stack_end = __main_stack_end);

. = ALIGN(Cool;
__process_stack_start = .;
PROVIDE(__process_stack_start = __process_stack_start);

. += __process_stack_size;

. = ALIGN(Cool;
__process_stack_end = .;
PROVIDE(__process_stack_end = __process_stack_end);

. = ALIGN(Cool;
__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);

Michoo
Guest

Tue Jul 19, 2011 8:57 pm   



W dniu 19.07.2011 22:39, Konop pisze:
Quote:
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

Konop
Guest

Tue Jul 19, 2011 9:13 pm   



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

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

Portal
Guest

Tue Jul 19, 2011 9:57 pm   



Konop wrote:
Quote:
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

Zbych
Guest

Wed Jul 20, 2011 6:09 am   



W dniu 2011-07-19 22:39, Konop pisze:
Quote:
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

Michoo
Guest

Wed Jul 20, 2011 11:25 am   



W dniu 19.07.2011 23:13, Konop pisze:
Quote:
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 Wink...
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.

Quote:
Wiem. Ale chciałem to zrobić trochę "kulturalniej" i się czegoś
dowiedzieć przy okazji Wink... 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

Konop
Guest

Wed Jul 20, 2011 8:44 pm   



W dniu 20.07.2011 13:25, Michoo pisze:
Quote:
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ę Wink... ale jedyne, czego nie znam, to składnia
skryptów linkera Wink...
A dlaczego w środek data?? Mam data, potem extram, potem bss...

Quote:
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 Wink... Może faktycznie jest w
środku... Skrypt mam ze strony Freddiego Chopina, taki człowiek, co
dobrze zna ARMy Wink... na jego stronie można znaleźć wiele ciekawych
rzeczy Very Happy
Skryptu od ST nie mam, gdyż oni nie pomagają ludziom używających
darmowych narzędzi WinkWinkWink...

--
Pozdrawiam
Konop

Konop
Guest

Wed Jul 20, 2011 8:45 pm   



W dniu 19.07.2011 23:57, Portal pisze:
Quote:
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

Konop
Guest

Wed Jul 20, 2011 8:53 pm   



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

Quote:
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
Wink... Wolę się upewnić Razz...

--
Pozdrawiam
Konop

Zbych
Guest

Thu Jul 21, 2011 5:50 am   



W dniu 2011-07-20 22:53, Konop pisze:
Quote:
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
Wink... Wolę się upewnić Razz...

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.

Konop
Guest

Sat Jul 23, 2011 10:51 am   



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


--
Pozdrawiam
Konop

elektroda NewsGroups Forum Index - Elektronika Polska - Zewnętrzna pamięć RAM w projekcie STM32 z GCC: Napotkane trudności z linkowaniem zmiennych!

NOWY TEMAT

Regulamin - Zasady uzytkowania Polityka prywatnosci Kontakt RTV map News map