|
Стратегия размещения функций Keil, Как определяется какая функция попадет в RAM |
|
|
|
Apr 27 2015, 07:27
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Всем привет!
В keil есть возможность нажав на файл исходников правой кнопкой и выбрав options, для Cortex процов задать регионы для секций Code/Const, Zero Init Data, Other Data
по умолчанию стоит default. И я был уверен что это для Code/Const - flash, а для остальных RAM. Так вот поглядел я карту памяти после компиляции и с удивлением обнаружил что достаточно большая часть функций размещены в RAM. Но не все, то есть получается что у кейла есть какая-то стратегия размещения функций? Кто нибудь, что нибудь знает про это?
Еще я обнаружил что кеил понаделал thumb код, хотя я думал по умолчанию будет ARM код, и только при желании оптимизации он будет что-то крутить. Или после появления thumb2 стало уже не можно пользоваться ARM кодом? Я понимаю что с точки зрения флеш ускорителей которые читают за 5 тактов проца 128 бит, лучше прочитать ~8 thumb инструкций (примерно потому что в thumb2 они бывают и 32 битные) чем 4 ARM инструкции, для этого преимущество отдано thumb коду?
|
|
|
|
3 страниц
1 2 3 >
|
 |
Ответов
(1 - 42)
|
Apr 27 2015, 07:44
|

Знающий
   
Группа: Участник
Сообщений: 756
Регистрация: 14-11-14
Пользователь №: 83 663

|
Цитата(Golikov A. @ Apr 27 2015, 11:27)  Всем привет!
В keil есть возможность нажав на файл исходников правой кнопкой и выбрав options, для Cortex процов задать регионы для секций Code/Const, Zero Init Data, Other Data
по умолчанию стоит default. И я был уверен что это для Code/Const - flash, а для остальных RAM. Так вот поглядел я карту памяти после компиляции и с удивлением обнаружил что достаточно большая часть функций размещены в RAM. Но не все, то есть получается что у кейла есть какая-то стратегия размещения функций? Кто нибудь, что нибудь знает про это?
Еще я обнаружил что кеил понаделал thumb код, хотя я думал по умолчанию будет ARM код, и только при желании оптимизации он будет что-то крутить. Или после появления thumb2 стало уже не можно пользоваться ARM кодом? Я понимаю что с точки зрения флеш ускорителей которые читают за 5 тактов проца 128 бит, лучше прочитать ~8 thumb инструкций (примерно потому что в thumb2 они бывают и 32 битные) чем 4 ARM инструкции, для этого преимущество отдано thumb коду? Маэстро, если речь идет о Cortex, то только Thumb-2. Даже если и 32разрядные всё равно Thumb. Никаких ARM.
--------------------
Пролетарий умственного труда.
|
|
|
|
|
Apr 27 2015, 07:53
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Вот блин... всегда читал строчку из манула Цитата The Cortex-M3 offers many new features, including a Thumb-2 instruction set считая что типа второй тумб вместо первого, и считал что это в добавок. И что-то даже не поглядел что АРМ набора вообще больше нету... С этим разобрались, спасибо. А про стратегию функций кейла кто знает где глянуть?
|
|
|
|
|
Apr 27 2015, 08:45
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Цитата Нету никакой стратегии. С настройками по умолчанию все функции идут в флеш. Ну а если начинаете что-то крутить - это уже на вашей совести. А если не крутил, а половина функций на файлах которых стоит Code/Const - default оказались в РАМе, то что делать? есть файл у которого ZI о other стоят в рам перенести, но код в дефолте, а функции из него все равно в РАМ попмали... Какая то видать стратегия есть, причем в некоторых файлах часть функций во флеше осталась, а часть в РАМе.
|
|
|
|
|
Apr 27 2015, 12:56
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Код ; ************************************************************* ; *** Scatter-Loading Description File generated by uVision *** ; *************************************************************
LR_IROM1 0x00010000 0x00010000 { ; load region size_region ER_IROM1 0x00010000 0x00010000 { ; load address = execution address *.o (RESET, +First) *(InRoot$$Sections) .ANY (+RO) } RW_IRAM1 0x10000000 0x00008000 { ; RW data .ANY (+RW +ZI) } RW_IRAM2 0x2007D000 0x00007000 { MyMAC.o (+RO +ZI +RW) FIFOModule.o (+RO) .ANY (+RW +ZI) } } вот такое вот... FIFOModule в свойствах стоит запихать его в RAM и он там. Цитата GetFIFODataSize 0x2007d5f9 Thumb Code 28 fifomodule.o(.text) GetFIFOBufferSize 0x2007d615 Thumb Code 30 fifomodule.o(.text) GetFIFOBufferEnd 0x2007d633 Thumb Code 16 fifomodule.o(.text) GetFIFODataEnd 0x2007d643 Thumb Code 16 fifomodule.o(.text) а вот для MyMAC - это езернетныймодуль, для него Code/Const стоит в дефолт, только данные и ZI в рам, а он тоже почему то хором попал в РАМ Цитата ENET_IRQHandler 0x2007d357 Thumb Code 198 mymac.o(.text) я вижу что в скатере все его секции туда запхались, но вопрос какого лешего? Скатер генерится самим кейлом, то есть я его в папке открыл, в среде к нему даже доступа нет. Вот такие чудеса...
|
|
|
|
|
Apr 27 2015, 13:31
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Цитата Вот поэтому и не стоит программировать "галочками" - чудес меньше будет. Я только За, но многим удобнее галочками (не один же я работаю на проектом)... Справедливости ради надо заметить что хуже работать не стало  , то есть функциональность сохранилась... Цитата Предлагаете читать мануалы? Мануалы придумал трус! Вы тут ни разу неправы. Если у вас среда типа какоса или IAR, то там есть явно представленный скатер файл, который заполняется руками или генерится визардом. А если у вас keil, то править руками скатер файл - это бороться с ветряными мельницами, он же будет его подменять. Да там действительно можно снять кучу галочек и перейти на полностью ручное управление, но изначально в галочной системе есть какой-то workflow который можно, а современных реалиях и нужно использовать, потому что сокращает время. Так что наезд в данном случае не принимается, мануалы тут не причем. Цитата Читать даже не предлагаю, но открыть и сделать Ctrl-F всегда можно. вы тоже не правы, потом что в мануале то как раз про галочки расписано как должно быть, а по факту получается иначе. Может в кейле есть еще какие-то способы дать указания разметке, про которые я не знаю.... Но великие читатели мануалов могут снизайти и указать ничтожному где про это написано...
|
|
|
|
|
Apr 27 2015, 13:36
|
Гуру
     
Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136

