Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Стратегия размещения функций Keil
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Golikov A.
Всем привет!

В 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 коду?

Obam
Цитата(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.
Golikov A.
Вот блин... всегда читал строчку из манула
Цитата
The Cortex-M3 offers many new features, including a Thumb-2 instruction set

считая что типа второй тумб вместо первого, и считал что это в добавок. И что-то даже не поглядел что АРМ набора вообще больше нету...
С этим разобрались, спасибо.

А про стратегию функций кейла кто знает где глянуть?
scifi
Цитата(Golikov A. @ Apr 27 2015, 10:53) *
А про стратегию функций кейла кто знает где глянуть?

Нету никакой стратегии. С настройками по умолчанию все функции идут в флеш. Ну а если начинаете что-то крутить - это уже на вашей совести.
Golikov A.
Цитата
Нету никакой стратегии. С настройками по умолчанию все функции идут в флеш. Ну а если начинаете что-то крутить - это уже на вашей совести.

А если не крутил, а половина функций на файлах которых стоит Code/Const - default оказались в РАМе, то что делать?

есть файл у которого ZI о other стоят в рам перенести, но код в дефолте, а функции из него все равно в РАМ попмали...

Какая то видать стратегия есть, причем в некоторых файлах часть функций во флеше осталась, а часть в РАМе.
scifi
MAP-файл - в студию!
aaarrr
Цитата(scifi @ Apr 27 2015, 11:49) *
MAP-файл - в студию!

И .scat тоже
ViKo
и тип процессора. sm.gif
Golikov A.
Lpc1768, scart по умолчанию, то есть какой кеил сам генерит. Мар сейчас не могу, но по нему фугкции лежат в раме с 2000... Ажреса.
aaarrr
Цитата(Golikov A. @ Apr 27 2015, 14:22) *
scart по умолчанию, то есть какой кеил сам генерит.

Все равно приложите, иначе концов не найти.
Golikov A.
Код
; *************************************************************
; *** 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)


я вижу что в скатере все его секции туда запхались, но вопрос какого лешего? Скатер генерится самим кейлом, то есть я его в папке открыл, в среде к нему даже доступа нет. Вот такие чудеса...
aaarrr
Цитата(Golikov A. @ Apr 27 2015, 15:56) *
я вижу что в скатере все его секции туда запхались, но вопрос какого лешего? Скатер генерится самим кейлом, то есть я его в папке открыл, в среде к нему даже доступа нет. Вот такие чудеса...

Вот поэтому и не стоит программировать "галочками" - чудес меньше будет.
scifi
Цитата(aaarrr @ Apr 27 2015, 16:05) *
Вот поэтому и не стоит программировать "галочками" - чудес меньше будет.

Предлагаете читать мануалы? Мануалы придумал трус! yeah.gif
aaarrr
Цитата(scifi @ Apr 27 2015, 16:13) *
Предлагаете читать мануалы? Мануалы придумал трус! yeah.gif

Читать даже не предлагаю, но открыть и сделать Ctrl-F всегда можно.
Golikov A.
Цитата
Вот поэтому и не стоит программировать "галочками" - чудес меньше будет.

Я только За, но многим удобнее галочками (не один же я работаю на проектом)... Справедливости ради надо заметить что хуже работать не стало sm.gif, то есть функциональность сохранилась...

Цитата
Предлагаете читать мануалы? Мануалы придумал трус!

Вы тут ни разу неправы. Если у вас среда типа какоса или IAR, то там есть явно представленный скатер файл, который заполняется руками или генерится визардом. А если у вас keil, то править руками скатер файл - это бороться с ветряными мельницами, он же будет его подменять. Да там действительно можно снять кучу галочек и перейти на полностью ручное управление, но изначально в галочной системе есть какой-то workflow который можно, а современных реалиях и нужно использовать, потому что сокращает время.

Так что наезд в данном случае не принимается, мануалы тут не причем.

Цитата
Читать даже не предлагаю, но открыть и сделать Ctrl-F всегда можно.

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

Но великие читатели мануалов могут снизайти и указать ничтожному где про это написано...
scifi
Цитата(Golikov A. @ Apr 27 2015, 16:31) *
вы тоже не правы, потом что в мануале то как раз про галочки расписано как должно быть, а по факту получается иначе. Может в кейле есть еще какие-то способы дать указания разметке, про которые я не знаю....

Ну как же? Вы же уже сказали, что
Цитата(Golikov A. @ Apr 27 2015, 16:31) *
... не один же я работаю на проектом

Вот и ищите среди них любителя тыкать в галочки biggrin.gif

Цитата(Golikov A. @ Apr 27 2015, 16:31) *
Но великие читатели мануалов могут снизайти и указать ничтожному где про это написано...

ЕМНИП, у кейла файл проекта (где хранятся эти галочки) пишется открытым текстом. Полистайте, может быть увидете, где именно галки спрятались.
Golikov A.
Давайте перестанем пытаться меня поддеть и сосредоточимся на тексте

