реклама на сайте
подробности

 
 
 
Reply to this topicStart new topic
> Размещение кода функции в RAM, компилятор GCC
Poluektovich
сообщение Sep 18 2015, 15:55
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 221
Регистрация: 15-09-08
Из: Зеленоград
Пользователь №: 40 201



Хочу чтобы код определенной функции выполнялся из 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.
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Sep 18 2015, 16:43
Сообщение #2


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



из чего это следует?
он во флеше для загрузки в RAM должен быть.
+ make clean надо сделать

Сообщение отредактировал _Pasha - Sep 18 2015, 16:45
Go to the top of the page
 
+Quote Post
DmitryM
сообщение Sep 19 2015, 05:54
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 583
Регистрация: 7-06-06
Из: Таганрог
Пользователь №: 17 840



Цитата(Poluektovich @ Sep 18 2015, 19:55) *
Хочу чтобы код определенной функции выполнялся из RAM. Для этого следовал рекомендациям:


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


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

__attribute__ ((section(".data"))); - это для констант размещенных в RAM
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Sep 19 2015, 06:28
Сообщение #4


Профессионал
*****

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



... И озаботиться тем, чтобы в ld script эта секция попадала в копируемые в ОЗУ данные.
Нолько на STM32F4xx это уже не требуется... Код в ОЗУ работает медленнеее чем из FLASH. На ATMEL SAM7 помогало.

Сообщение отредактировал Genadi Zawidowski - Sep 19 2015, 06:35
Прикрепленные файлы
Прикрепленный файл  STM32F446ZE_rom.zip ( 1.37 килобайт ) Кол-во скачиваний: 14
 
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Sep 19 2015, 09:01
Сообщение #5


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



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

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


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Sep 19 2015, 10:37
Сообщение #6


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



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

Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Sep 19 2015, 13:30
Сообщение #7


Профессионал
*****

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



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

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

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

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

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

((void (*)(void)) & codes [0]) ();
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Sep 20 2015, 02:52
Сообщение #8


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



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

Эта часть как раз понятна. Непонятно, что делать в скрипте линкера.
А если чтобы несколько функций на одни и те же адреса компилить?

Сообщение отредактировал _Pasha - Sep 20 2015, 02:54
Go to the top of the page
 
+Quote Post
Genadi Zawidowsk...
сообщение Sep 20 2015, 06:52
Сообщение #9


Профессионал
*****

Группа: Участник
Сообщений: 1 620
Регистрация: 22-06-07
Из: Санкт-Петербург, Россия
Пользователь №: 28 634



в сообщении №4 лежит архив со скриптом линкера - там как раз используется "AT" - аналог того, что делал оператор ".phase" в древнем микрософтовском асемблере M80. Несколько таких заведите... с соответствующими дублированиями.

Сообщение отредактировал Genadi Zawidowski - Sep 20 2015, 07:20
Go to the top of the page
 
+Quote Post
scifi
сообщение Sep 20 2015, 11:39
Сообщение #10


Гуру
******

Группа: Свой
Сообщений: 3 020
Регистрация: 7-02-07
Пользователь №: 25 136



Цитата(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]);
}
Go to the top of the page
 
+Quote Post
Poluektovich
сообщение Sep 21 2015, 14:31
Сообщение #11


Местный
***

Группа: Свой
Сообщений: 221
Регистрация: 15-09-08
Из: Зеленоград
Пользователь №: 40 201



Спасибо за помощь. Размещение в .ramfunc сработало.

Раньше при попытке размещения в .data выдавался warning:
Цитата
Warning: ignoring changed section attributes for .data
Go to the top of the page
 
+Quote Post

Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 18th July 2025 - 07:40
Рейтинг@Mail.ru


Страница сгенерированна за 0.01458 секунд с 7
ELECTRONIX ©2004-2016