|
Цитата(Golikov A. @ Apr 27 2015, 16:31)  вы тоже не правы, потом что в мануале то как раз про галочки расписано как должно быть, а по факту получается иначе. Может в кейле есть еще какие-то способы дать указания разметке, про которые я не знаю.... Ну как же? Вы же уже сказали, что Цитата(Golikov A. @ Apr 27 2015, 16:31)  ... не один же я работаю на проектом Вот и ищите среди них любителя тыкать в галочки Цитата(Golikov A. @ Apr 27 2015, 16:31)  Но великие читатели мануалов могут снизайти и указать ничтожному где про это написано... ЕМНИП, у кейла файл проекта (где хранятся эти галочки) пишется открытым текстом. Полистайте, может быть увидете, где именно галки спрятались.
|
|
|
|
|
Apr 27 2015, 13:44
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Давайте перестанем пытаться меня поддеть и сосредоточимся на тексте
есть в проекте 2 файла. 1. стоят галочки разместить в RAM: code, ZI, Other 2. стоят галочки разместить в RAM: ZI, Other
по какой-то причине для обоих файлов секция text попала в RAM, вот меня и интересует что на это могло повлиять. То есть может быть если функции первого файла стоят в раме, и вызывают функции второго файла, это как-бы тоже переносит их в RAM. Может есть какие-то стратегии оптимизации, которые функции какого-то размера или частоты использования переносят в RAM. Или переменные перенесенные в RAM и используемые в функциях тоже их с собой потянули (хотя константы вроде как идут в первой секции, а осnальные и так обычно в RAM)
Вот каким вопросом задаюсь я, а не тем почему галочка появилась...
|
|
|
|
|
Apr 27 2015, 13:55
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Golikov A. @ Apr 27 2015, 16:31)  ...если у вас keil, то править руками скатер файл - это бороться с ветряными мельницами, он же будет его подменять. Да там действительно можно снять кучу галочек и перейти на полностью ручное управление, но изначально в галочной системе есть какой-то workflow который можно, а современных реалиях и нужно использовать, потому что сокращает время. Раньше отключалось легко и непринужденно, одной галочкой  Ничего не сокращает - десяток строк проще руками написать. Цитата(Golikov A. @ Apr 27 2015, 16:44)  То есть может быть если функции первого файла стоят в раме, и вызывают функции второго файла, это как-бы тоже переносит их в RAM. Может есть какие-то стратегии оптимизации, которые функции какого-то размера или частоты использования переносят в RAM. Или переменные перенесенные в RAM и используемые в функциях тоже их с собой потянули (хотя константы вроде как идут в первой секции, а осnальные и так обычно в RAM)
Вот каким вопросом задаюсь я, а не тем почему галочка появилась... В Вашем случае все сделано в соответствии со скаттером. Соответственно, никакие стратегии оптимизации ни при чем совершенно.
|
|
|
|
|
Apr 27 2015, 13:58
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
не о том разговор.. В общем заключаю что это скорее баг чем фича. То есть должно было работать так, а получилось иначе, и никакой магии... ну и ладно, обычная ошибка.... интересно для LPC1768 есть выигрыш от запуска функций из ARM, он же 100 МГц, а читает за 5 тактов чуть ли не 8 инструкций, и имеет несколько блоков для сохранения считанного... Цитата В Вашем случае все сделано в соответствии со скаттером. Соответственно, никакие стратегии оптимизации ни при чем совершенно. тогда возникает вопрос почему скатер сделан не согласно настройкам...
|
|
|
|
|
Apr 27 2015, 18:06
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Всегда ли оно надо знать? Вот мне это интересно в моем проекте, но не критично, что в РАМ что во флэш он работает штатно. И я думаю еще с десяток такого рода проектов можно сделать. Иногда это нужно, там можно и руками, а иногда нет, там на автомате быстро прокатит. Цитата Кстати, описание именно его лежит в одном документе с линкером на инфоцентре арма, а не галочек кейла, странно - почему? Ага а библиотеки HAL от кейла несмотря на свою кривость завоевывают все больше популярность. Так же уверен вы пользуетесь виндусом, а не командной строкой доса? Я сам сторонник того что надо прописывать биты в регистры а не тыкать галочки в среде, но иногда это здорово сокращает время "на быстренько попробовать", так чего бы не овладеть данной функцией? Что вы потеряете если будете знать больше путей? Вот я теперь знаю, что данная часть не совершенна, и за ней надо следить, но если не парит можно пользоваться. Цитата Даже в этом топике пришлось перелопатить кучу всего, в результате придти к тому же скаттеру Знание о том что скатер засунул функции в РАМ не дает ответа на вопрос какого черта в скатере появилось задание так сделать, так что это не аргумент.
|
|
|
|
|
Apr 28 2015, 12:56
|
Гуру
     
