Вопрос или предложение, загрузите на Flash, затем скопируйте в RAM во время выполнения.

victor_pv
Пт 15 мая 2015 г. 15:27
Я просто думал, что некоторым людям, кажется, нужна скорость для некоторых вещей, и, как мы заметили при перемещении PIN_MAP, чтобы вспыхивать, бег от вспышки довольно медленнее, чем RAM, очевидно, очевидно.

Итак, в этой линии Тикинга, я подумал, что если вам нужно запустить эскиз, который подходит в ОЗУ (я.эн. В устройстве 64 КБ) вам нужна вся скорость, которую вы можете получить по какой -либо причине, но вам нужно, чтобы эскиз был навсегда на доске, а не загружать в ОЗУ каждый раз?
Я думаю, что решение может появиться в форме загрузчика, который хранит код во вспышке, а не в ОЗУ, а затем при загрузке устройства он копирует этот код в ОЗУ и начнет работать там, как и он, если оно было загружено с опцией DFU Загрузите в ОЗУ, только он экономит его навсегда во время вспышки и копирует его в ОЗУ каждый раз.
Это дает преимущество скорости, при этом постоянно сохраняя эскиз на доске.

Кто -нибудь нуждается в дополнительной скорости? Я уже думал о том, чтобы сделать это без гораздо большего кода в загрузчике.

Рик Кимбалл
Пт 15 мая 2015 г. 18:24
Вы хотите использовать линкер и какой -то пользовательский код запуска для копирования ваших процедур от Flash в Ram при сбросе. Этот пост должен дать вам представление о том, что должно произойти:

https: // форум.Sparkfun.com/viewtopic.pH ... 61&Start = 0

-рик

victor_pv
Пт 15 мая 2015 г. 18:56
Рик, часть копии в ОЗУ может быть интегрирована в загрузчик DFU, так же, как и другой вариант, так что не потребуется дополнительного времени в сборе эскиза, если загрузчик управляет процессом копирования.
Мой вопрос, я думаю, это выглядит как что -то полезное для всех?
Мне просто пришло в голову, что это должно быть довольно легко добавить к загрузчику Maple DFU, но я не знаю, обнаружил, что кто -то здесь нуждался в этом.

Рик Кимбалл
Пт 15 мая 2015 г., 18:59
Изменить свое общее.INC файл и добавьте '.Раздел RamText 'в области данных: $ git diff -w common.inc diff --git a/STM32F1/variants/generic_stm32f103c/ld/common.inc b/STM32F1/variants/generic_ index 0c2b6a4..ebac91d 100644 --- a/STM32F1/variants/generic_stm32f103c/ld/common.inc +++ b/STM32F1/variants/generic_stm32f103c/ld/common.inc @@ -140,6 +140,9 @@ SECTIONS *(.got.plt) *(.got) *(.data .data.* .gnu.linkonce.d.*) + . = ALIGN(4); + *(.ramtext) + . = ALIGN(8); __data_end__ = .; } > REGION_DATA AT> REGION_RODATA (END)

Рик Кимбалл
Пт 15 мая 2015 г., 19:06
И да, эта функция, безусловно, полезна, если у вас есть код, который вы хотите запустить с нулевыми состояниями ожидания. Однако, если вы прыгаете взад -вперед между Flash и RAM, накладные расходы на код шпона могут уничтожить любые результаты, которые вы делаете.

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

-рик

Рик Кимбалл
Пт 15 мая 2015 г., 19:33
Извините, я думаю, что понял ваш вопрос неправильно.

Тем не менее, вы можете изменить LDSICT, чтобы поместить только код __start__ и векторы прерываний в «ПЗУ», а остальные кода хранятся в The Region_Data, а затем линкера разрешит все адреса выполнения на ОЗУ. Единственные виниры в этом случае CTORS и призыв к основному. Все остальное будет в баране.

victor_pv
Пт 15 мая 2015 г., 21:48
Я думал о двух возможных способах. Что -то подобное, изменение сценария линкера, чтобы код был в позиции ОЗУ. Как вы думаете, это сработает, и код начала скопировал бы все это от Flash в Ram, как это копирует область переменных? или, возможно, код ассемблера, который должен сделать копию?

