• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Запуск кода из ram

SpLab

New member
Подскажите, может кто-то компилировал код для запуска из RAM (через UART_Loader режим BootROM, функция RAM Download). Нужно поправить что-то в ключах для линкера или нужно что-то править в ld-скрипте?
 

pvvx

Активный участник сообщества
Приложен проект под UDK, выводит в отладочный канал UART:

Hello RAM World!

user code done

По умолчанию, если не меняете в коде, то скорость вывода UART0/1 = скорости загрузки кода в esptool.py.
Код:
20:35:17 **** Build of configuration Default for project HelloRamWorld ****
mingw32-make.exe -f E:/ESP8266/workspace/HelloRamWorld/Makefile loadram
C:/Espressif/utils/esptool -p COM6 -b 230400 load_ram TESTRAM-0x00000.bin
Entering bootloader...
Connecting...
RAM boot...
Downloading 48 bytes at 40100000... done!
Downloading 0 bytes at 3ffe8000... done!
Downloading 28 bytes at 3ffe8000... done!
All segments done, executing at 40100010

20:35:19 Build Finished (took 1s.499ms)
 

Вложения

Последнее редактирование:

SpLab

New member
Приложен проект под UDK, выводит в отладочный канал UART:

Hello RAM World!

user code done

По умолчанию, если не меняете в коде, то скорость вывода UART0/1 = скорости загрузки кода в esptool.py.
Код:
20:35:17 **** Build of configuration Default for project HelloRamWorld ****
mingw32-make.exe -f E:/ESP8266/workspace/HelloRamWorld/Makefile loadram
C:/Espressif/utils/esptool -p COM6 -b 230400 load_ram TESTRAM-0x00000.bin
Entering bootloader...
Connecting...
RAM boot...
Downloading 48 bytes at 40100000... done!
Downloading 0 bytes at 3ffe8000... done!
Downloading 28 bytes at 3ffe8000... done!
All segments done, executing at 40100010

20:35:19 Build Finished (took 1s.499ms)
Спасибо, код работает. Но есть пара вопросов. Просмотрел весь Makefile, существенных отличий в опциях для линкера не обнаружил, практически тоже что и для записи во flash. Собственно вопрос: где же все-таки магия заставляющая линкер пихать код в RAM (а *.map говорит что код действительно в RAM)? И второй вопрос, а как избавиться от хедера в начале бинарника? В данном случае смысла от этого хедера нет, хотя 16 байт это ерунда, но все же.
 

Andy Korg

Moderator
Команда форума
...Собственно вопрос: где же все-таки магия заставляющая линкер пихать код в RAM...
На мой взгляд наоборот - есть волшебный атрибут ICACHE_FLASH_ATTR который помещает код во флэш-память, следовательно его отсутствие помещает код в RAM
 

pvvx

Активный участник сообщества
И второй вопрос, а как избавиться от хедера в начале бинарника? В данном случае смысла от этого хедера нет, хотя 16 байт это ерунда, но все же.
Эти 16 байт никуда не идут. Они нужны для загрузчика и их не 16, а на каждый сегмент ещё... Часть сегментов грузится в память RAM проинициализированных констант.
И Flash тоже грузится по началу в RAM, конкретно в IRAM сегмент и запускается, подключает остальную часть flash и много ещё чаго, а уже после заработает кеширование flash и "магия" :)
На мой взгляд наоборот - есть волшебный атрибут ICACHE_FLASH_ATTR который помещает код во флэш-память, следовательно его отсутствие помещает код в RAM
А он отключен в опциях транслятору :) Тем более что пользоваться *.h от SDK там незя, да и flash и QSPI не проинициализированы при данном методе запуска. :p
Flash заработает только после spi_flash_attach(); и других установок.
И bss и heap при старте совсем другие, чем в SDK...
В частности, после spi_flash_attach() надо вызвать init_sflash_start() которая установит скорость, включит кеширование и т.д.
Тогда в debug UART:
call_user_start()
user_init()
mac: 18:fe:34:9f:c0:bf
flash_id = 0x001340c8
Stop

Халявный пример приложил:
 

Вложения

Последнее редактирование:

SpLab

New member
Спасибо. Теперь кажется понял, поправьте если в чем-то не прав.
Оказывается магии то и нет :) На самом деле нет разницы в компиляции и сборке кода для исполнения из flash или из RAM, т.к. в конечном итоге код всегда исполняется из IRAM куда он помещается загрузчиком находящемся в BootROM. И в нашем случае мы подменяем функцию BootROM по загрузке сегментов кода из flash. Мы с помощью esptool.py разбираем прошивку на сегменты (обычно 3 сегмента) и загружаем по указанным там адресам сегменты в IRAM (память инструкций) и DRAM (память данных). Отличие только в том, что при разборке и запуске прошивки из flash BootROM производит инициализацию периферии и всяких служебных структур/функций ETS system, а в нашем случае мы должны сделать это самостоятельно, в том числе инициализировать работу с flash.
 

pvvx

Активный участник сообщества
поправьте если в чем-то не прав.
Всё так. Но инициализировать массу периферии (в том числе и память и прерывания) приходится и при загрузке с flash. Не требуется только начальная инициализация SPI :)
Есть ещё вариант - при работе прошивки, например c web-сервером, можно организовать загрузку кода с данными в пустое место IRAM, как оверлеев. При этом скорость исполнения таких кусков не будет отличаться от скорости кеширования flash и есть свои преимущества в использовании памяти. При оверлейном исполнении задач используется одна и та-же память. У стандартного SDK в IRAM не занято 6 килобайт. Покопавшись это исправляется до 8, не убивая там критичные ко времени исполнения процедуры (они же не кешируются)...
В SDK iram забита стандартными си-шными процедурами из либов типа printf и критичными по времени доступа при исполнения (отрабатывающими по прерываниям). Но там сидят и никчемные куски начальной инициализации...
 
Последнее редактирование:

NutsXXXL

New member
@pvvx
Я все еще не могу впитать - так есть способ грузить в отладочных целях _полноценные_ прошивки прямо в RAM без процедуры флешевания дабы ее не переписывать 500 раз на дню?
все что я прочел и понял на эту тему - возможна загрузка небольших кусков кода с микроскопическим SDK , включая iramsdk
загрузка идет через esptool.py load_ram, причем только одного куска
 

pvvx

Активный участник сообщества
все что я прочел и понял на эту тему - возможна загрузка небольших кусков кода с микроскопическим SDK , включая iramsdk
загрузка идет через esptool.py load_ram, причем только одного куска
Микроскопическим? 64 килобайта кода + 64 килобайта ROM+ 96 кб RAM для дохленького одноядерного MCU– это микроскопический кусок? :)

В web-свалке сейчас уже реализовано и работает загрузка оверлеев, использующая всю Flash и все ресурсы SDK. Там ограничения отлаживаемого, подгружаемого кода в IRAM = 24 килобайта, а для данных – вся HEAP и специальная выделенная область RAM в 1 килобайт под bss и прочие подгружаемые из кода константы для побайтного обращения (32-х битные можно расположить и в IRAM).
 
Последнее редактирование:

NutsXXXL

New member
@pvvx у нас тут похоже недопонимание, попробую без полемики более конкретно по своей задаче :
есть прошивка AT060 которую я хочу допиливать под свои задачи
есть ли способ не шить ее 500 раз по дню во флеш (для проверочно-отладочных целей) , а с компа прямо в RAMы на исполнение ?
 
Последнее редактирование:

pvvx

Активный участник сообщества
@pvvx у нас тут похоже недопонимание, попробую без полемики более конкретно по своей задаче :
есть прошивка AT060 которую я хочу допиливать под свои задачи
есть ли способ не шить ее 500 раз по дню во флеш (для проверочно-отладочных целей) , а с компа прямо в RAMы на исполнение ?
Дописываему часть - можно, но надо менять код - делать какую-то линковку...
 
Сверху Снизу