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

Keil uVision. Выполнение кода из RAM

2 часа назад, jcxz сказал:

Ну и что? В чём проблема скопировать руками и выполнить?

Можно. Проблемы нет. Просто лишние телодвижения, которые, КМК, можно каким-то образом сократить.
Ведь тот самый __main() как раз занимается установкой секций RO/RW/ZI. Он и копирует все функции, собственно.
Так вот работу по этому копированию и хотелось оставить на него.

По факту, если делать руками, то получится следующее. Допустим, есть у нас функция расчета CRC.
При запуске МК он инициализирует периферию (выполнение из Flash), проверяет условие входа в загрузчик.
Если в цепочке последовательных условий входа в загрузчик ни одно не сработало, выполняется последнее действие.
Это действие - сверка CRC прошивки, которая (возможно) лежит во Flash в области пользовательского приложения.

Значит, функция CRC дергается из Flash. На этом этапе.

Однако, если условие входа в загрузчик сработало (или после сверки CRC оказалось, что или приложение битое или его там нет), запускается его код.
Запуск загрузчика - это, собственно, передача управления функции __main(), которая инициализирует RO/RW/ZI в ОЗУ.

Но теперь засада: функция расчета CRC теперь нужна в дебрях логики самого загрузчика - например, сравнивать контрольную сумму пакетов при обмене.
То есть (поскольку весь загрузчик исполняется из ОЗУ) эта функция тоже должна оказаться в ОЗУ.

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

А если положиться на то, что __main() сама скопирует эту (эти) функции в ОЗУ, то задумываться о том, можно ли вызывать функцию или нет - не нужно.
Нет риска в этом случае, что код функции затерся другой функцией (ведь при ручном копировании надо всегда помнить, что лежит сейчас в памяти).

Так вот. Линкер кладет весь код (изначально) и данные в определенные секции во Flash. Мы можем сказать ему не упаковывать определенные регионы.
Значит, теоретически, у нас есть 2 копии одного и того же кода (на уровне бинарных кодов) - одна во Flash, другая в ОЗУ (естественно, при линковке в ОЗУ).
Мне моя логика подсказывала, что (возможно) существует вариант, когда я могу написать вот так

// GetCRC32() слинкована для работы из ОЗУ

...
  GetCRC32(&buf, len); // адрес вызова будет из ОЗУ
...
  __attribute__("вызовись из load-region image, плз")
  GetCRC32(&buf, len); // адрес вызова будет из Flash
...

:blush:

В map-файле я вижу адрес из load-региона, откуда грузится эта функция из Flash в ОЗУ.
Думаю, если я передам управление по этому адресу (с аргументами, естественно), функция запустится из Flash.
Что наводит на мысль, что скорее всего (теоретически) линкер может формировать символы а-ля [какой-то текст].GetCRC32.
Которые я и мог бы использовать в коде как ссылку на функцию-исходную-копию из load-региона.
 

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

Правильно ли я понимаю, что ваш вопрос больше "спортивный", т.е. расчитанный на повышение квалификации или исследование нового?

Что может быть приятнее, чем придумать себе проблему и героически ее решать?:biggrin: Шутка.
Вопрос для меня где-то между спортивным и полезным - с одной стороны мне интересно, затрагивался ли такой вопрос разработчиками тулзов.
С другой стороны мне интересно еще и потому, что

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

...можно же сразу в стартап-коде скопировать всё ПО в ОЗУ и там выполнить, в т.ч. и backend-логику?

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

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


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

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

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

Тогда полезнее (имхо) изучить работу с оверлеями.  :wink:

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


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

Решил не создавать новую тему и спросить здесь(встроенный поиск в этом форуме по словам "RAM" и "ОЗУ" не принес результатов):

Имеется достаточно относительно медленной QSPI флеш и ограниченное количество ОЗУ.

Требуется попеременно выполнять разные подпрограммы(задачи FreeRTOS) из ОЗУ, каждый раз копируя их из флеша.

Можно ли это осуществить в рамках одного проекта в Keil 4.53 ?

Пока предполагается задействовать позиционно-независимый код, поместить его в разные секции скаттера и копировать оттуда вручную.

Но как быть с отладкой, инициализацией переменных?

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


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

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

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

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

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

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

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

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

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

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