Другой способ, которым я подумал, позволив сценарию линкера, как в опции загрузки на ОЗУ, но затем в коде загрузчика установите некоторую проверку, что если вектор сброса
(Что, я считаю, является вторым словом загрузки, поскольку первым является адрес стека), находится в адресе в адресе RAM Drap 2xxxxxxxx, а не сразу же вызовать код, сначала скопируйте его на ОЗУ, затем запустите его. Это устранило бы необходимость создания другого сценария линкера, но добавить немного сложности к загрузчику. Тем не менее, я думаю, что это не должно быть сложным, что -то подобное должно работать:
if (checkUserCode(USER_CODE_FLASH0X8002000+4)) copySketchToRam (); jumpToUser(USER_CODE_RAM); }

victor_pv
Сб 16 мая 2015 г. 1:00
Ну, я только что реализовал в значительной степени, как показано выше, и работает нормально.
Я могу загрузить в ОЗУ, загрузить на Flash ID1 в X5000, загрузить на Flash ID2 X2000 и загрузить, чтобы Flash ID2, а также эскиз, связанный со сценарием обычного ОЗУ, и загрузчик обнаруживает его правильно и копирует его из Flash и запуска там.
Понимает около 200 лет больше, чем раньше, хотя я уверен, что это можно уменьшить, и все еще всего 7.1 кб

Rogerclark
Сб 16 мая 2015 г., 6:20
Виктор,

Я не уверен, сколько людей захотят бежать из барана. Я вижу, что это может заставить код работать быстрее, чем во флэш -.

Я не изучил это подробно, но процессоры ARM имеют сложный трубопровод инструкций с предварительной перефшированием и т. Д
видеть http: // Infocenter.рука.com/help/index.младший ... Gjicf.HTML

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


Также.
Я не слишком уверен, как ты работаешь. Вы получаете загрузчик для загрузки на Flash, но выполняя предварительную копию от Flash в ОЗУ каждый раз, когда он загружается

Как Bootloader узнает, что Flash содержит программу, которая была связана с запуском в RAM ? Или вы говорите, что это работает только после загрузки, я.E он загружается, чтобы вспыхивать, а затем копировать, чтобы отнести?

Проблема, которую я столкнулся с загрузкой RAM на основе, заключалась в том, что после загрузки оперативной памяти по какой -то причине загрузчик не просто прыгнул в место начала оперативной памяти, он, казалось, сбросил загрузчик, и в этом случае у него не было бы определенного способа узнать Была ли последняя загрузка, чтобы отнести или вспыхнуть

Единственный способ, которым я мог видеть это, - это поместить волшебное число в оперативную память, чтобы указать, что последняя загрузка была в том, чтобы отнести и надеяться, что эскиз никогда не поместит такое же магическое число в то же место в ОЗУ. я.e Это можно было бы заработать на 99.999% случаев, но я не мог заставить его работать в 100% случаев, потому что у меня не было возможности гарантировать, что набросок будет положить в оперативную память (в месте магического номера)

Zoomx
Пн 18 мая 2015 г., 16:18
Может быть.

victor_pv
Пн 18 мая 2015 г., 19:34
Роджер, последний коммит в моем репозиторе Bootloader, уже включил изменение. Работает так:

-IDE, составленная с помощью сценария линкера RAM (поэтому использует адреса ОЗУ), но загружается в ID2 (так что нормальная загрузка на Flash на 8002000).
Загрузчик загружает код, как и любой другой ID2, чтобы Flash.
Но когда загрузчик перезагружается и должен проверить, что в Flash и RAM для запуска, проверки так:
1.-Первая проверка, есть ли действительный адрес SP в 20000C00. Это указывало бы на загрузку в ОЗУ, например, оригинальный загрузчик, используемый для. Если действительный SP, то запускается из RAM.
2.-Следующая проверка, если 8002004 (которая является векторным положением сброса для эскиза, загруженного до 8002000), и если сброс вектор указывает на адрес, который соответствует 2000xxxx, это означает, что это вектор сброса к адресу оперативной памяти, а не для вспышки. В этом случае он копирует 64 КБ вспышки, начиная с 8002000 до оперативной памяти, начиная с 20000C00, и следующие ботинки оттуда, как на шаге 1 выше, когда загрузка была прямой для ОЗУ.
3-next он проверяет, есть ли действительный SP в 8002000 (как у вас, делайте с ID2), и если это так, загрузитесь на этот адрес в этом адресе.
4-финально проверяет действительный SP в 8008000, как старый ID1, и, если допустимые прыжки туда.

Если вы перезагрузите доску, шаг 1 найдет код в ОЗУ и работает напрямую, необходимо скопировать из Flash в RAM, если вы полностью выключите.

Итак, шаг 2 выше - новая добавленная функция. Я запускаю эскиз с некоторыми вычислениями и работает быстрее, но я думаю, что в основном это зависит от того, сколько прыгает по коду. Флэш достаточно быстра в последовательности с предварительным предварительным, но, как мы видели с PIN_MAP, она может быть медленной для других вещей.

Я не знаю, нужен ли этот вариант вообще. Я только что сделал для удовольствия от этого. Это воодушевлено мне по дороге домой на днях, и сделал это, и работает нормально. Мне потребовалось полчаса, чтобы кодировать и проверить это.
Дополнительный к академическому шагу 2 выше добавляет около 200 байтов в код загрузчика.

Это полностью функционально. Вся идея может пригодиться для обновления загрузчика или эскиза от себя. Сначала скопируйте раздел «Обновление» на известный адрес ОЗУ, затем выполните оттуда, и после запуска в ОЗУ он может переписать всю вспышку.
Я не вижу никакого немедленного использования прямо сейчас, так как я сказал, что это было в основном, чтобы проверить, смогу ли я это сделать.

Rogerclark
Пн 18 мая 2015 г., 20:36
Спасибо, Виктор

Я согласен, интересно узнать, что это возможно.

Пока у нас нет ложных срабатываний E.G Bootloader думает, что в RAM есть программа, когда нет, я не вижу никакого вреда в сохранении ее.

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

Мне это звучит стабильно, если мы можем гарантировать, что не может быть ложных срабатываний.

Я думаю, что с загрузчиком в том, что он должен быть намного более стабильным, чем ядро.
Потому что это скорее боль для перепрошивки загрузчика, чем просто перекомпилировать ядро ​​и загрузка (с помощью загрузчика)
Вот почему я бросил загрузку прямо в ОЗУ.

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

victor_pv
Пн 18 мая 2015 г., 22:06
Роджер, я не думаю, что это может быть ложным положительным в любом рабочем коде, разработанном без значительного изменения сценария линкера.
В любом коде, связанном с Flash, вектор сброса должен быть в адрес 800xxxx. Если вектор сброса, хранящийся при 8002000, соответствует шаблону для 200xxxxxx, он не может соответствовать шаблону для 800xxxx одновременно.

Что касается другой проверки, то тот, который проверяет действительный адрес SP на адресу 2000C00, я проверил опцию «Загрузка» для проверки опции RAM для SP, который соответствует не менее 3 или 4 нулей в конце. Которые предотвращают какую -либо ложную достоверность в чипах с 20 КБ, но могут позволить ложно положительно в чипе с более чем 20 КБ, если слово в ...C00 содержит указатель на другой адрес в диапазоне ОЗУ выше начального 20 КБ, и этот адрес указателя заканчивается в 3 или 4 нулях.

Чтобы предотвратить это, мы могли бы сделать эту маску линейкой #Define в конфигурации.H Файл. Таким образом, маска соответствует количеству оперативной памяти в MCU. Таким образом, на 20 КБ он проверял бы точки SP на следующее на 20 КБ, но на устройствах с высокой плотностью он мог бы проверить, что SP указывает на адрес сразу после 64 КБ ОЗУ на них.
Я все еще думаю, что шансы на оперативную память в C00, содержащий указатель, который подходит для маски, которую я использую, довольно тонкие.
Я могу проверить код, когда вернусь домой, и сказать вам, сколько бит я использовал.

Rogerclark
Пн 18 мая 2015 г. 11:05
Привет, Виктор,

Можем ли мы ждать обратной связи от Рэя, Матиаса и т. Д., Поскольку я знаю, что у некоторых людей есть сильные взгляды на загрузку RAM безопасной или хорошей идеей

Мадиас
Вторник 19 мая 2015 г. 8:18 утра
Хорошо, назовите меня не творческим, но я много думал, какую пользу мы получаем из этой функции. Таким образом, «автоматическое обновление», загрузчик - единственный сценарий или мы можем получить некоторое улучшение скорости в целом?
Но в любом случае интересная вещь!

Rogerclark
Вторник 19 мая 2015 г. 10:11
Привет, Матиас,

Я даже не уверен, что оперативная память помогает обновлять загрузчик
Мы уже можем обновить загрузчик через эскиз (Виктор уже сделал это), поэтому я не совсем уверен, как материал RAM больше помогает в этом.

Но я думаю, это искусство возможного.

Что меня беспокоит. По какой -то причине со старым кленовым загрузчиком я, казалось, получил ложные срабатывания на моем Maple Rev 3.

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

victor_pv
Вторник 19 мая 2015 г. 14:23
Роджер, опция загрузка на RAM давала ложные возможности из -за того, как Leaflabs тестировал на действительный адрес SP.
В основном он проверил, что вектор SP в C00 содержал любой действительный адрес ОЗУ. Это означает, что когда какой -либо эскиз положил любой указатель в этом месте, он даст ложный положительный.
Они использовали это:
if ((sp & 0x2ffe0000) == 0x20000000) {

Это означает, что любой адрес соответствующего адреса с 20000000 по 20010000 дает положительный результат. Это целое 64 КБ максимальной оперативной памяти, доступная в любом чипе серии R или C.
Таким образом, любой указатель, который хранится в C00, дает положительный. Когда мы начинаем использовать целое 20 КБ ОЗУ для эскизов, некоторые указатели оказались в этой области.

Теперь я проверяю это так:
if ((sp & 0xfffe0fff) == 0x20000000)
Это означает, что только адреса, множество 4 КБ, будут соответствовать шаблону (4 КБ, 8 КБ, 12 КБ и т. Д.):
20001000
20002000
20003000
20004000

Для устройства 20 КБ только 4 адреса могут дать ложный положительный положительный, 4, 8, 12 и 16. Настоящий позитив будет 20 кб.

Для устройства 64 КБ есть еще несколько ложных возможностей, всего 15:
20005000 (на 20 КБ это реальное положительное для SP).
20006000
...

Теперь шансы на указатель находится в этом месте (20000C00), и эта стоимость указателя является одним из 3 возможных ложных срабатываний, я считаю, что это чрезвычайно маленькие. Если это когда -либо произойдет, питание и питание очищает ОЗУ.

Но, чтобы предотвратить еще больше ложных срабатываний, так как мы сейчас используем разные цели для файла make, мы можем определить эту маску в конфигурации.H для каждой цели, например

if ((sp == sp_mask) {

Где sp_mask = 0x20005000 для Themaple mini (20 КБ +1, единственный вектор SP, который мы используем в любом из сценариев компилятора)
И для устройств 64 КБ:
Sp_mask = 0x20010000 (байт после 64 КБ).

РЕДАКТИРОВАТЬ: Со всеми вышеупомянуты. Я включил его только обратно в код, который я использовал для тестирования устройств с размером страницы 2 кб, которые имеют по крайней мере 48 или 64 КБ, но при сохранении загрузки оперативной памяти для всех устройств проще, чем для некоторых устройств. Метод выше должен решить проблему с ложными положительными.

Mrburnette
Вторник 19 мая 2015 г. 15:06
РЕДАКТИРОВАТЬ: Со всеми вышеупомянуты. 2 -е это.

Луча