grinux 0 27 августа, 2017 Опубликовано 27 августа, 2017 (изменено) · Жалоба Всем привет. Может кто-нибудь знает, как заставить линкер автоматически раскидывать 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 }; Изменено 27 августа, 2017 пользователем grinux Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 172 28 августа, 2017 Опубликовано 28 августа, 2017 · Жалоба Может кто-нибудь знает, как заставить линкер автоматически раскидывать 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: Неужто кто-то ещё пишет новое ПО для столь старого МК?? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 29 28 августа, 2017 Опубликовано 28 августа, 2017 · Жалоба Интересно, как бедный линкер будет догадываться куда автоматически разместить переменные, если вы ему об этом не хотите говорить? Кстати, надо аккуратней с размещением инициализированных данных во всяких "железных буферах". У них доступ бывает ограничен по разрядности. При копировании инициализирующих данных стартап код не знает про это ничего. Недавно пытался на STM32 в USB_PAM инициализированный массив разместить - не вышло, данные неправильно в него копируются. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Obam 29 28 августа, 2017 Опубликовано 28 августа, 2017 · Жалоба Чётко по требуемым адресам и в требуемой последовательности раскладываются "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 0 28 августа, 2017 Опубликовано 28 августа, 2017 · Жалоба 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: Неужто кто-то ещё пишет новое ПО для столь старого МК?? Спасибо, то что нужно. Новое не пишет, а старое развивается и поджирает память потихоньку. Интересно, как бедный линкер будет догадываться куда автоматически разместить переменные, если вы ему об этом не хотите говорить? Кстати, надо аккуратней с размещением инициализированных данных во всяких "железных буферах". У них доступ бывает ограничен по разрядности. При копировании инициализирующих данных стартап код не знает про это ничего. Недавно пытался на STM32 в USB_PAM инициализированный массив разместить - не вышло, данные неправильно в него копируются. Спасибо, буду иметь ввиду. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
grinux 0 30 августа, 2017 Опубликовано 30 августа, 2017 · Жалоба Интересно, как бедный линкер будет догадываться куда автоматически разместить переменные, если вы ему об этом не хотите говорить? Кстати, надо аккуратней с размещением инициализированных данных во всяких "железных буферах". У них доступ бывает ограничен по разрядности. При копировании инициализирующих данных стартап код не знает про это ничего. Недавно пытался на STM32 в USB_PAM инициализированный массив разместить - не вышло, данные неправильно в него копируются. И не только инициализированных. Например, только что случилось: функция записи IAP не работает, если данные для записи лежат в USB памяти. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 29 30 августа, 2017 Опубликовано 30 августа, 2017 · Жалоба Ну тут то всё в ваших руках - делайте как написано в документации и всё получится. А вот изменить с-либовский код уже не так просто. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
grinux 0 30 августа, 2017 Опубликовано 30 августа, 2017 (изменено) · Жалоба Ну тут то всё в ваших руках - делайте как написано в документации и всё получится. А вот изменить с-либовский код уже не так просто. Это функции 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"; Изменено 30 августа, 2017 пользователем grinux Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
VladislavS 29 30 августа, 2017 Опубликовано 30 августа, 2017 · Жалоба Разместить не проблема. Главное правильно писать/читать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
jcxz 172 30 августа, 2017 Опубликовано 30 августа, 2017 · Жалоба char iap_buf[xxx] @ "SYS_RAM";[/b] Насколько помню даташиты LPC: при вызове функций IAP не должно быть выполнения кода из флешь, в том числе и ISR. И они (IAP) или сами внутре запрещают прерывания или запретить их должны Вы. Отсюда вывод: данный буфер можно совместить к примеру с IRQ_STACK - union рулит. И таким образом сэкономить ОЗУ в старом ПО, поджирающем память. И вообще: union творит чудеса на поприще экономии байтов ОЗУ. Присмотритесь к нему. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться