Перейти к содержанию
    

LPCXpresso

Может кто подскажет, как сказать линковщику, что есть внешняя RAM?

Использую LPCXpresso 7.9.0.

В настройках проекта (MCU setting) добавил соответствующую секцию, но не помогает.

При линковке сообщение, что не хватает внутреннего ОЗУ... Во внешнее линковать и не пытается.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Может кто подскажет, как сказать линковщику, что есть внешняя RAM?

Использую LPCXpresso 7.9.0.

В настройках проекта (MCU setting) добавил соответствующую секцию, но не помогает.

При линковке сообщение, что не хватает внутреннего ОЗУ... Во внешнее линковать и не пытается.

Гуглить "скрипт линкера".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Гуглить "скрипт линкера".

 

Да я понимаю, что смотреть надо *.ld файлы. Но там все регионы памяти прописаны (формируются автоматически по настройкам из GUI и их редактировать нет смысла). Кажется должно было бы все работать. Да и описания синтаксиса я не нашел, поэтому не все в них понятно (здесь какой-то свой формат).

И такая проблема не только с внешней памятью. Я работаю с LPC4357, у него несколько банков внутреннего ОЗУ. Есть даже два смежных банка, но по мере заполнения первого, данные не "переползают" во второй. Линковщик просто ругается, что не достаточно места в первом.

На сайте указано, как код, константы, как массив переменных положить в нужный банк ОЗУ при помощи __attribute__ ((section.... Но это все не то.

С LPCXpresso (Eclipse) только начал работать, более привычен Keil. В нем примерно также в GUI указывается распределение памяти и все работает прозрачно для программиста.

А здесь даже не знаю куда ткнуться.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Есть даже два смежных банка, но по мере заполнения первого, данные не "переползают" во второй. Линковщик просто ругается, что не достаточно места в первом.

ЕМНИП, гнутый линкер не умеет раскидывать по разным банкам. И RealView (который в Кейле) тоже не умеет. А Яр умеет.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ЕМНИП, гнутый линкер не умеет раскидывать по разным банкам. И RealView (который в Кейле) тоже не умеет. А Яр умеет.

 

RealView как раз и умеет. Там все на раз-два настраивается прямо через GUI Keil.

 

А если GNU не умеет, то как тогда вообще работать с банками? Мне нужно немного встроенной памяти, что-бы, как минимум, проинициализировать внешнее большое ОЗУ и уйти туда работать.

Если не умеет автоматом раскидывать, то как это сделать вручную?

 

Изменено пользователем _Mikhail_

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Если не умеет автоматом раскидывать, то как это сделать вручную?

В исходнике приписывать переменные к отдельной секции, а потом размещать её в памяти как захочется.

 

Тут еще момент, о котором я писал. Скрипты для линкера формируются автоматически данной средой (LPCXpresso) и править их в тексте смысла нет. Поэтому, даже если и знать, как выправить скрипт вручную, мне не понятно как это подсунуть IDE.

Мне такие проблемы непонятны. Я всегда делаю сборку через Makefile, ну и скрипт линкера подсовываю сам, естественно.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

формируются автоматически по настройкам из GUI и их редактировать нет смысла

Дело обстоит с точностью до наоборот - не имеет смысла использовать сгенерированный как попало скрипт. Аккуратно написать свой.

Есть даже два смежных банка, но по мере заполнения первого, данные не "переползают" во второй. Линковщик просто ругается, что не достаточно места в первом.

Ну и опишите его ОДНИМ блоком, а не так, как визард нагенерил.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Дело обстоит с точностью до наоборот - не имеет смысла использовать сгенерированный как попало скрипт. Аккуратно написать свой.

 

Ну и опишите его ОДНИМ блоком, а не так, как визард нагенерил.

 

Нет. Про внутренние смежные блоки я к примеру сказал. Для первичной инициализации хватает и одной банки. Нужно много внешнего ОЗУ, а оно лежит совсем по другим адресам.

 

А про скрипты согласен. Я нашел уже нашел способ, как использовать свой. Сначала генерю автоматом для шаблона, а потом снимаю найденную галочку в настройках и можно редактировать скрипт, он перезаписываться не будет.

Теперь думаю, что там надо править...

 

В исходнике приписывать переменные к отдельной секции, а потом размещать её в памяти как захочется.

Это что ко всем переменным __attribute__ ((section... приписывать?!

Нет, ну можно, конечно, для краткости задифайнить.

Тогда проще весь стартовый код перелопатить таким образом.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это что ко всем переменным __attribute__ ((section... приписывать?!

Нет, ну можно, конечно, для краткости задифайнить.

Если не ошибаюсь, можно в скрипте линкера указывать имена файлов. Скажем, такие-то файлы - в один банк, остальные - в другой.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Это что ко всем переменным __attribute__ ((section... приписывать?!

Должна быть прагма типа:

#pragma arm section ...

Указывает куда, что класть. После нее действуют указания до конца файла или до отменяющей прагмы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Должна быть прагма типа:

#pragma arm section ...

Указывает куда, что класть. После нее действуют указания до конца файла или до отменяющей прагмы.

К сожалению, в GCC такого не нашел (

 

Буду пока смотреть в сторону скрипта линковки

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

К сожалению, в GCC такого не нашел (

 

Буду пока смотреть в сторону скрипта линковки

Как было сказано выше можно на регионы памяти назначать целиком единицы линковки. К примеру всё из startup.o размещать во внутренней памяти а всё остальное во внешней.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Как было сказано выше можно на регионы памяти назначать целиком единицы линковки. К примеру всё из 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 */
									 ) );
}

Изменено пользователем IgorKossak
[codebox] для длинного кода, [code] - для короткого!

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...