Программирование ARM ESP32 esptool Mon, June 24 2024  

Поделиться

Нашли опечатку?

Пожалуйста, сообщите об этом - просто выделите ошибочное слово или фразу и нажмите Shift Enter.

ESP32 esptool Печать
Добавил(а) microsin   

esptool.py это утилита на языке Python, предназначенная для взаимодействия с ПЗУ-загрузчиком (ROM bootloader) чипов Espressif SoC (ESP32, ESP32-C3 и т. п.).

Утилиты esptool.py, espefuse.py и espsecure.py составляют полный набор инструментария для работы с чипами от Espressif. Они позволяют выполнять следующие операции:

• Читать, записывать, стирать и проверять двоичные данные, сохраненные в памяти flash.
• Прочитать функциональную информацию чипа и другие связанные с ним данные, такие как MAC-адрес или идентификатор чипа (flash chip ID).
• Прочитать и записатьRead однократно программируемые конфигурационные данные (one-time-programmable efuse, OTP).
• Подготовить для прошивки двоичные исполняемые образы.
• Анализировать, собирать и выполнять слияние двоичных образов.

Здесь описывается работа с esptool.py для чипа ESP32. Для дополнительной информации по использованию esptool.py, относящейся к конкретному типу, перейдите по ссылке [1] и в выпадающем списке в левом верхнем углу выберите интересующий тип SoC. Решение общих проблем, связанных с работой утилиты esptool, см. в статье [13].

select SoC type

[Установка]

1. Для установки выполните команду esptool.py:

$ pip install esptool

2. Подсоедините чип Espressif к компьютеру - либо напрямую, либо через переходник USB-UART (в зависимости от типа микроконтроллера. Например, для ESP32-C3 см. [2]).

После этого утилита esptool.py готова к использованию. Например, для того, чтобы прочитать информацию об SPI flash:

$ esptool.py -p PORT flash_id

Здесь PORT нужно заменить на имя используемого последовательного порта. Для Linux это может быть имя наподобие /dev/ttyUSB0, а для Windows имя порта может быть типа COM2 и т. п. Если не указывать -p PORT, то утилита сама попытается выбрать первый подходящий порт.

Замечание: esptool.py это программа (скрипт) на языке Python. Если ваша система не распознает расширение *.py для автоматического запуска интерпретатора Python, либо если по какой-то причине у скрипта не установлен атрибут, разрешающий выполнение, то запускайте esptool.py с помощью прямого вызова интерпретатора Python:

> python.exe esptool.py -p COM4 flash_id

Или:

> python3 ./esptool.py -p COM4 flash_id

Быструю подсказку по командной строке можно получить, если указать опцию -h.

usage: esptool [-h]
               [--chip {auto,esp8266,esp32,esp32s2,esp32s3beta2,esp32s3,esp32c3,
                        esp32c6beta,esp32h2beta1,esp32h2beta2,esp32c2}]
               [--port PORT] [--baud BAUD]
               [--before {default_reset,usb_reset,no_reset,no_reset_no_sync}]
               [--after {hard_reset,soft_reset,no_reset,no_reset_stub}]
               [--no-stub] [--trace] [--override-vddsdio [{1.8V,1.9V,OFF}]]
               [--connect-attempts CONNECT_ATTEMPTS]
               {load_ram,dump_mem,read_mem,write_mem,write_flash,run,image_info,make_image,
                elf2image,read_mac,chip_id,flash_id,read_flash_status,write_flash_status,
                read_flash,verify_flash,erase_flash,erase_region,merge_bin,get_security_info,
                version}
               ...
 
esptool.py v3.3-dev - Espressif chips ROM Bootloader Utility
 
Позиционные аргументы (команды):
{load_ram,dump_mem,read_mem,write_mem,write_flash,run,image_info,make_image,elf2image,read_mac,
 chip_id,flash_id,read_flash_status,write_flash_status,read_flash,verify_flash,erase_flash,
 erase_region,merge_bin,get_security_info,version}
                        Запустите esptool {команда} -h для дополнительной подсказки
Команды:
    load_ram            Загрузить образ в RAM и запустить
    dump_mem            Дамп произвольной области памяти на диск
    read_mem            Чтение произвольной области памяти
    write_mem           Read-modify-write произвольной области памяти
    write_flash         Запуск двоичного файла (binary blob) в flash
    run                 Запуск кода приложения, находящегося в flash
    image_info          Дамп заголовков из образа приложения
    make_image          Создание образа приложения из двоичных файлов
    elf2image           Создание образа приложения из ELF-файла
    read_mac            Прочитать MAC-адрес из OTP ROM
    chip_id             Прочитать идентификатор чипа (Chip) ID из OTP ROM
    flash_id            Прочитать идентификатор производителя SPI flash и её device ID
    read_flash_status   Прочитать регистр состояния SPI flash
    write_flash_status  Запись регистра состояния SPI flash
    read_flash          Чтение содержимого SPI flash
    verify_flash        Проверка соответствия бинарника (binary blob) и flash
    erase_flash         Выполнение стирания чипа SPI flash
    erase_region        Стирание области памяти flash
    merge_bin           Склейка нескольких сырых двоичных файлы в один для последующей прошивки
    get_security_info   Получение некоторых данных, относящихся к безопасности
    version             Напечатать версию esptool
 
Опциональные аргументы:
  -h, --help            Показать этот текст подсказки и выйти
  --chip {auto,esp8266,esp32,esp32s2,esp32s3beta2,esp32s3,esp32c3,esp32c6beta,esp32h2beta1,
          esp32h2beta2,esp32c2}, -c {auto,esp8266,esp32,esp32s2,esp32s3beta2,esp32s3,esp32c3,
          esp32c6beta,esp32h2beta1,esp32h2beta2,esp32c2}
                        Тип целевого чипа
  --port PORT, -p PORT  Устройство последовательного порта
  --baud BAUD, -b BAUD  Скорость последовательного порта
  --before {default_reset,usb_reset,no_reset,no_reset_no_sync}
                        Что делать перед подключением к чипу
  --after {hard_reset,soft_reset,no_reset,no_reset_stub},
   -a {hard_reset,soft_reset,no_reset,no_reset_stub}
                        Что делать после завершения работы esptool.py
  --no-stub             Запрет запуска flasher stub, работать только с ROM bootloader.
                        Некоторые функции будут недоступны [3].
  --trace, -t           Разрешить вывод отладочной трассировки протокола взаимодействия
                        esptool.py и чипа.
  --override-vddsdio [{1.8V,1.9V,OFF}]
                        Отменить внутренний регулятор напряжения ESP32 VDDSDIO (используйте
                        с осторожностью)
  --connect-attempts CONNECT_ATTEMPTS
                        Количество попыток для соединения. Отрицательное значение или 0
                        для бесконечных попыток. По умолчанию используется 7.

[Базовые команды esptool.py]

write_flash. Команда запишет двоичные данные ESP-чипа flash, например:

esptool.py --port COM4 write_flash 0x1000 my_app-0x01000.bin

В одной командной строке можно указать несколько адресов flash и имен файлов.

Практический пример, записывающий загрузчик (bootloader.bin), образ приложения (my_app-0x01000.bin), таблицу разделов (partition-table.bin) и начальные данные OTA (ota_data_initial.bin). Обратите внимание, что имя порта подключения не указано (утилита esptool.py сама попытается выбрать подходящий), но указана скорость обмена (-b 460800) и параметры SPI (--flash_mode dio --flash_freq 20m --flash_size 4MB) и указаны другие опции, определяющие поведение утилиты и загрузчика (--before=default_reset --after=hard_reset):

python esptool.py -b 460800 --before=default_reset --after=hard_reset write_flash --flash_mode dio
 --flash_freq 20m --flash_size 4MB 0x0 bootloader.bin 0x10000 my_app-0x01000.bin 0x8000 partition-table.bin
 0xd000 ota_data_initial.bin

Аргумент --chip указывать необязательно, когда записывается flash, esptool определит тип чипа, когда подключится через последовательный порт. Адреса могут быть указаны в HEX-формате (с префиксом 0x) или в десятичном формате (например, вместо 0x1000 можно указать 4096).

Установка режима и размера flash. Могут понадобиться специальные аргументы для режима памяти flash и её размера, если вы хотите поменять значения по умолчанию. Например:

esptool.py --port /dev/ttyUSB0 write_flash --flash_mode qio --flash_size 32m 0x0 bootloader.bin 0x1000 my_app.bin

Начиная с esptool версии v2.0 эти опции часто не нужны, поскольку по умолчанию используются режим и размер, сохраненные в файле образа (.bin). Подробнее про режимы flash см. [4].

Компрессия. По умолчанию последовательные данные передаются в сжатом виде, чтобы повысить производительность. Опция -u/--no-compress запрещает это поведение.

