TsM 0 18 сентября, 2015 Опубликовано 18 сентября, 2015 · Жалоба Может кто подскажет, как сказать линковщику, что есть внешняя RAM? Использую LPCXpresso 7.9.0. В настройках проекта (MCU setting) добавил соответствующую секцию, но не помогает. При линковке сообщение, что не хватает внутреннего ОЗУ... Во внешнее линковать и не пытается. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Petka 0 18 сентября, 2015 Опубликовано 18 сентября, 2015 · Жалоба Может кто подскажет, как сказать линковщику, что есть внешняя RAM? Использую LPCXpresso 7.9.0. В настройках проекта (MCU setting) добавил соответствующую секцию, но не помогает. При линковке сообщение, что не хватает внутреннего ОЗУ... Во внешнее линковать и не пытается. Гуглить "скрипт линкера". Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
TsM 0 18 сентября, 2015 Опубликовано 18 сентября, 2015 · Жалоба Гуглить "скрипт линкера". Да я понимаю, что смотреть надо *.ld файлы. Но там все регионы памяти прописаны (формируются автоматически по настройкам из GUI и их редактировать нет смысла). Кажется должно было бы все работать. Да и описания синтаксиса я не нашел, поэтому не все в них понятно (здесь какой-то свой формат). И такая проблема не только с внешней памятью. Я работаю с LPC4357, у него несколько банков внутреннего ОЗУ. Есть даже два смежных банка, но по мере заполнения первого, данные не "переползают" во второй. Линковщик просто ругается, что не достаточно места в первом. На сайте указано, как код, константы, как массив переменных положить в нужный банк ОЗУ при помощи __attribute__ ((section.... Но это все не то. С LPCXpresso (Eclipse) только начал работать, более привычен Keil. В нем примерно также в GUI указывается распределение памяти и все работает прозрачно для программиста. А здесь даже не знаю куда ткнуться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 18 сентября, 2015 Опубликовано 18 сентября, 2015 · Жалоба Есть даже два смежных банка, но по мере заполнения первого, данные не "переползают" во второй. Линковщик просто ругается, что не достаточно места в первом. ЕМНИП, гнутый линкер не умеет раскидывать по разным банкам. И RealView (который в Кейле) тоже не умеет. А Яр умеет. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
TsM 0 18 сентября, 2015 Опубликовано 18 сентября, 2015 (изменено) · Жалоба ЕМНИП, гнутый линкер не умеет раскидывать по разным банкам. И RealView (который в Кейле) тоже не умеет. А Яр умеет. RealView как раз и умеет. Там все на раз-два настраивается прямо через GUI Keil. А если GNU не умеет, то как тогда вообще работать с банками? Мне нужно немного встроенной памяти, что-бы, как минимум, проинициализировать внешнее большое ОЗУ и уйти туда работать. Если не умеет автоматом раскидывать, то как это сделать вручную? Изменено 18 сентября, 2015 пользователем _Mikhail_ Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 18 сентября, 2015 Опубликовано 18 сентября, 2015 · Жалоба Если не умеет автоматом раскидывать, то как это сделать вручную? В исходнике приписывать переменные к отдельной секции, а потом размещать её в памяти как захочется. Тут еще момент, о котором я писал. Скрипты для линкера формируются автоматически данной средой (LPCXpresso) и править их в тексте смысла нет. Поэтому, даже если и знать, как выправить скрипт вручную, мне не понятно как это подсунуть IDE. Мне такие проблемы непонятны. Я всегда делаю сборку через Makefile, ну и скрипт линкера подсовываю сам, естественно. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 18 сентября, 2015 Опубликовано 18 сентября, 2015 · Жалоба формируются автоматически по настройкам из GUI и их редактировать нет смысла Дело обстоит с точностью до наоборот - не имеет смысла использовать сгенерированный как попало скрипт. Аккуратно написать свой. Есть даже два смежных банка, но по мере заполнения первого, данные не "переползают" во второй. Линковщик просто ругается, что не достаточно места в первом. Ну и опишите его ОДНИМ блоком, а не так, как визард нагенерил. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
TsM 0 18 сентября, 2015 Опубликовано 18 сентября, 2015 · Жалоба Дело обстоит с точностью до наоборот - не имеет смысла использовать сгенерированный как попало скрипт. Аккуратно написать свой. Ну и опишите его ОДНИМ блоком, а не так, как визард нагенерил. Нет. Про внутренние смежные блоки я к примеру сказал. Для первичной инициализации хватает и одной банки. Нужно много внешнего ОЗУ, а оно лежит совсем по другим адресам. А про скрипты согласен. Я нашел уже нашел способ, как использовать свой. Сначала генерю автоматом для шаблона, а потом снимаю найденную галочку в настройках и можно редактировать скрипт, он перезаписываться не будет. Теперь думаю, что там надо править... В исходнике приписывать переменные к отдельной секции, а потом размещать её в памяти как захочется. Это что ко всем переменным __attribute__ ((section... приписывать?! Нет, ну можно, конечно, для краткости задифайнить. Тогда проще весь стартовый код перелопатить таким образом. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
scifi 1 18 сентября, 2015 Опубликовано 18 сентября, 2015 · Жалоба Это что ко всем переменным __attribute__ ((section... приписывать?! Нет, ну можно, конечно, для краткости задифайнить. Если не ошибаюсь, можно в скрипте линкера указывать имена файлов. Скажем, такие-то файлы - в один банк, остальные - в другой. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
zltigo 0 18 сентября, 2015 Опубликовано 18 сентября, 2015 · Жалоба Это что ко всем переменным __attribute__ ((section... приписывать?! Должна быть прагма типа: #pragma arm section ... Указывает куда, что класть. После нее действуют указания до конца файла или до отменяющей прагмы. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
TsM 0 18 сентября, 2015 Опубликовано 18 сентября, 2015 · Жалоба Должна быть прагма типа: #pragma arm section ... Указывает куда, что класть. После нее действуют указания до конца файла или до отменяющей прагмы. К сожалению, в GCC такого не нашел ( Буду пока смотреть в сторону скрипта линковки Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Petka 0 18 сентября, 2015 Опубликовано 18 сентября, 2015 · Жалоба К сожалению, в GCC такого не нашел ( Буду пока смотреть в сторону скрипта линковки Как было сказано выше можно на регионы памяти назначать целиком единицы линковки. К примеру всё из startup.o размещать во внутренней памяти а всё остальное во внешней. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
TsM 0 23 сентября, 2015 Опубликовано 23 сентября, 2015 (изменено) · Жалоба Как было сказано выше можно на регионы памяти назначать целиком единицы линковки. К примеру всё из startup.o размещать во внутренней памяти а всё остальное во внешней. Ну мне это и надо. Я хочу регионом по умолчанию сделать внешнюю память (это работает), а модули стартапа через скрипот линкера разместить во внутренней RamLoc32 (не получается). Изучал LD, но пока не разобраться. Не понял, как прописать расположение данных для конкретных файлов в скрипты LPCXpresso. Вот что сгенерила IDE: /* * GENERATED FILE - DO NOT EDIT * © Code Red Technologies Ltd, 2008-2013 * © NXP Semiconductors 2013-2015 * Generated linker script file for LPC4357 * Created from memory.ldt by FMCreateLinkMemory * Using Freemarker v2.3.23 * LPCXpresso v7.9.2 [build 493] [2015-09-14] on 23.09.2015 9:05:06 */ MEMORY { /* Define each memory region */ MFlashA512 (rx) : ORIGIN = 0x1a000000, LENGTH = 0x80000 /* 512K bytes (alias Flash) */ RAM_EXT (rwx) : ORIGIN = 0x28000000, LENGTH = 0x1000000 /* 16M bytes (alias RAM) */ RamLoc32 (rwx) : ORIGIN = 0x10000000, LENGTH = 0x8000 /* 32K bytes (alias RAM2) */ } /* Define a symbol for the top of each memory region */ __base_MFlashA512 = 0x1a000000 ; /* MFlashA512 */ __base_Flash = 0x1a000000; /* Flash */ __top_MFlashA512 = 0x1a000000 + 0x80000; /* 512K bytes */ __top_Flash = 0x1a000000 + 0x80000; /* 512K bytes */ __base_RAM_EXT = 0x28000000 ; /* RAM_EXT */ __base_RAM = 0x28000000; /* RAM */ __top_RAM_EXT = 0x28000000 + 0x1000000; /* 16M bytes */ __top_RAM = 0x28000000 + 0x1000000; /* 16M bytes */ __base_RamLoc32 = 0x10000000 ; /* RamLoc32 */ __base_RAM2 = 0x10000000; /* RAM2 */ __top_RamLoc32 = 0x10000000 + 0x8000; /* 32K bytes */ __top_RAM2 = 0x10000000 + 0x8000; /* 32K bytes */ /* * GENERATED FILE - DO NOT EDIT * © Code Red Technologies Ltd, 2008-2013 * © NXP Semiconductors 2013-2015 * Generated linker script file for LPC4357 * Created from linkscript.ldt by FMCreateLinkLibraries * Using Freemarker v2.3.23 * LPCXpresso v7.9.2 [build 493] [2015-09-14] on 23.09.2015 9:05:06 */ INCLUDE "dc_freertos_webserver_Debug_library.ld" INCLUDE "dc_freertos_webserver_Debug_memory.ld" ENTRY(ResetISR) SECTIONS { /* MAIN TEXT SECTION */ .text : ALIGN(4) { FILL(0xff) __vectors_start__ = ABSOLUTE(.); KEEP(*(.isr_vector)) /* Global Section Table */ . = ALIGN(4); __section_table_start = .; __data_section_table = .; LONG(LOADADDR(.data)); LONG( ADDR(.data)); LONG( SIZEOF(.data)); LONG(LOADADDR(.data_RAM2)); LONG( ADDR(.data_RAM2)); LONG( SIZEOF(.data_RAM2)); __data_section_table_end = .; __bss_section_table = .; LONG( ADDR(.bss)); LONG( SIZEOF(.bss)); LONG( ADDR(.bss_RAM2)); LONG( SIZEOF(.bss_RAM2)); __bss_section_table_end = .; __section_table_end = .; /* End of Global Section Table */ *(.after_vectors*) } >MFlashA512 .text : ALIGN(4) { *(.text*) *(.rodata .rodata.* .constdata .constdata.*) . = ALIGN(4); } > MFlashA512 /* * for exception handling/unwind - some Newlib functions (in common * with C++ and STDC++) use this. */ .ARM.extab : ALIGN(4) { *(.ARM.extab* .gnu.linkonce.armextab.*) } > MFlashA512 __exidx_start = .; .ARM.exidx : ALIGN(4) { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } > MFlashA512 __exidx_end = .; _etext = .; /* DATA section for RamLoc32 */ .data_RAM2 : ALIGN(4) { FILL(0xff) PROVIDE(__start_data_RAM2 = .); *(.ramfunc.$RAM2) *(.ramfunc.$RamLoc32) *(.data.$RAM2*) *(.data.$RamLoc32*) . = ALIGN(4); PROVIDE(__end_data_RAM2 = .); } > RamLoc32 AT>MFlashA512 /* MAIN DATA SECTION */ .uninit_RESERVED : ALIGN(4) { KEEP(*(.bss.$RESERVED*)) . = ALIGN(4); _end_uninit_RESERVED = .; } > RAM_EXT /* Main DATA section (RAM_EXT) */ .data : ALIGN(4) { FILL(0xff) _data = .; *(vtable) *(.ramfunc*) *(.data*) . = ALIGN(4); _edata = .; } > RAM_EXT AT>MFlashA512 /* BSS section for RamLoc32 */ .bss_RAM2 : ALIGN(4) { PROVIDE(__start_bss_RAM2 = .); *(.bss.$RAM2*) *(.bss.$RamLoc32*) . = ALIGN (. != 0 ? 4 : 1); /* avoid empty segment */ PROVIDE(__end_bss_RAM2 = .); } > RamLoc32 /* MAIN BSS SECTION */ .bss : ALIGN(4) { _bss = .; *(.bss*) *(COMMON) . = ALIGN(4); _ebss = .; PROVIDE(end = .); } > RAM_EXT /* NOINIT section for RamLoc32 */ .noinit_RAM2 (NOLOAD) : ALIGN(4) { *(.noinit.$RAM2*) *(.noinit.$RamLoc32*) . = ALIGN(4); } > RamLoc32 /* DEFAULT NOINIT SECTION */ .noinit (NOLOAD): ALIGN(4) { _noinit = .; *(.noinit*) . = ALIGN(4); _end_noinit = .; } > RAM_EXT PROVIDE(_pvHeapStart = DEFINED(__user_heap_base) ? __user_heap_base : .); PROVIDE(_vStackTop = DEFINED(__user_stack_top) ? __user_stack_top : __top_RAM_EXT - 0); /* ## Create checksum value (used in startup) ## */ PROVIDE(__valid_user_code_checksum = 0 - (_vStackTop + (ResetISR + 1) + (NMI_Handler + 1) + (HardFault_Handler + 1) + (( DEFINED(MemManage_Handler) ? MemManage_Handler : 0 ) + 1) /* MemManage_Handler may not be defined */ + (( DEFINED(BusFault_Handler) ? BusFault_Handler : 0 ) + 1) /* BusFault_Handler may not be defined */ + (( DEFINED(UsageFault_Handler) ? UsageFault_Handler : 0 ) + 1) /* UsageFault_Handler may not be defined */ ) ); } Изменено 23 сентября, 2015 пользователем IgorKossak [codebox] для длинного кода, [code] - для короткого! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться