Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: ILINK и куски RAM по разным адресам
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
grinux
Всем привет.
Может кто-нибудь знает, как заставить линкер автоматически раскидывать rw данные по памяти, состоящей, например, у NXP LPC23xx из трех кусков.
define symbol __ICFEDIT_region_RAM_start__ = 0x40000040;
define symbol __ICFEDIT_region_RAM_end__ = 0x40007FFF;
define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__];

define symbol __region_USB_DMA_RAM_start__ = 0x7FD00000;
define symbol __region_USB_DMA_RAM_end__ = 0x7FD01FFF;
define region USB_DMA_RAM_region= mem:[from __region_USB_DMA_RAM_start__ to __region_USB_DMA_RAM_end__];

define symbol __region_EMAC_DMA_RAM_start__ = 0x7FE00000;
define symbol __region_EMAC_DMA_RAM_end__ = 0x7FE03FFF;
define region EMAC_DMA_RAM_region= mem:[from __region_EMAC_DMA_RAM_start__ to __region_EMAC_DMA_RAM_end__];

place in RAM_region { readwrite,
block CSTACK, block SVC_STACK, block IRQ_STACK, block FIQ_STACK,
block UND_STACK, block ABT_STACK, block HEAP };
place in USB_DMA_RAM_region
{ section USB_DMA_RAM };
place in EMAC_DMA_RAM_region
{ section EMAC_DMA_RAM };

сейчас если я хочу положить в область USB или EMAC что то, то нужно явно указывать:
int var @ "USB_DMA_RAM";

Хотелось бы так определить эти три зоны в icf файле, чтобы не нужно было явно указывать расположение для переменных.
Вот такой трюк не прокатил:
place in RAM_region { readwrite,
block CSTACK, block SVC_STACK, block IRQ_STACK, block FIQ_STACK,
block UND_STACK, block ABT_STACK, block HEAP };
place in USB_DMA_RAM_region
{ readwrite };
place in EMAC_DMA_RAM_region
{ readwrite };
jcxz
Цитата(grinux @ Aug 27 2017, 23:12) *
Может кто-нибудь знает, как заставить линкер автоматически раскидывать rw данные по памяти, состоящей, например, у NXP LPC23xx из трех кусков.

Код
define region RAM_regionA   = mem:[from 0x1FFE8000 size 0x18000]; //PSRAM (code)
define region RAM_regionB   = mem:[from 0x20000000 size 0x20000]; //DSRAM1 (RW-data)
define region RAM_regionC   = mem:[from 0x20020000 size 0x20000]; //DSRAM2 (RW-data)
...
place in RAM_regionB | RAM_regionC {rw, first block CSTACK, section .raw, block HEAP};

PS: Неужто кто-то ещё пишет новое ПО для столь старого МК?? wacko.gif
VladislavS
Интересно, как бедный линкер будет догадываться куда автоматически разместить переменные, если вы ему об этом не хотите говорить?

Кстати, надо аккуратней с размещением инициализированных данных во всяких "железных буферах". У них доступ бывает ограничен по разрядности. При копировании инициализирующих данных стартап код не знает про это ничего. Недавно пытался на STM32 в USB_PAM инициализированный массив разместить - не вышло, данные неправильно в него копируются.
Obam
Чётко по требуемым адресам и в требуемой последовательности раскладываются "block"-и; иначе link-ер имеет право (arbitrary) "своевольничать".
Из .icf-файла:
Цитата
define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { };
define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { };
define block Process_stack with alignment = 8, size =0x400 {};

place in RAM_region { block CSTACK, block Process_stack, block HEAP };
place at end of RAM_region {readwrite};

и в результате:
Цитата
*******************************************************************************
*** PLACEMENT SUMMARY
***

"A1": place at 0x00400000 { ro section .intvec };
"P1": place in [from 0x00400000 to 0x0040ffff] { ro };
"P2": place in [from 0x20000000 to 0x20003fff] {
block CSTACK, block Process_stack, block HEAP };
"A2": place at end of [0x20000000-0x20003fff] { rw };
"A3": place at end of [0x00400000-0x0040ffff] { ro section BITMAPS };

Section Kind Address Size Object
------- ---- ------- ---- ------
"A1": 0xfc
.intvec const 0x00400000 0xcc cstartup_M.o [1]
.intvec const 0x004000cc 0x30 cstartup_M.o [1]
- 0x004000fc 0xfc