Стирание перед записью. Чтобы данные были успешно записаны в память flash, должны быть стерты все соответствующие сектора по 4096 байт (самая маленькая независимо стираемая область памяти). Как следствие, когда смещение записываемых данных не выровнено на адрес, нацело делящийся на 4096, потребуется стереть дополнительные блоки памяти. Esptool будет показывать информацию о том, какие будут стерты сектора памяти flash.

Используйте опцию -e/--erase-all, чтобы стереть перед программированием все сектора flash (не только те, которые подвергаются записи).

Защита загрузчика. Прошивка в регион загрузчика (0x0 .. 0x7FFF) по умолчанию запрещена, если было определено, что активирована функция Secure Boot [5]. Это мера безопасности для предотвращения случайной перезаписи защищенного загрузчика, что в конечном итоге может привести к "окирпичиванию" устройства.

Это поведение может быть отменено опцией --force. Используйте это только на свой страх и риск, и только если понимаете, что делаете!

Защита шифрованием flash. Перезапись зашифрованного firmware (bootloader, приложение, и т. д.) запрещена без указания опции --encrypt, если разрешена фича Flash Encryption [6], и запрещена функция Encrypted Download (установлен efuse-бит EFUSE_DISABLE_DL_ENCRYPT).

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

Это поведение можно отменить опцией --force. Используйте эту опцию при условии, что flash-ключ шифрования генерируется вне устройства, и можно выполнить шифрование на машине хоста.

Прошивка несовместимого образа. Утилита esptool.py перед прошивкой проверит каждый бинарник. Если было определено, что образ firmware допустимый, то в его заголовке проверяются поля идентификатора чипа (Chip) ID и минимальной ревизии чипа (Minimum chip revision) на соответствие значениям реально подключенного чипа. Если образ оказался несовместимым с чипом, или требует более новую ревизию чипа, то прошивка не производится.

Это поведение можно отменить опцией --force.

read_flash. Команда read_flash позволяет считать обратно содержимое flash. В этой команде аргументами указывается адрес, размер и имя файла для дампа. Например, чтобы полностью прочитать 2 мегабайта подключенной flash:

esptool.py -p PORT -b 460800 read_flash 0 0x200000 flash_contents.bin

Также можно автоматически определить размер flash, указав вместо размера ALL. Предыдущий пример с автодетектом размера:

esptool.py -p PORT -b 460800 read_flash 0 ALL flash_contents.bin

Замечание: если команда write_flash обновила режим (flash mode) образа загрузки (boot image), и во время прошивки указан размер flash, то прочитанные байты могут отличаться от записанных.

erase_flash и erase_region. Для полного стирания flash выполните команду (вся память чипа будет заполнена байтами 0xFF):

esptool.py erase_flash

Чтобы стереть область flash, начиная с адреса 0x20000, длиной 0x4000 байт (16 килобайт):

esptool.py erase_region 0x20000 0x4000

Адрес и длина области должны нацело делиться на размер сектора SPI flash. Этот размер сектора составляет 0x1000 (4096) байт для поддерживаемых чипов flash.

Защита flash. По умолчанию стирание чипа flash запрещено, если активна либо фича Secure Boot [5], либо Flash Encryption [6]. Эта мера безопасности предназначена для того, чтобы случайно не удалить защищенный загрузчик, что может полностью превратить устройство в "кирпич".

Это поведение можно отменить опцией --force. Используйте только на свой страх и риск, и только если понимаете, что делаете!

read_mac. Эта команда позволяет прочитать встроенный MAC-адрес чипа. Пример вывода:

$ python3 ./esptool.py flash_id
esptool.py v3.3-dev
Found 1 serial ports
Serial port /dev/ttyUSB0
Connecting....
Detecting chip type... ESP32-C3
Chip is ESP32-C3 (revision 3)
Features: Wi-Fi
Crystal is 40MHz
MAC: a0:76:4e:14:5a:3c
Uploading stub...
Running stub...
Stub running...
Manufacturer: 20
Device: 4016
Detected flash size: 4MB
Hard resetting via RTS pin...

Информацию об именах производителей чипов и типах чипов см. в заголовочном файле flashchips.h [7].

elf2image. Команда elf2image преобразует ELF-файл (результат работы компилятора и линкера) в двоичный исполняемый образ, который можно прошить в flash, и откуда может быть загружено и запущено приложение:

esptool.py --chip ESP32 elf2image my_app.elf

Для этой команды не требуется соединение с чипом.

Команда elf2image также принимает аргументы режима --flash_freq и --flash_mode, который могут использоваться для установки значений по умолчанию в заголовке образа. Это важно, когда генерируется образ, который будет запускаться напрямую загрузчиком чипа. Эти значения можно также переопределить командой write_flash (см. описание выше). Однако если вы хотите перезаписать эти значения командой write_flash, то используйте аргумент --dont-append-digest команды elf2image, чтобы пропустить добавление цифровой подписи SHA256 после образа. Цифровая подпись SHA256 станет недостоверной после перезаписи заголовка образа, что недопустимо.

По умолчанию elf2image использует секции в ELF-файле, чтобы сгенерировать каждый сегмент в двоичном исполняемом коде (binary executable). Чтобы вместо этого использовать сегменты (PHDR), передайте опцию --use_segments.

Для ESP32 команда elf2image создаст один двоичный файл образа исполняемого кода, "image file". По умолчанию у него будет то же самое имя, что и у входного ELF-файла, просто расширение файла .elf поменяется на .bin:

esptool.py --chip ESP32 elf2image my_esp_app.elf

В результате выполнения этой команды получится файл образа my_esp_app.bin.

image_info. Эта команда выведет некоторую информацию об образе (адрес загрузки, размеры и т. д.) в файле .bin, который был создан командой elf2image.

Чтобы посмотреть больше информации по файлу образа, такую как установленный размер flash, частоту тактов интерфейса SPI и режим подключения, или расширенную информацию заголовка, используйте опцию --version 2. Этот расширенный вывод в плане сделать выводом по умолчанию в будущих релизах утилиты esptool.

esptool.py image_info --version 2 my_esp_app.bin

Эта информация соответствует заголовкам, описанных в документации по формату образа прошивки, см. ниже врезку "Firmware Image Format".

Файлы образа (firmware) генерируются командой esptool.py elf2image. Файлы образа загружаются и запускаются встроенным ROM-загрузчиком SoC-чипа Espressif.

Файл firmware состоит из заголовка (header), расширенного заголовка (extended header), переменного количества сегментов данных и блока окончания (footer). Многобайтные поля хранятся в формате little-endian [10].

Заголовок файла. Заголовок состоит из 8 байт:

Байт Описание
0 Магическое число (всегда 0xE9).
1 Количество сегментов.
2 Режим подключения памяти, SPI Flash Mode (0 = QIO, 1 = QOUT, 2 = DIO, 3 = DOUT).
3 Старшие 4 бита - размер Flash (0 = 1MB, 1 = 2MB, 2 = 4MB, 3 = 8MB, 4 = 16MB). Младшие 4 бита - частота Flash (0 = 40 МГц, 1 = 26 МГц, 2 = 20 МГц, 0xf = 80 МГц).
4 .. 7 Адрес точки входа.

Утилита esptool.py перезапишет 2-й и 3-й байт (начиная с 0 байта), в соответствии с информацией SPI flash, предоставленной опциями командной строки, но только если в конце файла образа не была добавлена цифровая подпись SHA256. Таким образом, если вы намереваетесь поменять параметры SPI flash во время процесса прошивки, например командой esptool.py write_flash, то генерируйте образы без цифровых подписей SHA256. Этого можно достичь запуском команды esptool.py elf2image с аргументом --dont-append-digest.

Расширенный заголовок файла. 16-байтный extended header идет сразу после заголовка образа:

Байт Описание
0 Ножка WP, когда выводы SPI установлены через efuse (считывается кодом ROM bootloader).
1-3 Настройки нагрузочной способности ножек SPI flash (считывается кодом ROM bootloader).
4-5 Chip ID (обозначает устройство ESP, для которого предназначен этот образ).
6 Минимальная ревизия чипа, поддерживаемая образом (устарело, используйте следующее поле).
7-8 Минимальная ревизия чипа, поддерживаемая образом (в формате major * 100 + minor).
9-10 Максимальная ревизия чипа, поддерживаемая образом (в формате major * 100 + minor).
11-14 Зарезервированные байты в дополнительном пространстве заголовка, в настоящее время не используются.
15 Флаг добавления хэша (если 1, то после контрольной суммы добавляется цифровая подпись SHA256).

Сегмент

Байт Описание
0-3 Смещение в памяти.
4-7 Размер сегмента.
8 .. n Данные.

