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

Вопрос Спецификация на встроенный загрузчик

Всем доброго времени суток!
Меня интересуют несколько вопросов по поводу встроенного загрузчика в ESP8266.

1. Есть ли полное официальное описание протокола кроме «ESP8266 SDK Application Note Firmware Download Protocol v1.0»?
2. Из какого источника использовалась информация в данной статье: https://esp8266.ru/esp8266-image-firmware-protocol/
3. Можно ли обновлять встроенный загрузчик или он прошит наглухо?
4. Есть ли описание кодов ошибок загрузчика и его режимов работы (ets Jan 8 2013, rst cause: 4, boot mode: (3,0))?

Если есть любая информация по поводу встроенного загрузчика, буду очень признателен.
Заранее большое спасибо!
 

pvvx

Активный участник сообщества
https://esp8266.ru/forum/threads/es...ena-flesh-kak-proverit.1558/page-2#post-22718
+ pin_reg.xlsx strapping esp8266web/pin_reg.xlsx at master · pvvx/esp8266web · GitHub
+ недавнее https://esp8266.ru/forum/threads/i2c-neponjatki.2581/#post-38045
Заливка кода через UART реализована на Питоне в esptool.py и наглядна.
Там ещё есть работа с SDIO, но по ней информации совсем мало...
Всё остальное раскидано по форуму. Часть, из дизасм-а ROM-BIOS, я уже забыл, как и ссылки на раскиданные куски описаний по этому делу, т.к. чип уже устарел.
Других копошившихся в данном деле и пытавшихся более глубже разобраться за более 2 года не встречал.
Найдете - пишите...
 
pvvx, большое вам спасибо за помощь! Пересмотрю материал и постараюсь сложить целую картину загрузчика (на сколько это возможно:)).

P.S. Бегло анализируя протокол "esptool v1.2" оказалось, что утилита загружает в RAM модуля свою прошивку. Потом через неё работает с модулем и его флеш-памятью по своему внутреннему протоколу инкапсулированному в SLIP протокол.
 
pvvx, большое вам спасибо за помощь! Пересмотрю материал и постараюсь сложить целую картину загрузчика (на сколько это возможно:)).

P.S. Бегло анализируя протокол "esptool v1.2" оказалось, что утилита загружает в RAM модуля свою прошивку. Потом через неё работает с модулем и его флеш-памятью по своему внутреннему протоколу инкапсулированному в SLIP протокол.
как успехи? у меня сейчас стоит такая же задача - через прозрачный уарт пик контроллера подключённого к usb прошить esp8266. водникла шальная мысль генерить файл прошивки в SLIP протоколе и уже его передавать по уарту.
 
как успехи? у меня сейчас стоит такая же задача - через прозрачный уарт пик контроллера подключённого к usb прошить esp8266. водникла шальная мысль генерить файл прошивки в SLIP протоколе и уже его передавать по уарту.
Здравствуйте! Успехи практически удовлетворительные. Единственное, на что так и не нашёл точной информации – это коды ошибок. Пришлось проводить эксперименты над загрузчиком и ориентироваться на результат его работы. Информацию про встроенный загрузчик насобирал, но так и не успел её систематизировать... P.S. Позже обязательно этим займусь :)

Что касается вашей задачи, то решение вполне неплохое. Обмениваясь заранее сформированными пакетами через UART, можно сэкономить много ресурсов для МК.

Можно воспользоваться несколькими вариантами:
1. Доработать готовую утилиту(к примеру nodemcu-flasher) для прошивки модулей под ваши нужны;
2. Встроить алгоритм для работы с загрузчиком в ваш софт.

Хорошее описание протокола загрузчика можно найти тут:
https://esp8266.ru/esp8266-image-firmware-protocol/
Serial Protocol · espressif/esptool Wiki · GitHub

Если интересуют алгоритмы работы, то пишите, сброшу.
 
Здравствуйте! Успехи практически удовлетворительные. Единственное, на что так и не нашёл точной информации – это коды ошибок. Пришлось проводить эксперименты над загрузчиком и ориентироваться на результат его работы. Информацию про встроенный загрузчик насобирал, но так и не успел её систематизировать... P.S. Позже обязательно этим займусь :)

Что касается вашей задачи, то решение вполне неплохое. Обмениваясь заранее сформированными пакетами через UART, можно сэкономить много ресурсов для МК.

Можно воспользоваться несколькими вариантами:
1. Доработать готовую утилиту(к примеру nodemcu-flasher) для прошивки модулей под ваши нужны;
2. Встроить алгоритм для работы с загрузчиком в ваш софт.

Хорошее описание протокола загрузчика можно найти тут:
https://esp8266.ru/esp8266-image-firmware-protocol/
Serial Protocol · espressif/esptool Wiki · GitHub