есть в проекте 2 файла.
1. стоят галочки разместить в RAM: code, ZI, Other
2. стоят галочки разместить в RAM: ZI, Other

по какой-то причине для обоих файлов секция text попала в RAM, вот меня и интересует что на это могло повлиять. То есть может быть если функции первого файла стоят в раме, и вызывают функции второго файла, это как-бы тоже переносит их в RAM. Может есть какие-то стратегии оптимизации, которые функции какого-то размера или частоты использования переносят в RAM. Или переменные перенесенные в RAM и используемые в функциях тоже их с собой потянули (хотя константы вроде как идут в первой секции, а осnальные и так обычно в RAM)

Вот каким вопросом задаюсь я, а не тем почему галочка появилась...
aaarrr
Цитата(Golikov A. @ Apr 27 2015, 16:31) *
...если у вас keil, то править руками скатер файл - это бороться с ветряными мельницами, он же будет его подменять. Да там действительно можно снять кучу галочек и перейти на полностью ручное управление, но изначально в галочной системе есть какой-то workflow который можно, а современных реалиях и нужно использовать, потому что сокращает время.

Раньше отключалось легко и непринужденно, одной галочкой sm.gif

Ничего не сокращает - десяток строк проще руками написать.

Цитата(Golikov A. @ Apr 27 2015, 16:44) *
То есть может быть если функции первого файла стоят в раме, и вызывают функции второго файла, это как-бы тоже переносит их в RAM. Может есть какие-то стратегии оптимизации, которые функции какого-то размера или частоты использования переносят в RAM. Или переменные перенесенные в RAM и используемые в функциях тоже их с собой потянули (хотя константы вроде как идут в первой секции, а осnальные и так обычно в RAM)

Вот каким вопросом задаюсь я, а не тем почему галочка появилась...

В Вашем случае все сделано в соответствии со скаттером. Соответственно, никакие стратегии оптимизации ни при чем совершенно.
Golikov A.
не о том разговор..

В общем заключаю что это скорее баг чем фича. То есть должно было работать так, а получилось иначе, и никакой магии... ну и ладно, обычная ошибка....

интересно для LPC1768 есть выигрыш от запуска функций из ARM, он же 100 МГц, а читает за 5 тактов чуть ли не 8 инструкций, и имеет несколько блоков для сохранения считанного...

Цитата
В Вашем случае все сделано в соответствии со скаттером. Соответственно, никакие стратегии оптимизации ни при чем совершенно.

тогда возникает вопрос почему скатер сделан не согласно настройкам...
aaarrr
Цитата(Golikov A. @ Apr 27 2015, 16:58) *
тогда возникает вопрос почему скатер сделан не согласно настройкам...

Это или глюк среды, или где-то среди галочек что-то осталось незамеченным.
toweroff
Цитата(aaarrr @ Apr 27 2015, 16:55) *
Раньше отключалось легко и непринужденно, одной галочкой sm.gif

удивитесь, наверное, но и по сей день ничего не поменялось sm.gif
Нажмите для просмотра прикрепленного файла
я уже давно отключаю автоскаттер и сам указываю, что где хранить, если это мне нужно
Golikov A.
ну а смысл тогда кейла если все по отключать и руками вбивать?
scifi
Цитата(Golikov A. @ Apr 27 2015, 19:34) *
ну а смысл тогда кейла если все по отключать и руками вбивать?

У кейла хороший отладчик.
А вообще, если какая-то свистелка-перделка к нему прикручена, ей совсем не обязательно пользоваться.
Golikov A.
Но также не обязательно отказываться, если она мелодично свистит) В 90% случаев она работает как надо, будет посвистыватьsm.gif...

ровно также отладку в порт никто не отменял)
toweroff
Цитата(Golikov A. @ Apr 27 2015, 19:34) *
ну а смысл тогда кейла если все по отключать и руками вбивать?

это дает точное знание о том, где что будет лежать. Даже в этом топике пришлось перелопатить кучу всего, в результате придти к тому же скаттеру.
Кстати, описание именно его лежит в одном документе с линкером на инфоцентре арма, а не галочек кейла, странно - почему?
Golikov A.
Всегда ли оно надо знать? Вот мне это интересно в моем проекте, но не критично, что в РАМ что во флэш он работает штатно. И я думаю еще с десяток такого рода проектов можно сделать. Иногда это нужно, там можно и руками, а иногда нет, там на автомате быстро прокатит.


Цитата
Кстати, описание именно его лежит в одном документе с линкером на инфоцентре арма, а не галочек кейла, странно - почему?

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

Я сам сторонник того что надо прописывать биты в регистры а не тыкать галочки в среде, но иногда это здорово сокращает время "на быстренько попробовать", так чего бы не овладеть данной функцией? Что вы потеряете если будете знать больше путей? Вот я теперь знаю, что данная часть не совершенна, и за ней надо следить, но если не парит можно пользоваться.


Цитата
Даже в этом топике пришлось перелопатить кучу всего, в результате придти к тому же скаттеру

