Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Размещение кода функции в RAM
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
Poluektovich
Хочу чтобы код определенной функции выполнялся из RAM. Для этого следовал рекомендациям:
Цитата
Placing code in RAM using GCC
Gcc supports the use of the __attribute__ keyword which allows you to apply special attributes to your code. There are many attributes you can apply; the one we are interested in is section .
The section attribute places code in a specific memory section as defined in the cm3gcc.ld file. RAM is defined as the .data section. So, for example, if you wanted to place a function in RAM the code for the function prototype would look like this:
void foo (void) __attribute__ ((section(".data")));


Однако. код по-прежнему размещется во FLASH.
_Pasha
из чего это следует?
он во флеше для загрузки в RAM должен быть.
+ make clean надо сделать
DmitryM
Цитата(Poluektovich @ Sep 18 2015, 19:55) *
Хочу чтобы код определенной функции выполнялся из RAM. Для этого следовал рекомендациям:


Однако. код по-прежнему размещется во FLASH.


Вообще-то надо
void foo (void) __attribute__ ((section(".ramfunc")));

__attribute__ ((section(".data"))); - это для констант размещенных в RAM
Genadi Zawidowski
... И озаботиться тем, чтобы в ld script эта секция попадала в копируемые в ОЗУ данные.
Нолько на STM32F4xx это уже не требуется... Код в ОЗУ работает медленнеее чем из FLASH. На ATMEL SAM7 помогало.
Сергей Борщ
Цитата(DmitryM @ Sep 19 2015, 08:54) *
__attribute__ ((section(".data"))); - это для констант размещенных в RAM
Да хоть горшком обзовите, только в печь не суйте. Какая линкеру разница, что конкретно за байты лежат в этой секции? Он не отличает коды команд от констант начальных значений. И решение с помещением кода в секцию .data - довольно элегантное: без дополнительных теловижений образ загружаемого в ОЗУ кода вместе с констанатами начальных значений размещается в ПЗУ, в ОЗУ под этот код резервируется место заодно с данными, стартап-код копирует образ кода из ПЗУ в ОЗУ вместе с начальными значениями данных. Я всегда добавлял в скрипт свою секцию рядом со входной секцией .data но так и не додумался сразу класть функции в секцию .data.

Poluektovich: сделайте минимальный проект из одной вашей функции и вызывающей ее main(). Выложите исходник и сдержимое .map, разберемся. Может даже и исходника хватит.
_Pasha
кста, вопрос.
как правильно сделать shared buffer?
например чтобы работать с областью ОЗУ как данными.
а затем скопировать код функции и запустить ее?

Genadi Zawidowski
Цитата
помещением кода в секцию .data - довольно элегантное

Что-то из тулзов на атрибуты секции ругалось при таком решении... Потому я у себя оставил ramfunc.

Цитата
работать с областью ОЗУ как данными. а затем скопировать код функции и запустить ее?

Делаете массив, заплолняете его кодами, затем вызываете начальный адрес как функцию (не забыть про thumb!).

Код
uint32_t codes [77];
...
codes [0] = 0xXXXX;
...

((void (*)(void)) & codes [0]) ();
_Pasha
Цитата(Genadi Zawidowski @ Sep 19 2015, 16:30) *
Делаете массив, заплолняете его кодами, затем вызываете начальный адрес как функцию (не забыть про thumb!).

Эта часть как раз понятна. Непонятно, что делать в скрипте линкера.
А если чтобы несколько функций на одни и те же адреса компилить?
Genadi Zawidowski
в сообщении №4 лежит архив со скриптом линкера - там как раз используется "AT" - аналог того, что делал оператор ".phase" в древнем микрософтовском асемблере M80. Несколько таких заведите... с соответствующими дублированиями.
scifi
Цитата(Genadi Zawidowski @ Sep 19 2015, 16:30) *
Делаете массив, заплолняете его кодами, затем вызываете начальный адрес как функцию (не забыть про thumb!).

+1. Я так обычно и делаю. Самый надёжный способ, и не требует настройки линкера.
В общем случае невозможно гарантировать, что компилятор не вставит в код функции вызов библиотечных функций типа длинного деления, memcpy и тому подобного.
Вот пример:
Код
static const uint16_t jump2fw[] =
{
        0xF850, 0xDB04, /* LDR.W SP, [R0], #4   */
        0x6800,         /* LDR.W R0, [R0]       */
        0x4700,         /* BX R0                */
};

void func(void)
{
        ...
        ((void (*)(int*))(1 + (int)jump2fw))(&fw_start[2]);
}
Poluektovich
Спасибо за помощь. Размещение в .ramfunc сработало.

Раньше при попытке размещения в .data выдавался warning:
Цитата
Warning: ignoring changed section attributes for .data
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.