Если интересуют алгоритмы работы, то пишите, сброшу.
Благодарю!
Собсвенно у меня стоит слегка другая задача: есть PIC контроллер который по UART соединён с ESP8266 и при этом управляет всеми его вывдоами (рст, чип_ен, гпио0 и т.д.). В тех задании прописано что пик_контролер должен уметь прошивать еспешку по уарту и при этом от пик контроллера требуется только (программисты его поленились) взять бинарный файл и странслировать его в уарт. и всё. поскольку .bin файлы которые генерирует esptool.py совсем не то что транслируется по уарту в загрузчик то по совету pvvx Прошивка через терминал без программ прошивальщиков я решил или поискать готовый конвертер их 4х файлов прошивки для ESP (0x00000 0x10000 esp_init_data_default.bin и blank.bin) в один готовый для трансляции по уарту.
В программе FLASH_DOWNLOAD_TOOLS_V3.4.2_Win нашёл кнопочку CombineBin. вроде бы оно, то что нужно по посылка итогового файла по уарту ничего не дала.
Может есть где готовая программа конвертер или esptool.py может это сделать?
 
Благодарю!
Собсвенно у меня стоит слегка другая задача: есть PIC контроллер который по UART соединён с ESP8266 и при этом управляет всеми его вывдоами (рст, чип_ен, гпио0 и т.д.). В тех задании прописано что пик_контролер должен уметь прошивать еспешку по уарту и при этом от пик контроллера требуется только (программисты его поленились) взять бинарный файл и странслировать его в уарт. и всё. поскольку .bin файлы которые генерирует esptool.py совсем не то что транслируется по уарту в загрузчик то по совету pvvx Прошивка через терминал без программ прошивальщиков я решил или поискать готовый конвертер их 4х файлов прошивки для ESP (0x00000 0x10000 esp_init_data_default.bin и blank.bin) в один готовый для трансляции по уарту.
В программе FLASH_DOWNLOAD_TOOLS_V3.4.2_Win нашёл кнопочку CombineBin. вроде бы оно, то что нужно по посылка итогового файла по уарту ничего не дала.
Может есть где готовая программа конвертер или esptool.py может это сделать?
Здравствуйте!
Напрямую прошить файл будет очень проблематично и такой вариант (с большой вероятностью) будет нестабильно работать.

Вся суть прямой передачи сводится к следующему:
1. Взять несколько файлов прошивки (*.bin) и собрать из них один файл (можно попробовать через утилиту esptool.py). Нужно не забывать, что файлы пишутся по разным адресам. Или взять один готовый файл. В результате будем иметь один файл с чистой прошивкой для ESP модуля.
2. Что бы прошить данный файл необходимо выполнить некоторые манипуляции с самим модулем.
2.1 Перевести модуль в режим загрузчика.
2.2. Начать периодическую отправку специального синхронизирующего фрейма (данные фрейма не относятся к прошивке) и дожидаться подтверждения синхронизации. В большинстве случаев ответ приходит на вторую посылку фрейма.
2.3. После синхронизации необходимо выполнить настройку и предварительное стирание записываемых страниц.
3. Теперь можно посылать файл прошивки, инкапсулированный в SLIP протокол + не забывать добавлять заголовки к каждому фрейму.
4. После записи файла нужно отправить фрейм с командой запуска модуля (по желанию).

Исходя из выше написанного, что бы прошить файл напрямую, нужно взять бинарный файл и добавить к нему как минимум 2 синхронизирующих фрейма + разбить прошивку на пакеты с заголовками + всё обрамить в SLIP протокол. При таком раскладе сразу теряется надёжность + контроль за процессом прошивки, не говоря уже про подводные камни которые будут попадаться.

Для вашей ситуации предлагаю простой вариант. Взять готовую утилиту nodemcu-flasher (написана на Delphi, в интернете есть исходники, умеет прошивать несколько файлов) и дописать её для ваших нужд. Вам нужно будет добавить команды для управления вашим микроконтроллером (перевод модуля в режим загрузчика и т.д.) и отправку данных через ваш интерфейс. Проще говоря, предлагаю через ваш интерфейс связи ПК с ПИК передавать данные + команды, которые сформирует программа. Тогда не стоит беспокоиться о склейке файлов и их формированию. За вас всё сделает программа + будет контроль над процессом прошивки.
 
Здравствуйте!
Напрямую прошить файл будет очень проблематично и такой вариант (с большой вероятностью) будет нестабильно работать.
ясно. понятно. благодарю за развёрнтый ответ!
вопрос 1) esptool.py выдаёт combined_image.bin - это 4 файла (0x00000.bin 0x10000.bin esp_init_data_default.bin blanc.bin) которые собраны в один и с уже заданной адресацией для памяти? если так, то задача упрощается до простой передачи файла по алгоритму описанному в документации https://esp8266.ru/forum/redirect/?to=aHR0cDovL2VzcHJlc3NpZi5jb20vc2l0ZXMvZGVmYXVsdC9maWxlcy9lc3A4MjY2LXNka19hcHBsaWNhdGlvbl9ub3RlX2Zpcm13YXJlX2Rvd25sb2FkX3Byb3RvY29sX2VuLnBkZg==
у меня немного нетривиальная задача: программа есть. в C# и пик контроллер подключен через USB. пик идёт как прозрачный UART между USB и ESP8266. (почему предыдущий разработчик не выбрал тот же ftdi? хз)
 
Последнее редактирование:
мда... перебрал кучу вариантов и сдался. начну писать свою реализацию алгоритма глядя на код в esptool.py
только один вопрос: как должен выглядеть синхронизирующий фрейм(кадр)?
upd:
придётся самому
я поэксперементировал. FLASH_DOWNLOAD_TOOLS_V3.4.2_Win выдаёт скомбинированный файл .bin из 4х сохраняя их адресацию. поробовал разные комбинации - работает.
открыл я esptool.py и ужаснулся. питон.
короч если следовать оф. документации есп еспрессифа то получается последовательность команд:
я даю команду (выдрал из мейкфайла)
esptool.py -p /dev/ttyUSB0 -b 74400 write_flash 0x00000 $(OUTDIR)0x00000.bin 0x10000 $(OUTDIR)0x10000.bin 0xFC000 $(OUTDIR)esp_init_data_default_26mhz.bin 0xFE000 $(OUTDIR)blank.bin
затем открываю сам питон файл
и поехали:
def main()
в нём сразу не отходя от кассы
esp.connect() - тут идёт дёрганье ногами гпио0 и ресетом. тут же идёт синхрокадр
def sync(self):
self.command(ESPROM.ESP_SYNC, '\x07\x07\x12\x20' + 32 * '\x55')
for i in xrange(7):
self.command()

и тут я могу схитрить - записать в файл то как выглядит синхрокадр.

и....
дальше я немного потерялся в логике питона.
но деваться некуда. надо копать.
 
Последнее редактирование:
1) esptool.py выдаёт combined_image.bin - это 4 файла (0x00000.bin 0x10000.bin esp_init_data_default.bin blanc.bin) которые собраны в один и с уже заданной адресацией для памяти?
Адреса файлов прописываются в командной строке при запуске утилиты esptool.py. Если данный файл появился после запуска, то в нём должны быть собраны все 4 файла.

как должен выглядеть синхронизирующий фрейм(кадр)?
Синхронизирующий фрейм представляет собой заголовок (по протоколу) + определённая последовательность байт. Фрейм выглядит так:

Код:
#define ESP_HANDSHAKE_FRAME   "\xC0\x00\x08\x24\x00\x00\x00\x00\x00\x07\x07\x12\x20\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\xC0"
После успешной синхронизации скорости, модуль ответит подтверждением (по протоколу).

P.S. Если вы хотите написать свою реализацию программы для прошивки, то пишите сразу отталкиваясь от протокола загрузчика. Утилита esptool.py работает по своему алгоритму. Если коротко, то она синхронизируется с модулем, заливает ему в ОЗУ свой прообраз загрузчика, запускает его и потом уже через него работает по своему протоколу.
 
Андрей180,
Адреса файлов прописываются в командной строке при запуске утилиты esptool.py. Если данный файл появился после запуска, то в нём должны быть собраны все 4 файла.
поэксперементировал с разными файлами и разным содержимым. все фалы делал combined и загружал с адреса 0х00000 - прекрасно работало. загружал через esptool.py
насчёт своего прообраза загрузчика - у меня версия есптул.пу 1.2 (__version__ = "1.2") и разбирая её не могу найти загрузку доп.загрузчика.
Если вы хотите написать свою реализацию программы для прошивки, то пишите сразу отталкиваясь от протокола загрузчика.
именно этим и занимаюсь. есть ли готовый код на Си? я его как dll подключу к C# приложению.
 
  • #define ESP_HANDSHAKE_FRAME "\xC0\x00\x08\x24\x00\x00\x00\x00\x00\x07\x07\x12\x20\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\x55\xC0"
попробовал отправить эту строку. получилось! немного укоротил её до состояния (отправлял макросом для Terminala от Br@y)
Код:
$07$07$12$20$55$55$55$55$55$55$55$55$55$55$55$55$55$55$55$55$55$55$55$55$55$55$55$55$55$55$55$55$55$55$55$55$C00
получил ответ
Код:
C0 01 00 02 00 00 00 00 00 01 05 C0
ну в принципе понятно что делать дальше
отправитькоманду на стирание флеша и записать свои данные из файла combined.bin
и шоколад. надеюсь.
 
