Перейти к содержанию
    

Выполнение ф-ций из ram

Добрый день! Подскажите пожалуйста про выполнение ф-ций из ram. Можно ли как то сделать так, что бы ф-ции кототорые выполняются в теле данной ф-ци, но не обрамлённые дерективой линковщику, так же выполнялись из ram?

Например, есть 2 ф-ции: void f1(void) и void f2(void).

__attribute__((section(".itcm"))) void f1(void)
{
  f2();
}

При этом, я хочу что бы f2() так же находилась и выполнялась из ram. Но при этом я не хочу лезть в исходник (где объявлена ф-ция f2) и напротв всхех ф-ций ставить дерективу ((section(".itcm"))). Например, моя ф-ция, помимо прочего может использовать кубовские халы или сторонние файлы исходников, в которые я бы не хотел лезть и что то в них править.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Специального ключа компилятора нет. Можно попробовать идти таким путем - собирать вашу функцию и все, что ей требуется как отдельную программу в промежуточный объектный файл и вторым проходом линковать с остальной частью программы, размещая секции .text этого промежуточного объектного файла в ОЗУ. 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

40 minutes ago, Сергей Борщ said:

Специального ключа компилятора нет. Можно попробовать идти таким путем - собирать вашу функцию и все, что ей требуется как отдельную программу в промежуточный объектный файл и вторым проходом линковать с остальной частью программы, размещая секции .text этого промежуточного объектного файла в ОЗУ. 

Ух ё... Не до такого не дорос ещё. Проще директив понавтыркивать. Спасибо за помощь.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

в скриптпх линкера можно явно переложить что угодно куда угодно. и править Ссорсы для этого не придется

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, AlexRayne сказал:

в скриптпх линкера можно явно переложить что угодно куда угодно. и править Ссорсы для этого не придется

Можно. Только работать оно после этого перестанет. С довольно высокой вероятностью.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

вобчем то да, чтоб оно работало надо стартап адекватный

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

11 минут назад, AlexRayne сказал:

вобчем то да, чтоб оно работало надо стартап адекватный

Дело не в стартапе. Надо проследить всю иерархию вызовов функций, на всю глубину - чтобы всю эту иерархию скопировать в ОЗУ. Также скопировать все данные этих функций в ОЗУ. Отделить секции, функций выполняющихся только из флеша, от выполняющихся из ОЗУ. Соответственно - откорректирровать все адреса переходов и вызовов. И смещения const-данных (вычисляемых относительно PC). С учётом также тех функций (и данных), которые сгенерит оптимизатор.

А это в принципе невозможно сделать вручную.

Поэтому выбор невелик:

1. Или как завещал Сергей Борщ.

2. Или воспользоваться возможностями компилятора (__ramfunc в IAR).

Но ни то ни другое не подходит под изначальные хотелки ТС.

 

PS: А стартап - дело десятое.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 минуту назад, jcxz сказал:

2. Или воспользоваться возможностями компилятора (__ramfunc в IAR).

чем это отличается от назначения функции в ОЗУсекцию в линкером? окромя ворнингов?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

14 минут назад, AlexRayne сказал:

чем это отличается от назначения функции в ОЗУсекцию в линкером? окромя ворнингов?

Отличается тем, что компилятор знает, что данная функция будет исполняться из ОЗУ. И что она не должна использовать никакие данные из флеша.

Поэтому если у вас, например, в одном месте кода вызывается memset() и в другом месте также вызывается memset(). То:

1) Если обе этих точки вызова находятся в обычных функциях (не __ramfunc), то в конечном образе прошивки будет один экземпляр кода memset(), вызываемый из обеих точек (и находящийся во флешь).

2) Если же одна точка вызова - в обычной функции, а другая - в __ramfunc-функции, то в исполняемом образе в памяти МК (после старта прошивки), будет 2 копии кода memset(): одна - во флешь, другая - в ОЗУ.

Аналогично, если у вас в двух функциях (обычной и __ramfunc) используется какая-то одна и та же константа, то:

1) В образе прошивки в памяти МК может быть только одна копия этой константы;

2) Будет 2 копии этой константы - одна во флешь, другая - в ОЗУ.

И заботится обо всём этом компилятор. Он не одну функцию куда-то там "назначает", а всю цепочку вложенных вызовов из этой функции. Всё цепочку переносит в ОЗУ. И всю совокупность всех const-данных, используемых во всей этой цепочке (делая копии при необходимости). А также выдаёт варнинги, если имеются какие-то не __ramfunc-функции, вызываемые из __ramfunc-функций.

Вручную вы этого не сделаете.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 минут назад, jcxz сказал:

Вручную вы этого не сделаете.

что значит не сделаю вручную, что мне помешает?

в остальном приятный автомат у иара признаться. как в gcc это проворачивают?

Изменено пользователем AlexRayne

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

45 минут назад, AlexRayne сказал:

что значит не сделаю вручную, что мне помешает?

Ну так покажите как вы это сделаете?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 минуту назад, jcxz сказал:

Ну так покажите как вы это сделаете?

отследить все связи и переложить в ОЗУ - тоже самое что иар делает. в чем проблему то видите? 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Линковать программу как полностью выполняющуюся из ОЗУ и не парить себе моск:crazy:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

35 минут назад, AlexRayne сказал:

отследить все связи и переложить в ОЗУ - тоже самое что иар делает. в чем проблему то видите? 

Так покажите нам как, раз не видите проблем.

Вот например внутри функции (в её начале):

ADR.W    R1,table000        
LDR      R1,[R1, R0, LSL #+2]

в R0 - входной аргумент функции. table000 - const. Покажите как будете "отслеживать связи" для table000? С какого адреса по какой будете её копировать в ОЗУ?  :biggrin:

А если в коде встретится команда например BX R0 - как будете "отслеживать связи" куда она ведёт?  :biggrin:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Береш исходник и смотриш. и хреф в помощ. Иар не магический шар, связи выводит не из ноосферы а из сорса. отслеживать асемблерный код нет смысла.

конкретно в приведенном случае придется всю таблицу table000 в озу переложить.

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...