Footer. Файл добавляется нулями до тех пор, пока его размер не станет на 1 байт меньше числа, нацело делящегося на 16. Последний байт (который дополнит размер файла до минимального значения, нацело делящегося на 16) это контрольная сумма данных всех сегментов. Контрольная сумма определена как операция ИСКЛЮЧАЮЩЕЕ ИЛИ (XOR) всех байт и байта 0xEF.

Если опция добавления хэша (байт 15 в расширенном заголовке) установлена в 0x01, то после контрольной суммы добавляется цифровая подпись SHA256 "simple hash" (от всего образа целиком). Эта цифровая подпись является отдельной для secure boot, и используется только для определения повреждения прошивки. Информация SPI flash не может быть изменена во время прошивки, если к образу добавлен хэш.

Если разрешена фича secure boot, то также добавляется соответствующая подпись (и simple hash включены в подписанные данные). Эта сигнатура образа различается для Secure Boot V1 и Secure Boot V2.

Чтобы проанализировать двоичный образ и получить полную информацию о его заголовках и сегментах, используйте команду image_info с опцией --version 2 option.

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

Если указанный двоичный образ образа это загрузчик (bootloader), и в образе был обнаружен правильный заголовок загрузчика ESP-IDF, то будут также показаны специфичные поля, описывающие загрузчик.

merge_bin. Команда merge_bin сольет друг с другом несколько двоичных файлов (любого вида) в один файл, который позже можно будет прошить в память flash устройства. Любые промежутки между файлами будут заполнены байтами 0xFF (такое же содержимое, как в чистых областях flash).

Пример:

esptool.py --chip ESP32 merge_bin -o merged-flash.bin --flash_mode dio --flash_size 4MB
 0x1000 bootloader.bin 0x8000 partition-table.bin 0x10000 app.bin

В этом примере будет сгенерирован файл merged-flash.bin, состоящий из 3 файлов. Этот файл может быть позже записан в память flash командой esptool.py write_flash 0x0 merged-flash.bin.

Описание используемых опций:

• Команда merge_bin поддерживает те же самые опции --flash_mode, --flash_size и --flash_freq, как и команда write_flash, чтобы переназначить соответствующие значение в заголовке flash загрузчика (подробности см. выше). Эти опции применяются для содержимого выходного файла таким же образом, как и при записи в память flash. Если используете эти опции, то убедитесь, что передали параметр --chip, поскольку и поддерживаемые значения, и смещение загрузчика зависят от типа чипа.
• Опция --target-offset 0xNNN создаст сгенерированный двоичный образ, который должен быть прошит по указанному смещению вместо смещения 0x0.
• Опция --fill-flash-size SIZE дополнит сгенерированный двоичный образ, который будет дополнен байтами 0xFF до полного указанного размера. Нарпример, --fill-flash-size 4MB создаст двоичный файл размером 4 мегабайта.
• Существует возможность подключить опции из текстового файла @filename. Например, эта возможность для удобства может использоваться с системой сборки ESP-IDF [8], которая создает файл flash_args в директории build проекта:

cd build    # Переход в директорию build проекта ESP-IDF
esptool.py --chip ESP32 merge_bin -o merged-flash.bin @flash_args

[Продвинутые команды]

Следующие команды используются реже, или могут быть интересны продвинутым пользователям (см. [9]).

• Verify Flash Data: verify_flash
• Dump a Memory Region to File: dump_mem
• Load a Binary to RAM: load_ram
• Read or Write RAM: read_mem / write_mem
• Read Flash Chip Registers: read_flash_status
• Write Flash Chip Registers: write_flash_status

[Ссылки]

1. Esptool.py Documentation site:espressif.com.
2. ESP32-C3: встроенный интерфейс USB в качестве консоли USB Serial / контроллера JTAG.
3. Протокол загрузчика ESP32.
4. Esptool.py Flash Modes site:espressif.com.
5. Secure Boot V2 site:espressif.com.
6. Flash Encryption site:espressif.com.
7. flashchips.h - идентификаторы чипов flash разных производителей.
8. ESP-IDF Build System.
9. Esptool Advanced Commands site:espressif.com.
10. Порядок следования байт (endianness).
11. Выбор режима загрузки ESP32-C3.
12. SPI Flash Modes site:espressif.com.
13. ESP32: проблемы с прошивкой SPI Flash и загрузкой.

 

Добавить комментарий


Защитный код
Обновить

Top of Page