Знание о том что скатер засунул функции в РАМ не дает ответа на вопрос какого черта в скатере появилось задание так сделать, так что это не аргумент.
aaarrr
Не знаю как для других, а для меня скрипт линкера является неотъемлемой частью исходных текстов проекта. Его можно один раз сгенерировать средой, но затем содержимое лучше зафиксировать и править только руками. Автоматы хороши только для быстрого старта в незнакомом окружении.
toweroff
Цитата(aaarrr @ Apr 27 2015, 21:35) *
Не знаю как для других, а для меня скрипт линкера является неотъемлемой частью исходных текстов проекта. Его можно один раз сгенерировать средой, но затем содержимое лучше зафиксировать и править только руками. Автоматы хороши только для быстрого старта в незнакомом окружении.

+
генерится скрипт, отключается галка, чтобы кейл его не портил каждый раз, и включается в svn
кейловыми галками тоже не все так гладко, он включает весь модуль целиком в область, а если мне это не нужно?
Golikov A.
Ну может вы и правы. Тем более что за время жизни проекта этот скрипт редко меняется, в целом если жмет и руками лень, можно опять же кейлом перегенерить.

Спасибо всем участникам беседы.
Golikov A.
А вот мне тут подумалось. Кроме того что сказать линкеру разместить функцию в RAM, надо же еще где-то написать копирование данных из адреса флеш, в тот адрес где разместили функцию. Сама же она туда не перелезет. В технологии галочек за этим кеил следит, чего то теперь мне эта технология стала казаться опасной...
aaarrr
Цитата(Golikov A. @ Apr 28 2015, 12:16) *
А вот мне тут подумалось. Кроме того что сказать линкеру разместить функцию в RAM, надо же еще где-то написать копирование данных из адреса флеш, в тот адрес где разместили функцию. Сама же она туда не перелезет.

Так собственно линкер это и делает.
Golikov A.
у кортексов встроена функция переброски памяти?
aaarrr
Цитата(Golikov A. @ Apr 28 2015, 13:53) *
у кортексов встроена функция переброски памяти?

Линкер создаст таблицы и подцепит необходимое.
Golikov A.
А в какой момент будет копирование? до ресета что ли?
Сергей Борщ
Цитата(Golikov A. @ Apr 28 2015, 14:04) *
А в какой момент будет копирование? до ресета что ли?
Не знаю как делает Кейл (а вам влом посмотреть листинг?), я копирую заодно с инициализированными переменными.
aaarrr
Цитата(Golikov A. @ Apr 28 2015, 14:04) *
А в какой момент будет копирование? до ресета что ли?

До перехода на main(). Поинтересуйтесь, например, содержимым InRoot$$Sections.
Golikov A.
Цитата
Не знаю как делает Кейл (а вам влом посмотреть листинг?), я копирую заодно с инициализированными переменными.

В 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? ну да там же и все копировщики и инициализаторы вызываются, но текст их не доступен... означает ли что если я делаю файл для линкера руками, то я должен и руками все эти копировщики поправить, а то беда может быть.
esaulenka
Не надо ничего руками трогать, оно и так хорошо работает. Линкер создаёт специальные символы, по которым этот __main() инициализирует RAM.
Помнится, в скаттер-файле можно легко ошибиться - всё собирается, но этот __main() копирует данные вечно.

PS почти всегда пользовался автоматическим scatter'ом. Максимум, что мне надо было - "откусить" кусочек flash под загрузчик, это галками сделать легко.
Для более сложной конфигурации (вспомнить бы, зачем мне потребовалось раскидывать функции по RAM, да ещё с жёстко заданными адресами..) пришлось изрядно почитать, и заработало оно не сразу.
aaarrr
Цитата(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() копирует данные вечно.

Ошибиться и в программе можно, но какой же это аргумент?

Структура у скаттера очень простая и наглядная. Возможные "хотелки" на раз находятся в документации.
Golikov A.
Цитата
Нет, все сделает линкер.

линкер он кому принадлежит? Это же часть кейла? то есть у другой среды он может быть реализован иначе? Или же он как-то стандартизован на уровне ARM?
aaarrr
Цитата(Golikov A. @ Apr 28 2015, 18:42) *
линкер он кому принадлежит? Это же часть кейла? то есть у другой среды он может быть реализован иначе? Или же он как-то стандартизован на уровне ARM?

Линкер является частью RVCT, т.е. относится не только к Кейлу, но и к прочей продукции ARM.
У IAR, GNU, GreenHills и прочих решения свои, но общие принципы одинаковые.
Golikov A.
То есть на самом деле стандартизован на уровне ARM...

спасибо за пояснения...
toweroff
Цитата(Golikov A. @ Apr 28 2015, 15:56) *
но текст их не доступен... означает ли что если я делаю файл для линкера руками, то я должен и руками все эти копировщики поправить, а то беда может быть.

почему недоступен? отладчиком все прекрасно видно
ничего править руками не нужно. Как в скаттере расписано, так линкер сам и соберет в нужных областях. Что нужно - проинициализирует, что нужно - скопирует
а так оно да, __main != main, после как раз восстановления областей на своих местах управление передается на main()
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.