Группа: Свой
Сообщений: 4 256
Регистрация: 17-02-06
Пользователь №: 14 454

|
Цитата Не знаю как делает Кейл (а вам влом посмотреть листинг?), я копирую заодно с инициализированными переменными. В IAR я тоже все руками делал, правда для 7 арма, а тут кортекс и с кейлом разленился. Цитата До перехода на main(). Поинтересуйтесь, например, содержимым InRoot$$Sections. Поглядел что на векторе ресета инициализация клоков и переход в маин. 2 функции вызываются одна за другой. Код Reset_Handler PROC EXPORT Reset_Handler [WEAK] IMPORT SystemInit IMPORT __main
LDR R0, =SystemInit BLX R0 LDR R0, =__main BX R0 ENDP я не против того что и как по секциям линкером распределено, но когда питание выключено оно все во флэшке, а потом должно в рам перелезть, и вот в какой момент что-то я в замешательстве. UPD. отгадка в том что __main - это не main? ну да там же и все копировщики и инициализаторы вызываются, но текст их не доступен... означает ли что если я делаю файл для линкера руками, то я должен и руками все эти копировщики поправить, а то беда может быть.
|
|
|
|
|
Apr 28 2015, 13:49
|

Профессионал
    
Группа: Свой
Сообщений: 1 032
Регистрация: 13-03-08
Из: Маськва
Пользователь №: 35 877

|
Не надо ничего руками трогать, оно и так хорошо работает. Линкер создаёт специальные символы, по которым этот __main() инициализирует RAM. Помнится, в скаттер-файле можно легко ошибиться - всё собирается, но этот __main() копирует данные вечно.
PS почти всегда пользовался автоматическим scatter'ом. Максимум, что мне надо было - "откусить" кусочек flash под загрузчик, это галками сделать легко. Для более сложной конфигурации (вспомнить бы, зачем мне потребовалось раскидывать функции по RAM, да ещё с жёстко заданными адресами..) пришлось изрядно почитать, и заработало оно не сразу.
--------------------
Тут обсуждается творческий порыв, а не соответствие каким-либо стандартам ©
|
|
|
|
|
Apr 28 2015, 14:32
|
Гуру
     
Группа: Свой
Сообщений: 10 713
Регистрация: 11-12-04
Пользователь №: 1 448

|
Цитата(Golikov A. @ Apr 28 2015, 15:56)  отгадка в том что __main - это не main? ну да там же и все копировщики и инициализаторы вызываются, но текст их не доступен... Именно так: __main и main - это разные вещи. Цитата(Golikov A. @ Apr 28 2015, 15:56)  означает ли что если я делаю файл для линкера руками, то я должен и руками все эти копировщики поправить, а то беда может быть. Нет, все сделает линкер. Цитата(esaulenka @ Apr 28 2015, 16:49)  Помнится, в скаттер-файле можно легко ошибиться - всё собирается, но этот __main() копирует данные вечно. Ошибиться и в программе можно, но какой же это аргумент? Структура у скаттера очень простая и наглядная. Возможные "хотелки" на раз находятся в документации.
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|