"P1": 0x19bc
.text ro code 0x004000fc 0x1860 SPIDMA_Test_SAM3S1_Main.o [1]

.iar.init_table const 0x00401a8c 0x24 - Linker created -
Initializer bytes ro data 0x00401ab0 0x8 <for rw-1>
.rodata const 0x00401ab8 0x0 bwt_init3c.o [4]
- 0x00401ab8 0x19bc

"A3": 0x107c
BITMAPS const 0x0040ef84 0x10 SPIDMA_Test_SAM3S1_Main.o [1]

BITMAPS const 0x0040ffec 0x14 SPIDMA_Test_SAM3S1_Main.o [1]
- 0x00410000 0x107c

"P2": 0x1400
CSTACK 0x20000000 0x1000 <Block>
CSTACK uninit 0x20000000 0x1000 <Block tail>
Process_stack 0x20001000 0x400 <Block>
Process_stack uninit 0x20001000 0x400 <Block tail>
- 0x20001400 0x1400

В "The linker configuration file" из "IAR C/C++ Development Guide" всё подробно прописано - один раз прочитать.
grinux
Цитата(jcxz @ Aug 28 2017, 09:54) *
Код
define region RAM_regionA   = mem:[from 0x1FFE8000 size 0x18000]; //PSRAM (code)
define region RAM_regionB   = mem:[from 0x20000000 size 0x20000]; //DSRAM1 (RW-data)
define region RAM_regionC   = mem:[from 0x20020000 size 0x20000]; //DSRAM2 (RW-data)
...
place in RAM_regionB | RAM_regionC {rw, first block CSTACK, section .raw, block HEAP};

PS: Неужто кто-то ещё пишет новое ПО для столь старого МК?? wacko.gif


Спасибо, то что нужно.

Новое не пишет, а старое развивается и поджирает память потихоньку.



Цитата(VladislavS @ Aug 28 2017, 10:01) *
Интересно, как бедный линкер будет догадываться куда автоматически разместить переменные, если вы ему об этом не хотите говорить?

Кстати, надо аккуратней с размещением инициализированных данных во всяких "железных буферах". У них доступ бывает ограничен по разрядности. При копировании инициализирующих данных стартап код не знает про это ничего. Недавно пытался на STM32 в USB_PAM инициализированный массив разместить - не вышло, данные неправильно в него копируются.


Спасибо, буду иметь ввиду.
grinux
Цитата(VladislavS @ Aug 28 2017, 10:01) *
Интересно, как бедный линкер будет догадываться куда автоматически разместить переменные, если вы ему об этом не хотите говорить?

Кстати, надо аккуратней с размещением инициализированных данных во всяких "железных буферах". У них доступ бывает ограничен по разрядности. При копировании инициализирующих данных стартап код не знает про это ничего. Недавно пытался на STM32 в USB_PAM инициализированный массив разместить - не вышло, данные неправильно в него копируются.


И не только инициализированных.
Например, только что случилось: функция записи IAP не работает, если данные для записи лежат в USB памяти. wacko.gif
VladislavS
Ну тут то всё в ваших руках - делайте как написано в документации и всё получится. А вот изменить с-либовский код уже не так просто.
grinux
Цитата(VladislavS @ Aug 30 2017, 21:40) *
Ну тут то всё в ваших руках - делайте как написано в документации и всё получится. А вот изменить с-либовский код уже не так просто.


Это функции bootrom.
Я сделал так
place in ROM_region { readonly, first block VER_INFO};
place in RAM_region { section SYS_RAM, block CSTACK, block SVC_STACK, block IRQ_STACK, block FIQ_STACK, block UND_STACK, block ABT_STACK, block HEAP };
place in RAM_region | USB_DMA_RAM_region | EMAC_DMA_RAM_region { readwrite };

char iap_buf[xxx] @ "SYS_RAM";
VladislavS
Разместить не проблема. Главное правильно писать/читать.
jcxz
Цитата(grinux @ Aug 30 2017, 21:45) *
char iap_buf[xxx] @ "SYS_RAM";[/b]

Насколько помню даташиты LPC: при вызове функций IAP не должно быть выполнения кода из флешь, в том числе и ISR. И они (IAP) или сами внутре запрещают прерывания или запретить их должны Вы. Отсюда вывод: данный буфер можно совместить к примеру с IRQ_STACK - union рулит. И таким образом сэкономить ОЗУ в старом ПО, поджирающем память.
И вообще: union творит чудеса на поприще экономии байтов ОЗУ. Присмотритесь к нему.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.