@Андрей180,

всем снова привет!
была пауза на неделю - осваивал c# и usb. теперь полностью готов шлюз программа c# <-> pic 18f24k50 <-> esp8266.
теперь я начал очень подробно ковырять собственно единственно что может быть открытым по загузчику - esptool.py
для того чтобы понимать что вообще куда идёт я дописал несколько строк в питон скрипт
Код:
   """ Read a SLIP packet from the serial port """
    def read(self):
        a = self._slip_reader.next()
        #print(self._slip_reader.next())
        print("\r\nvvvvvvvvvvvvvvvvvvvv ")
        print(" ".join("0x{:02x}".format(ord(c)) for c in a))
        print(" vvvvvvvvvvvvvvvvv\r\n")
        return a

    """ Write bytes to the serial port while performing SLIP escaping """
    def write(self, packet):
        buf = '\xc0' \
              + (packet.replace('\xdb','\xdb\xdd').replace('\xc0','\xdb\xdc')) \
              + '\xc0'
        self._port.write(buf)
        #Sam Arcanum
        print("\r\n^^^^^^^^^^^^^^^^^^^ ")
        print(" ".join("0x{:02x}".format(ord(c)) for c in buf))
        print(" ^^^^^^^^^^^^^^^^^^^\r\n")
и в результате в консоль я получил дамп байт (см. файл)
у меня множество вопросов -
1) увидел синхрокадр - и отправил его и получил ответ на него и из программы терминала от br@y и из своей программы на с#. пока что это весь успех.
2) в файле есть массив байт (строка 116 ) который идёт от есптул.пу к самой есп - это переписывается загрузчик?

где можно ознакомиться с более полным списком команд кроме той тех.доки на четырнадцать страниц по загрузчике прошивки?
upd: про формат slip понял всё кроме одного момента:

Код:
• All occurrences of 0xC0 and 0xDB inside the packet are replaced with 0xDB 0xDC
and 0xDB 0xDD, respectively.
что это значит? надо менять все эти комбинации на данные? или что?
 

Вложения

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

pvvx

Активный участник сообщества
где можно ознакомиться с более полным списком команд кроме той тех.доки на четырнадцать страниц по загрузчике прошивки?
В IDA и дампе ROM-BIOS.
Собственно esptool.py примерно так и был создан. Отличие только в названии disasm программы и операционной системе :)
 
В IDA и дампе ROM-BIOS.
Собственно esptool.py примерно так и был создан. Отличие только в названии disasm программы и операционной системе :)
мда... люто.
то есть варинт только один - просто записать последовательность команд, отправить их есп и ожидать строгой последовательности. а затем отправить сам файл прошивки. так?
 

pvvx

Активный участник сообщества
мда... люто.
то есть варинт только один - просто записать последовательность команд, отправить их есп и ожидать строгой последовательности. а затем отправить сам файл прошивки. так?
Основной протокол же уже описан (SLIP). Команды даны не все, и не все работают (часть имеют ошибки в реализации кода в ROM).
Вы не заявили свою конечную цель, а гадать что вас интересует и уже есть - сложно
 
(часть имеют ошибки в реализации кода в ROM).
как лечить?

я так понимаю что длинная борода байт на 116 строке - это новый загрузчик. и он переписывается всегда при загрузке новой прошивки. так?
тогда тогда полуачется - просто записать все эти массивы отправляемых загрузчиком команд - прям как есть. и отправить их. ждать строго определённого ответа (у меня на проекте везде одни и те же кварцы и микросхемы памяти). а передача файла прошивки - уже инкапсулировать в slip.
конечно не панацея - всё жёстко но надо помнить что загрузчик будет выполнен на микроконтроллере и места там много. си шарп - отладочное средство разработчика.
 

pvvx

Активный участник сообщества
Вы не заявили свою конечную цель, а гадать что вас интересует и уже есть - сложно
прошу прощения.
конечная цель - научиться прошивать есп8266. одним комбинированным файлом. файл будет передаваться на устройство и есп, при необходимости, будет прошиваться главным контроллером целевого устройства.
что есть - написано выше (есть усб, пик 18ф24к50 и сама есп с кристаллом на 24мгц 8 мб памяти). пик - шлюз усб<->уарт. прога для пиа - на си шарпе. сейчас есть стабильниый шлюз. всё. осталось только прошить файлом.
 

pvvx

Активный участник сообщества
Т.к. по UART есть базовая команда загрузки кода и запуска его исполнения, то более правильное решение, для многих случаев, является создание кода загрузчика обеспечивающего какой стандартный протокол. Например xmodem/zmodem. Такое решение позволяет осуществить прошивку в любом терминале.

Ошибку имеет функция стирания блока секторов. Стирает не то, захватив дополнительные сектора...
 
Сверху Снизу