├── .git-blame-ignore-revs ├── .github ├── ISSUE_TEMPLATE │ ├── bug-report-no-hw.yml │ ├── config.yml │ ├── feature-request.yml │ └── issue-with-hw.yml ├── pull_request_template.md └── workflows │ ├── build_esptool.yml │ ├── dangerjs.yml │ ├── dev_release_esptool_pypi.yml │ ├── issue_bot.yml │ ├── issue_comment.yml │ ├── new_issues.yml │ ├── new_prs.yml │ ├── release_esptool_pypi.yml │ └── test_esptool.yml ├── .gitignore ├── .gitlab-ci.yml ├── .pre-commit-config.yaml ├── CHANGELOG.md ├── CONTRIBUTING.rst ├── LICENSE ├── MANIFEST.in ├── README.md ├── ci ├── Sign-File.ps1 ├── download_flasher_stubs.py ├── espressif.ico ├── gh_changelog_template.md.j2 ├── patch_dev_release.py └── setup_softhsm2.sh ├── docs ├── README.md ├── _static │ └── esptool_versions.js ├── conf_common.py ├── en │ ├── about.rst │ ├── advanced-topics │ │ ├── boot-mode-selection.rst │ │ ├── diag │ │ │ ├── command_packet_format.diag │ │ │ ├── download_procedure_chart.diag │ │ │ ├── firmware_image_ext_header_format.diag │ │ │ ├── firmware_image_format.diag │ │ │ ├── firmware_image_format_esp8266.diag │ │ │ ├── firmware_image_header_format.diag │ │ │ └── response_packet_format.diag │ │ ├── firmware-image-format.rst │ │ ├── index.rst │ │ ├── serial-protocol.rst │ │ └── spi-flash-modes.rst │ ├── conf.py │ ├── contributing.rst │ ├── espefuse │ │ ├── adc-info-cmd.rst │ │ ├── burn-bit-cmd.rst │ │ ├── burn-block-data-cmd.rst │ │ ├── burn-custom-mac-cmd.rst │ │ ├── burn-efuse-cmd.rst │ │ ├── burn-key-cmd.rst │ │ ├── burn-key-digest-cmd.rst │ │ ├── check-error-cmd.rst │ │ ├── dump-cmd.rst │ │ ├── execute-scripts-cmd.rst │ │ ├── get-custom-mac-cmd.rst │ │ ├── inc │ │ │ ├── summary_ESP32-C2.rst │ │ │ ├── summary_ESP32-C3.rst │ │ │ ├── summary_ESP32-C5.rst │ │ │ ├── summary_ESP32-C6.rst │ │ │ ├── summary_ESP32-C61.rst │ │ │ ├── summary_ESP32-H2.rst │ │ │ ├── summary_ESP32-P4.rst │ │ │ ├── summary_ESP32-S2.rst │ │ │ ├── summary_ESP32-S3.rst │ │ │ └── summary_ESP32.rst │ │ ├── index.rst │ │ ├── read-write-protections-cmd.rst │ │ ├── set-flash-voltage-cmd.rst │ │ └── summary-cmd.rst │ ├── espsecure │ │ └── index.rst │ ├── esptool │ │ ├── advanced-commands.rst │ │ ├── advanced-options.rst │ │ ├── basic-commands.rst │ │ ├── basic-options.rst │ │ ├── configuration-file.rst │ │ ├── diag │ │ │ └── reset_sequence.svg │ │ ├── entering-bootloader.rst │ │ ├── flash-modes.rst │ │ ├── flasher-stub.rst │ │ ├── flashing-firmware.rst │ │ ├── index.rst │ │ ├── scripting.rst │ │ └── serial-connection.rst │ ├── index.rst │ ├── installation.rst │ ├── migration-guide.rst │ ├── remote-serial-ports.rst │ ├── resources.rst │ ├── troubleshooting.rst │ └── versions.rst └── utils.sh ├── esp_rfc2217_server.py ├── esp_rfc2217_server ├── __init__.py ├── __main__.py ├── esp_port_manager.py └── redirector.py ├── espefuse.py ├── espefuse ├── __init__.py ├── __main__.py ├── cli_util.py ├── efuse │ ├── __init__.py │ ├── base_fields.py │ ├── base_operations.py │ ├── csv_table_parser.py │ ├── emulate_efuse_controller_base.py │ ├── esp32 │ │ ├── __init__.py │ │ ├── emulate_efuse_controller.py │ │ ├── fields.py │ │ ├── mem_definition.py │ │ └── operations.py │ ├── esp32c2 │ │ ├── __init__.py │ │ ├── emulate_efuse_controller.py │ │ ├── fields.py │ │ ├── mem_definition.py │ │ └── operations.py │ ├── esp32c3 │ │ ├── __init__.py │ │ ├── emulate_efuse_controller.py │ │ ├── fields.py │ │ ├── mem_definition.py │ │ └── operations.py │ ├── esp32c5 │ │ ├── __init__.py │ │ ├── emulate_efuse_controller.py │ │ ├── fields.py │ │ ├── mem_definition.py │ │ └── operations.py │ ├── esp32c6 │ │ ├── __init__.py │ │ ├── emulate_efuse_controller.py │ │ ├── fields.py │ │ ├── mem_definition.py │ │ └── operations.py │ ├── esp32c61 │ │ ├── __init__.py │ │ ├── emulate_efuse_controller.py │ │ ├── fields.py │ │ ├── mem_definition.py │ │ └── operations.py │ ├── esp32h2 │ │ ├── __init__.py │ │ ├── emulate_efuse_controller.py │ │ ├── fields.py │ │ ├── mem_definition.py │ │ └── operations.py │ ├── esp32h21 │ │ ├── __init__.py │ │ ├── emulate_efuse_controller.py │ │ ├── fields.py │ │ ├── mem_definition.py │ │ └── operations.py │ ├── esp32h4 │ │ ├── __init__.py │ │ ├── emulate_efuse_controller.py │ │ ├── fields.py │ │ ├── mem_definition.py │ │ └── operations.py │ ├── esp32p4 │ │ ├── __init__.py │ │ ├── emulate_efuse_controller.py │ │ ├── fields.py │ │ ├── mem_definition.py │ │ └── operations.py │ ├── esp32s2 │ │ ├── __init__.py │ │ ├── emulate_efuse_controller.py │ │ ├── fields.py │ │ ├── mem_definition.py │ │ └── operations.py │ ├── esp32s3 │ │ ├── __init__.py │ │ ├── emulate_efuse_controller.py │ │ ├── fields.py │ │ ├── mem_definition.py │ │ └── operations.py │ ├── mem_definition_base.py │ └── util.py └── efuse_defs │ ├── esp32.yaml │ ├── esp32c2.yaml │ ├── esp32c3.yaml │ ├── esp32c5.yaml │ ├── esp32c6.yaml │ ├── esp32c61.yaml │ ├── esp32h2.yaml │ ├── esp32h21.yaml │ ├── esp32h2_v0.0_v1.1.yaml │ ├── esp32h4.yaml │ ├── esp32p4.yaml │ ├── esp32s2.yaml │ └── esp32s3.yaml ├── espsecure.py ├── espsecure ├── __init__.py ├── __main__.py └── esp_hsm_sign │ ├── __init__.py │ └── exceptions.py ├── esptool.py ├── esptool ├── __init__.py ├── __main__.py ├── bin_image.py ├── cli_util.py ├── cmds.py ├── config.py ├── loader.py ├── logger.py ├── reset.py ├── targets │ ├── __init__.py │ ├── esp32.py │ ├── esp32c2.py │ ├── esp32c3.py │ ├── esp32c5.py │ ├── esp32c6.py │ ├── esp32c61.py │ ├── esp32h2.py │ ├── esp32h21.py │ ├── esp32h4.py │ ├── esp32p4.py │ ├── esp32s2.py │ ├── esp32s3.py │ ├── esp8266.py │ └── stub_flasher │ │ ├── 1 │ │ ├── README.md │ │ ├── esp32.json │ │ ├── esp32c2.json │ │ ├── esp32c3.json │ │ ├── esp32c5.json │ │ ├── esp32c6.json │ │ ├── esp32c61.json │ │ ├── esp32h2.json │ │ ├── esp32p4.json │ │ ├── esp32s2.json │ │ ├── esp32s3.json │ │ └── esp8266.json │ │ └── 2 │ │ ├── LICENSE-APACHE │ │ ├── LICENSE-MIT │ │ ├── README.md │ │ ├── esp32.json │ │ ├── esp32c2.json │ │ ├── esp32c3.json │ │ ├── esp32c5.json │ │ ├── esp32c6.json │ │ ├── esp32c61.json │ │ ├── esp32h2.json │ │ ├── esp32p4.json │ │ ├── esp32s2.json │ │ ├── esp32s3.json │ │ └── esp8266.json ├── uf2_writer.py └── util.py ├── pyproject.toml ├── setup.py └── test ├── .covconf ├── README.md ├── conftest.py ├── ecdsa_secure_boot_signing_key2.pem ├── efuse_scripts ├── efuse_burn1.py ├── efuse_burn2.py ├── esp32 │ ├── config1.json │ ├── config2.json │ ├── execute_efuse_script.py │ └── execute_efuse_script2.py └── esp32xx │ ├── config1.json │ ├── config2.json │ ├── execute_efuse_script.py │ └── execute_efuse_script2.py ├── elf2image ├── esp32-app-template.elf ├── esp32-bootloader.elf ├── esp32-too-many-sections.elf ├── esp32-too-many-sections │ └── Makefile ├── esp32-zephyr.elf ├── esp32c6-appdesc.elf ├── esp32c6-appdesc │ ├── Makefile │ ├── esp32c6-appdesc.ld │ └── main.c ├── esp8266-nonossdkv12-example.elf ├── esp8266-nonossdkv20-at-v2.elf ├── esp8266-nonosssdk20-iotdemo.elf └── esp8266-openrtos-blink-v2.elf ├── images ├── aes_key.bin ├── bootloader_esp32.bin ├── bootloader_esp32_v5_2.bin ├── bootloader_esp32c3.bin ├── bootloader_esp8266.bin ├── efuse │ ├── 128bit │ ├── 128bit_key │ ├── 192bit │ ├── 192bit_1 │ ├── 192bit_2 │ ├── 224bit │ ├── 256bit │ ├── 256bit_1 │ ├── 256bit_1_256bit_2_combined │ ├── 256bit_2 │ ├── 256bit_3 │ ├── 64bit │ ├── 92bit │ ├── 96bit │ └── esp_efuse_custom_table.csv ├── esp32c3_header_min_rev.bin ├── esp32s3_header.bin ├── esp8266_deepsleep.bin ├── esp_idf_blink_esp32s2.bin ├── fifty_kb.bin ├── not_4_byte_aligned.bin ├── one_kb.bin ├── one_kb_all_ef.bin ├── one_mb.bin ├── onebyte.bin ├── partitions_singleapp.bin ├── ram_helloworld │ ├── helloworld-esp32.bin │ ├── helloworld-esp32_edit.bin │ ├── helloworld-esp32c2.bin │ ├── helloworld-esp32c3.bin │ ├── helloworld-esp32c5.bin │ ├── helloworld-esp32c6.bin │ ├── helloworld-esp32c61.bin │ ├── helloworld-esp32h2.bin │ ├── helloworld-esp32p4.bin │ ├── helloworld-esp32s3.bin │ ├── helloworld-esp8266.bin │ └── source │ │ ├── Makefile │ │ ├── ld │ │ ├── app_32.ld │ │ ├── app_32c2.ld │ │ ├── app_32c3.ld │ │ ├── app_32c5.ld │ │ ├── app_32c6.ld │ │ ├── app_32c61.ld │ │ ├── app_32h2.ld │ │ ├── app_32p4.ld │ │ ├── app_32s2.ld │ │ ├── app_32s3.ld │ │ └── app_8266.ld │ │ └── main.c ├── sector.bin └── zerolength.bin ├── secure_images ├── 256bit_iv.bin ├── 256bit_key.bin ├── 512bit_key.bin ├── bootloader-encrypted-aes-xts.bin ├── bootloader-encrypted-conf0.bin ├── bootloader-encrypted-conf3.bin ├── bootloader-encrypted-conf9.bin ├── bootloader-encrypted-confc.bin ├── bootloader-encrypted.bin ├── bootloader.bin ├── bootloader_digested.bin ├── bootloader_multi_signed_v2.bin ├── bootloader_signed.bin ├── bootloader_signed_v2_ecdsa192.bin ├── bootloader_signed_v2_ecdsa256.bin ├── bootloader_signed_v2_ecdsa384.bin ├── bootloader_signed_v2_rsa.bin ├── bootloader_unsigned_v2.bin ├── digest_iv.bin ├── ecdsa192_public_key_digest_v2.bin ├── ecdsa192_secure_boot_signing_key.pem ├── ecdsa192_secure_boot_signing_key2.pem ├── ecdsa192_secure_boot_signing_key_v2.pem ├── ecdsa192_secure_boot_signing_pubkey.pem ├── ecdsa192_secure_boot_signing_pubkey2.pem ├── ecdsa256_public_key_digest_v2.bin ├── ecdsa256_secure_boot_signing_key.pem ├── ecdsa256_secure_boot_signing_key2.pem ├── ecdsa256_secure_boot_signing_key_pkcs8.pem ├── ecdsa256_secure_boot_signing_key_v2.pem ├── ecdsa256_secure_boot_signing_pubkey.pem ├── ecdsa256_secure_boot_signing_pubkey2.pem ├── ecdsa256_secure_boot_signing_pubkey_raw.bin ├── ecdsa384_secure_boot_signing_key.pem ├── ecdsa384_secure_boot_signing_key2.pem ├── ecdsa384_secure_boot_signing_pubkey.pem ├── ecdsa384_secure_boot_signing_pubkey2.pem ├── ef-flashencryption-key.bin ├── hello-world-signed-encrypted-aes-xts-256.bin ├── hello-world-signed-encrypted-aes-xts.bin ├── hello-world-signed-encrypted.bin ├── hello-world-signed.bin ├── pre_calculated_bootloader_signature.bin ├── pre_calculated_bootloader_signature_ecdsa192.bin ├── pre_calculated_bootloader_signature_ecdsa256.bin ├── pre_calculated_bootloader_signature_ecdsa384.bin ├── pre_calculated_bootloader_signature_rsa.bin ├── rsa_public_key_digest.bin ├── rsa_secure_boot_signing_key.pem ├── rsa_secure_boot_signing_key2.pem ├── rsa_secure_boot_signing_key3.pem ├── rsa_secure_boot_signing_key4.pem ├── rsa_secure_boot_signing_pubkey.pem ├── rsa_secure_boot_signing_pubkey2.pem └── rsa_secure_boot_signing_pubkey4.pem ├── sitecustomize.py ├── test_espefuse.py ├── test_espsecure.py ├── test_espsecure_hsm.py ├── test_esptool.py ├── test_esptool_sdm.py ├── test_image_info.py ├── test_imagegen.py ├── test_logger.py ├── test_merge_bin.py ├── test_modules.py └── test_uf2_ids.py /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # Refactoring 2 | 4875e8906fdedeb7ecb2f94aa40877c418df3b70 3 | 63debb0facdc50b52c7759a01d773f6ebb25bc81 4 | aee798dbe46640f708fe2297b94ff30c11152fca 5 | e5f5d9de3b3ecdc096ca14150c4bedd9817b709a 6 | e17d996bb0faf58d3fe4c77e415246ffb3687976 7 | 513898db2ac7a1990dc94aa6f49cda3165c442bf 8 | 07678b581003da453ec8bafed5993fb32862bbbb 9 | b57f69bd13222b1753446a0f7c17386eda1dc2c9 10 | 11 | # Formating with Black 12 | 45f1da954eeab4897fb852894fae0c1b901b3926 13 | 14 | # Refactoring documentation 15 | 6282f98dbfca58add4992c259c0aac3c3ec64d3f 16 | 17 | # Fixing linter issues 18 | 2e4e77cde269379f3aba2e1344c912f47c5974de 19 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report-no-hw.yml: -------------------------------------------------------------------------------- 1 | name: Bug report - no ESP chip involved 2 | description: Report bugs or crashes which don't use any attached hardware 3 | labels: ['Type: Bug'] 4 | body: 5 | - type: input 6 | id: os 7 | attributes: 8 | label: Operating System 9 | description: On which OS does this issue occur? 10 | placeholder: ex. macOS 12.1 and Xubuntu 20.04 11 | validations: 12 | required: true 13 | - type: input 14 | id: version 15 | attributes: 16 | label: Esptool Version 17 | description: The output of `git describe` if working with the sources, output of `esptool.py version` otherwise. If possible, consider [updating esptool](https://docs.espressif.com/projects/esptool/en/latest/installation.html#how-to-update). 18 | placeholder: ex. v4.0.1, commit v4.1-10-g2059335aa 19 | validations: 20 | required: true 21 | - type: input 22 | id: python 23 | attributes: 24 | label: Python Version 25 | description: Which Python version are you using? Run `python -V` to check this. 26 | placeholder: ex. Python 3.10.6 27 | validations: 28 | required: true 29 | - type: input 30 | id: command 31 | attributes: 32 | label: Full Esptool Command Line that Was Run 33 | description: Please input the full esptool command. 34 | placeholder: ex. `esptool.py elf2image esp32-bootloader.elf` 35 | - type: textarea 36 | id: output 37 | attributes: 38 | label: Esptool Output 39 | description: Provide the full output log. 40 | placeholder: Copy and paste all lines of output here. 41 | render: shell 42 | - type: textarea 43 | id: expected 44 | attributes: 45 | label: What is the Expected Behaviour? 46 | description: Please provide a clear and concise description of the expected behaviour. 47 | placeholder: ex. Print the version number. 48 | - type: textarea 49 | id: more-info 50 | attributes: 51 | label: More Information 52 | description: Do you have any other information from investigating this? 53 | placeholder: ex. I tried on my friend's Windows 10 PC and the command works there. 54 | - type: textarea 55 | id: other-remarks 56 | attributes: 57 | label: Other Steps to Reproduce 58 | description: Is there any other information you can think of which will help us reproduce this problem? 59 | placeholder: ex. Only crashes on first day of the month. 60 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | blank_issues_enabled: false 2 | contact_links: 3 | - name: ESP8266 Forum 4 | url: https://bbs.espressif.com/ 5 | about: For questions about using esptool.py with ESP8266 6 | - name: ESP32 Forum 7 | url: https://esp32.com 8 | about: For questions about using esptool.py with ESP32 9 | 10 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature-request.yml: -------------------------------------------------------------------------------- 1 | name: Feature request 2 | description: Suggest an idea for this project 3 | labels: ['Type: Feature Request'] 4 | body: 5 | - type: markdown 6 | attributes: 7 | value: | 8 | * We welcome any ideas or feature requests! It’s helpful if you can explain exactly why the feature would be useful. 9 | * There are usually some outstanding feature requests in the [existing issues list](https://github.com/espressif/esptool/issues?q=is%3Aopen+is%3Aissue+label%3Aenhancement), feel free to add comments to them. 10 | * If you would like to contribute, please read the [contributions guide](https://docs.espressif.com/projects/esptool/en/latest/contributing.html). 11 | - type: textarea 12 | id: problem-related 13 | attributes: 14 | label: Is your feature request related to a problem? 15 | description: Please provide a clear and concise description of what the problem is. 16 | placeholder: ex. I'm always frustrated when ... 17 | - type: textarea 18 | id: solution 19 | attributes: 20 | label: Describe the solution you'd like 21 | description: Please provide a clear and concise description of what you want to happen. 22 | placeholder: ex. When connecting to an Espressif chip ... 23 | - type: textarea 24 | id: alternatives 25 | attributes: 26 | label: Describe alternatives you've considered 27 | description: Please provide a clear and concise description of any alternative solutions or features you've considered. 28 | placeholder: ex. Choosing other approach wouldn't work, because ... 29 | - type: textarea 30 | id: context 31 | attributes: 32 | label: Additional context 33 | description: Please add any other context or screenshots about the feature request here. 34 | placeholder: ex. This would work only when ... 35 | -------------------------------------------------------------------------------- /.github/pull_request_template.md: -------------------------------------------------------------------------------- 1 | 4 | 5 | # This change fixes the following bug(s): 6 | 9 | 10 | # I have tested this change with the following hardware & software combinations: 11 | 14 | 15 | # I have run the esptool.py automated integration tests with this change and the above hardware: 16 | 21 | -------------------------------------------------------------------------------- /.github/workflows/dangerjs.yml: -------------------------------------------------------------------------------- 1 | name: DangerJS Pull Request linter 2 | on: 3 | pull_request_target: 4 | types: [opened, edited, reopened, synchronize] 5 | 6 | permissions: 7 | pull-requests: write 8 | contents: write 9 | 10 | jobs: 11 | pull-request-style-linter: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Check out PR head 15 | uses: actions/checkout@v4 16 | with: 17 | ref: ${{ github.event.pull_request.head.sha }} 18 | 19 | - name: DangerJS pull request linter 20 | uses: espressif/shared-github-dangerjs@v1 21 | env: 22 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 23 | with: 24 | instructions-contributions-file: 'CONTRIBUTING.rst' 25 | instructions-gitlab-mirror: 'true' 26 | -------------------------------------------------------------------------------- /.github/workflows/dev_release_esptool_pypi.yml: -------------------------------------------------------------------------------- 1 | # This workflow will upload an esptool Python package when a dev release tag (e.g. "v4.7.dev2") is pushed 2 | 3 | name: PyPI dev release 4 | 5 | on: 6 | push: 7 | tags: 8 | - v*.*.dev* 9 | 10 | jobs: 11 | build_and_upload: 12 | 13 | runs-on: ubuntu-latest 14 | 15 | if: startsWith(github.ref, 'refs/tags/') && contains(github.ref_name, 'dev') 16 | 17 | steps: 18 | - uses: actions/checkout@master 19 | - name: Set up Python 3.13 20 | uses: actions/setup-python@master 21 | with: 22 | python-version: '3.13' 23 | - name: Install dependencies 24 | run: | 25 | python -m pip install --upgrade pip 26 | python -m pip install twine build 27 | 28 | - name: Create development release ${{ github.ref_name }} 29 | env: 30 | TWINE_USERNAME: __token__ 31 | TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} 32 | TWINE_NON_INTERACTIVE: true 33 | run: | 34 | python ci/patch_dev_release.py --version ${{ github.ref_name }} esptool/__init__.py 35 | git diff 36 | python -m pip download esptool==$(python setup.py -V) && echo "Version ${{ github.ref_name }} already published, skipping..." && exit 1 37 | 38 | echo "Packaging and publishing new esptool development release: ${{ github.ref_name }}" 39 | python -m build --sdist 40 | twine upload dist/* 41 | -------------------------------------------------------------------------------- /.github/workflows/issue_bot.yml: -------------------------------------------------------------------------------- 1 | name: Bot response to issues 2 | 3 | on: 4 | issues: 5 | types: [opened, edited] 6 | 7 | jobs: 8 | docs_bot: 9 | name: Generate automated response by docs bot 10 | runs-on: ubuntu-latest 11 | steps: 12 | - name: Docs bot action 13 | if: ${{ github.repository_owner == 'espressif' }} 14 | uses: espressif/docs-bot-action@master 15 | env: 16 | BOT_API_KEY: ${{ secrets.BOT_API_KEY }} 17 | BOT_INTEGRATION_ID: ${{ secrets.BOT_INTEGRATION_ID }} 18 | BOT_API_ENDPOINT: ${{ secrets.BOT_API_ENDPOINT }} 19 | with: 20 | github_token: ${{ secrets.GITHUB_TOKEN }} 21 | github_repository: ${{ github.repository }} 22 | github_issue_number: ${{ github.event.issue.number }} 23 | title: ${{ github.event.issue.title }} 24 | in_msg: ${{ github.event.issue.body }} 25 | prefix_out_msg: > 26 | Hi @${{ github.event.issue.user.login }}! Please be aware that 27 | (1) the following suggestions are generated by a bot and haven't been fact-checked by Espressif 28 | Systems, 29 | (2) burning eFuses and enabling security features are irreversible operations and can damage your ESP32 device. 30 | We hope that this message will help you until an Espressif Engineer looks at your issue. 31 | -------------------------------------------------------------------------------- /.github/workflows/issue_comment.yml: -------------------------------------------------------------------------------- 1 | name: Sync issue comments to Jira 2 | 3 | # This workflow will be triggered when new issue comment is created (including PR comments) 4 | on: issue_comment 5 | 6 | jobs: 7 | sync_issue_comments_to_jira: 8 | name: Sync Issue Comments to Jira 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@master 12 | - name: Sync issue comments to Jira 13 | uses: espressif/sync-jira-actions@v1 14 | env: 15 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 16 | JIRA_PASS: ${{ secrets.JIRA_PASS }} 17 | JIRA_PROJECT: ESPTOOL 18 | JIRA_COMPONENT: GitHub 19 | JIRA_URL: ${{ secrets.JIRA_URL }} 20 | JIRA_USER: ${{ secrets.JIRA_USER }} 21 | -------------------------------------------------------------------------------- /.github/workflows/new_issues.yml: -------------------------------------------------------------------------------- 1 | name: Sync issues to Jira 2 | 3 | # This workflow will be triggered when a new issue is opened 4 | on: issues 5 | 6 | jobs: 7 | sync_issues_to_jira: 8 | name: Sync issues to Jira 9 | runs-on: ubuntu-latest 10 | steps: 11 | - uses: actions/checkout@master 12 | - name: Sync GitHub issues to Jira project 13 | uses: espressif/sync-jira-actions@v1 14 | env: 15 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 16 | JIRA_PASS: ${{ secrets.JIRA_PASS }} 17 | JIRA_PROJECT: ESPTOOL 18 | JIRA_COMPONENT: GitHub 19 | JIRA_URL: ${{ secrets.JIRA_URL }} 20 | JIRA_USER: ${{ secrets.JIRA_USER }} 21 | -------------------------------------------------------------------------------- /.github/workflows/new_prs.yml: -------------------------------------------------------------------------------- 1 | name: Sync remaining PRs to Jira 2 | 3 | # This workflow will be triggered every hour, to sync remaining PRs (i.e. PRs with zero comment) to Jira project 4 | # Note that, PRs can also get synced when new PR comment is created 5 | on: 6 | schedule: 7 | - cron: "0 * * * *" 8 | 9 | jobs: 10 | sync_prs_to_jira: 11 | name: Sync PRs to Jira 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@master 15 | - name: Sync PRs to Jira project 16 | uses: espressif/sync-jira-actions@v1 17 | with: 18 | cron_job: true 19 | env: 20 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 21 | JIRA_PASS: ${{ secrets.JIRA_PASS }} 22 | JIRA_PROJECT: ESPTOOL 23 | JIRA_COMPONENT: GitHub 24 | JIRA_URL: ${{ secrets.JIRA_URL }} 25 | JIRA_USER: ${{ secrets.JIRA_USER }} 26 | -------------------------------------------------------------------------------- /.github/workflows/release_esptool_pypi.yml: -------------------------------------------------------------------------------- 1 | # This workflow will upload an esptool Python package when a release is created 2 | 3 | name: PyPI release 4 | 5 | on: 6 | release: 7 | types: [released] 8 | 9 | jobs: 10 | build_and_upload: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@master 16 | - name: Set up Python 3.13 17 | uses: actions/setup-python@master 18 | with: 19 | python-version: '3.13' 20 | - name: Install dependencies 21 | run: | 22 | python -m pip install --upgrade pip 23 | pip install twine build 24 | - name: Build and upload esptool ${{ github.event.release.tag_name }} 25 | env: 26 | TWINE_USERNAME: __token__ 27 | TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} 28 | run: | 29 | PUBLISHED_VERSION=$(curl https://pypi.org/pypi/esptool/json 2>/dev/null | jq -r '.info.version') 30 | CURRENT_VERSION=$(python setup.py --version 2>/dev/null) 31 | 32 | if [ "$PUBLISHED_VERSION" == "$CURRENT_VERSION" ]; then 33 | echo "Version ${PUBLISHED_VERSION} already published, skipping..." 34 | exit 1 35 | else 36 | echo "Packaging and publishing new esptool version: ${CURRENT_VERSION}" 37 | python -m build --sdist 38 | twine upload dist/* 39 | fi 40 | -------------------------------------------------------------------------------- /.github/workflows/test_esptool.yml: -------------------------------------------------------------------------------- 1 | name: Test esptool 2 | 3 | on: [push, pull_request] 4 | 5 | jobs: 6 | test_esptool: 7 | runs-on: ubuntu-22.04 8 | 9 | strategy: 10 | matrix: 11 | python-version: ['3.10', '3.11', '3.12', '3.13'] 12 | 13 | steps: 14 | - name: Checkout ref commit 15 | uses: actions/checkout@master 16 | 17 | - name: Set up Python ${{ matrix.python-version }} 18 | uses: actions/setup-python@master 19 | with: 20 | python-version: ${{ matrix.python-version }} 21 | 22 | - name: Install dependencies 23 | run: | 24 | python -m pip install --upgrade pip 25 | pip install 'setuptools>=64' 26 | 27 | - name: SoftHSM2 setup 28 | run: | 29 | sudo apt-get update 30 | sudo apt-get install -y softhsm2 31 | sudo chmod -R a+rx /etc/softhsm 32 | sudo chmod a+r /etc/softhsm/softhsm2.conf 33 | sudo chown -R $(whoami) /var/lib/softhsm 34 | ./ci/setup_softhsm2.sh || exit 1 35 | 36 | - name: Install esptool and check if the installed versions can run 37 | run: | 38 | python setup.py build 39 | pip install --extra-index-url https://dl.espressif.com/pypi -e .[dev,hsm] 40 | esptool.py --help 41 | espefuse.py --help 42 | espsecure.py --help 43 | 44 | - name: Test esptool and components 45 | run: | 46 | pytest -m host_test 47 | pytest test/test_espsecure_hsm.py 48 | 49 | check_stubs: 50 | runs-on: ubuntu-latest 51 | steps: 52 | - name: Checkout 53 | uses: actions/checkout@master 54 | 55 | - name: Set up Python 3.13 56 | uses: actions/setup-python@master 57 | with: 58 | python-version: 3.13 59 | 60 | - name: Check if flasher stubs are up-to-date 61 | run: | 62 | ./ci/download_flasher_stubs.py 63 | git diff --exit-code 64 | 65 | lint_esptool: 66 | runs-on: ubuntu-22.04 67 | steps: 68 | - name: Checkout 69 | uses: actions/checkout@master 70 | 71 | - name: Set up Python 3.10 72 | uses: actions/setup-python@master 73 | with: 74 | python-version: "3.10" 75 | 76 | - name: Run pre-commit hooks 77 | run: | 78 | pip install --extra-index-url https://dl.espressif.com/pypi -e .[dev] 79 | pre-commit run --all-files 80 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .pypirc 2 | *.pyc 3 | *~ 4 | GPATH 5 | GRTAGS 6 | GTAGS 7 | esptool.egg-info 8 | .eggs 9 | build 10 | dist 11 | local.mk 12 | 13 | .envrc 14 | report.xml 15 | 16 | docs/_build/ 17 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/astral-sh/ruff-pre-commit 3 | rev: v0.9.6 4 | hooks: 5 | - id: ruff # Runs ruff linter (replaces flake8) 6 | args: [--fix, --exit-non-zero-on-fix] # --fix for fixing errors 7 | - id: ruff-format 8 | - repo: https://github.com/sphinx-contrib/sphinx-lint 9 | rev: v1.0.0 10 | hooks: 11 | - id: sphinx-lint 12 | name: Lint RST files in docs folder using Sphinx Lint 13 | files: ^((docs/en)/.*\.(rst|inc))|CONTRIBUTING.rst$ 14 | - repo: https://github.com/pre-commit/mirrors-mypy 15 | rev: v1.15.0 16 | hooks: 17 | - id: mypy 18 | additional_dependencies: ['types-PyYAML<=6.0.12.12'] 19 | # ignore wrapper scripts because of name colision with efuse/__init__.py etc. 20 | exclude: test/|docs/|espefuse.py|espsecure.py|esptool.py|esp_rfc2217_server.py 21 | - repo: https://github.com/codespell-project/codespell 22 | rev: v2.4.1 23 | hooks: 24 | - id: codespell 25 | additional_dependencies: 26 | - tomli 27 | - repo: https://github.com/espressif/conventional-precommit-linter 28 | rev: v1.10.0 29 | hooks: 30 | - id: conventional-precommit-linter 31 | stages: [commit-msg] 32 | args: 33 | - --allow-breaking 34 | default_stages: [pre-commit] 35 | default_install_hook_types: [pre-commit, commit-msg] 36 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include README.md 2 | include LICENSE 3 | include esptool/targets/stub_flasher/1/* 4 | include esptool/targets/stub_flasher/2/* 5 | include espefuse/efuse_defs/*.yaml 6 | # sdist includes test/test*.py by default, but esptool.py tests 7 | # are so far only intended to run from the git repo itself 8 | prune test 9 | prune .github 10 | prune docs 11 | exclude .git* 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # esptool.py 2 | 3 | A Python-based, open-source, platform-independent serial utility for flashing, provisioning, and interacting with Espressif SoCs. 4 | 5 | [![Test esptool](https://github.com/espressif/esptool/actions/workflows/test_esptool.yml/badge.svg?branch=master)](https://github.com/espressif/esptool/actions/workflows/test_esptool.yml) [![Build esptool](https://github.com/espressif/esptool/actions/workflows/build_esptool.yml/badge.svg?branch=master)](https://github.com/espressif/esptool/actions/workflows/build_esptool.yml) 6 | 7 | ## Documentation 8 | 9 | Visit the [documentation](https://docs.espressif.com/projects/esptool/) or run `esptool.py -h`. 10 | 11 | ## Contribute 12 | 13 | If you're interested in contributing to esptool.py, please check the [contributions guide](https://docs.espressif.com/projects/esptool/en/latest/contributing.html). 14 | 15 | ## About 16 | 17 | esptool.py was initially created by Fredrik Ahlberg (@[themadinventor](https://github.com/themadinventor/)), and later maintained by Angus Gratton (@[projectgus](https://github.com/projectgus/)). It is now supported by Espressif Systems. It has also received improvements from many members of the community. 18 | 19 | ## License 20 | 21 | This document and the attached source code are released as Free Software under GNU General Public License Version 2 or later. See the accompanying [LICENSE file](https://github.com/espressif/esptool/blob/master/LICENSE) for a copy. 22 | -------------------------------------------------------------------------------- /ci/Sign-File.ps1: -------------------------------------------------------------------------------- 1 | [CmdletBinding()] 2 | param ( 3 | [Parameter()] 4 | [String] 5 | $Path 6 | ) 7 | 8 | 9 | function FindSignTool { 10 | $SignTool = "signtool.exe" 11 | if (Get-Command $SignTool -ErrorAction SilentlyContinue) { 12 | return $SignTool 13 | } 14 | $SignTool = "${env:ProgramFiles(x86)}\Windows Kits\10\bin\x64\signtool.exe" 15 | if (Test-Path -Path $SignTool -PathType Leaf) { 16 | return $SignTool 17 | } 18 | $SignTool = "${env:ProgramFiles(x86)}\Windows Kits\10\bin\x86\signtool.exe" 19 | if (Test-Path -Path $SignTool -PathType Leaf) { 20 | return $SignTool 21 | } 22 | $sdkVers = "10.0.22000.0", "10.0.20348.0", "10.0.19041.0", "10.0.17763.0" 23 | Foreach ($ver in $sdkVers) 24 | { 25 | $SignTool = "${env:ProgramFiles(x86)}\Windows Kits\10\bin\${ver}\x64\signtool.exe" 26 | if (Test-Path -Path $SignTool -PathType Leaf) { 27 | return $SignTool 28 | } 29 | } 30 | "signtool.exe not found" 31 | Exit 1 32 | } 33 | 34 | function SignEsptool { 35 | param( 36 | [Parameter()] 37 | [String] 38 | $Path 39 | ) 40 | 41 | $SignTool = FindSignTool 42 | "Using: $SignTool" 43 | $CertificateFile = [system.io.path]::GetTempPath() + "certificate.pfx" 44 | 45 | if ($null -eq $env:CERTIFICATE) { 46 | "CERTIFICATE variable not set, unable to sign the file" 47 | Exit 1 48 | } 49 | 50 | if ("" -eq $env:CERTIFICATE) { 51 | "CERTIFICATE variable is empty, unable to sign the file" 52 | Exit 1 53 | } 54 | 55 | $SignParameters = @("sign", "/tr", 'http://timestamp.digicert.com', "/td", "SHA256", "/f", $CertificateFile, "/fd", "SHA256") 56 | if ($env:CERTIFICATE_PASSWORD) { 57 | "CERTIFICATE_PASSWORD detected, using the password" 58 | $SignParameters += "/p" 59 | $SignParameters += $env:CERTIFICATE_PASSWORD 60 | } 61 | $SignParameters += $Path 62 | 63 | [byte[]]$CertificateBytes = [convert]::FromBase64String($env:CERTIFICATE) 64 | [IO.File]::WriteAllBytes($CertificateFile, $CertificateBytes) 65 | 66 | &$SignTool $SignParameters 67 | 68 | if (0 -eq $LASTEXITCODE) { 69 | Remove-Item $CertificateFile 70 | } else { 71 | Remove-Item $CertificateFile 72 | "Signing failed" 73 | Exit 1 74 | } 75 | 76 | } 77 | 78 | SignEsptool ${Path} 79 | -------------------------------------------------------------------------------- /ci/download_flasher_stubs.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD 4 | # SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | import glob 7 | import os 8 | import urllib.request 9 | 10 | STUBS = ( 11 | { 12 | "STUB_SET_VERSION": "1", 13 | "DOWNLOAD_URL": "https://github.com/espressif/esptool-legacy-flasher-stub/releases/download", 14 | "TAG_URL": "https://github.com/espressif/esptool-legacy-flasher-stub/releases/tag", 15 | "VERSION": "v1.5.1", 16 | "FILE_LIST": ( 17 | "esp32", 18 | "esp32c2", 19 | "esp32c3", 20 | "esp32c5", 21 | "esp32c6", 22 | "esp32c61", 23 | "esp32h2", 24 | "esp32p4", 25 | "esp32s2", 26 | "esp32s3", 27 | "esp8266", 28 | ), 29 | "LICENSE": "released as Free Software under GNU General Public License " 30 | "Version 2 or later", 31 | }, 32 | { 33 | "STUB_SET_VERSION": "2", 34 | "DOWNLOAD_URL": "https://github.com/espressif/esp-flasher-stub/releases/download", 35 | "TAG_URL": "https://github.com/espressif/esp-flasher-stub/releases/tag", 36 | "VERSION": "v0.1.0", 37 | "FILE_LIST": ( 38 | "esp32", 39 | "esp32c2", 40 | "esp32c3", 41 | "esp32c5", 42 | "esp32c6", 43 | "esp32c61", 44 | "esp32h2", 45 | "esp32p4", 46 | "esp32s2", 47 | "esp32s3", 48 | "esp8266", 49 | ), 50 | "LICENSE": "dual licensed under the Apache License Version 2.0 or the MIT " 51 | "license", 52 | }, 53 | ) 54 | 55 | DESTINATION_DIR = os.path.join("esptool", "targets", "stub_flasher") 56 | 57 | README_TEMPLATE = """# Licensing 58 | 59 | The binaries in JSON format distributed in this directory are {LICENSE}. They were released at {URL} from where the sources can be obtained. 60 | """ # noqa: E501 61 | 62 | 63 | def main(): 64 | for stub_set in STUBS: 65 | dest_sub_dir = os.path.join(DESTINATION_DIR, stub_set["STUB_SET_VERSION"]) 66 | 67 | """ The directory is cleaned up so we would detect if a stub was just committed 68 | into the repository but the name was not added into the FILE_LIST of STUBS. 69 | This would be an unwanted state because the checker would not detect any 70 | changes in that stub.""" 71 | for old_file in glob.glob(os.path.join(dest_sub_dir, "*.json")): 72 | print(f"Removing old file {old_file}") 73 | os.remove(old_file) 74 | 75 | for file_name in stub_set["FILE_LIST"]: 76 | file = ".".join((file_name, "json")) 77 | url = "/".join((stub_set["DOWNLOAD_URL"], stub_set["VERSION"], file)) 78 | dest = os.path.join(dest_sub_dir, file) 79 | print(f"Downloading {url} to {dest}") 80 | urllib.request.urlretrieve(url, dest) 81 | 82 | with open(os.path.join(dest_sub_dir, "README.md"), "w") as f: 83 | print(f"Writing README to {f.name}") 84 | f.write( 85 | README_TEMPLATE.format( 86 | LICENSE=stub_set["LICENSE"], 87 | URL="/".join((stub_set["TAG_URL"], stub_set["VERSION"])), 88 | ) 89 | ) 90 | 91 | 92 | if __name__ == "__main__": 93 | main() 94 | -------------------------------------------------------------------------------- /ci/espressif.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/ci/espressif.ico -------------------------------------------------------------------------------- /ci/gh_changelog_template.md.j2: -------------------------------------------------------------------------------- 1 | {# This changelog template is used for automatically generated GH release notes. #} 2 | {# It is passed to commitizen's --template option in a GH Actions workflow run. #} 3 | 4 | {% for entry in tree %} 5 | 6 | {% for change_key, changes in entry.changes.items() %} 7 | 8 | {% if change_key %} 9 | ### {{ change_key }} 10 | {% endif %} 11 | 12 | {% for change in changes %} 13 | {% if change.scope %} 14 | - **{{ change.scope }}**: {{ change.message }} 15 | {% elif change.message %} 16 | - {{ change.message }} 17 | {% endif %} 18 | {% endfor %} 19 | {% endfor %} 20 | {% endfor %} 21 | 22 | Thanks to , and others for contributing to this release! 23 | 24 | # Results of checking the release against common anti-virus SW 25 | 26 | 27 | 28 | The failures are probably false positives. You can mark esptool as safe in your anti-virus SW, or [install esptool from source](https://docs.espressif.com/projects/esptool/en/latest/installation.html). 29 | -------------------------------------------------------------------------------- /ci/patch_dev_release.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD 2 | # 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | 5 | import argparse 6 | import re 7 | 8 | LINE_RE = re.compile(r"^__version__ = ['\"]([^'\"]*)['\"]") 9 | NEW_LINE = '__version__ = "{}"\n' 10 | 11 | 12 | def patch_file(path, new_version): 13 | assert ".dev" in new_version 14 | new_version = new_version.lstrip("v") 15 | 16 | with open(path, "r") as fin: 17 | lines = fin.readlines() 18 | 19 | for i, line in enumerate(lines, start=0): 20 | m = LINE_RE.search(line) 21 | if m: 22 | lines[i] = NEW_LINE.format(new_version) 23 | break 24 | 25 | with open(path, "w") as fout: 26 | fout.writelines(lines) 27 | 28 | 29 | def main(): 30 | parser = argparse.ArgumentParser() 31 | parser.add_argument("file", help="Path to script with __version__") 32 | parser.add_argument( 33 | "--version", help="Development version specifier to patch the version to" 34 | ) 35 | args = parser.parse_args() 36 | patch_file(args.file, args.version) 37 | 38 | 39 | if __name__ == "__main__": 40 | main() 41 | -------------------------------------------------------------------------------- /ci/setup_softhsm2.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Init tokens for tests 4 | softhsm2-util --init-token --label softhsm-test-token --pin 1234 --so-pin 123456 --slot 0 5 | softhsm2-util --init-token --label softhsm-test-token-1 --pin 1234 --so-pin 123456 --slot 1 6 | softhsm2-util --init-token --label softhsm-test-token-2 --pin 1234 --so-pin 123456 --slot 2 7 | softhsm2-util --init-token --label softhsm-test-token-3 --pin 1234 --so-pin 123456 --slot 3 8 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Documentation Source Folder 2 | 3 | This folder contains source files of **esptool documentation**. 4 | 5 | The sources do not render well in GitHub and some information is not visible at all. 6 | 7 | Use actual documentation generated within about 20 minutes on each commit: 8 | 9 | # Hosted Documentation 10 | 11 | * English: https://docs.espressif.com/projects/esptool/ 12 | 13 | The above URL is for the master branch latest version. Click the drop-down in the bottom left to choose a particular version. 14 | 15 | # Building Documentation 16 | 17 | The documentation is built using the python package `esp-docs`, which can be installed by running `pip install esp-docs`. Running `build-docs --help` will give a summary of available options. For more information see the `esp-docs` documentation at https://github.com/espressif/esp-docs/blob/master/README.md 18 | -------------------------------------------------------------------------------- /docs/_static/esptool_versions.js: -------------------------------------------------------------------------------- 1 | var DOCUMENTATION_VERSIONS = { 2 | DEFAULTS: { has_targets: true, 3 | supported_targets: [ "esp32" ] 4 | }, 5 | VERSIONS: [ 6 | { name: "latest", old: false, pre_release: false, supported_targets: [ "esp8266", "esp32", "esp32s2", "esp32s3", "esp32c3", "esp32c2", "esp32c6", "esp32p4", "esp32h2", "esp32c5", "esp32c61" ] }, 7 | { name: "release-v4", old: false, pre_release: false, supported_targets: [ "esp8266", "esp32", "esp32s2", "esp32s3", "esp32c3", "esp32c2", "esp32c6", "esp32p4", "esp32h2", "esp32c5", "esp32c61" ] }, 8 | ], 9 | IDF_TARGETS: [ 10 | { text: "ESP8266", value: "esp8266" }, 11 | { text: "ESP32", value: "esp32" }, 12 | { text: "ESP32-S2", value: "esp32s2" }, 13 | { text: "ESP32-S3", value: "esp32s3" }, 14 | { text: "ESP32-C3", value: "esp32c3" }, 15 | { text: "ESP32-C2", value: "esp32c2" }, 16 | { text: "ESP32-C6", value: "esp32c6" }, 17 | { text: "ESP32-H2", value: "esp32h2" }, 18 | { text: "ESP32-P4", value: "esp32p4" }, 19 | { text: "ESP32-C5", value: "esp32c5" }, 20 | { text: "ESP32-C61", value: "esp32c61" }, 21 | ] 22 | }; 23 | -------------------------------------------------------------------------------- /docs/conf_common.py: -------------------------------------------------------------------------------- 1 | from esp_docs.conf_docs import * # noqa: F403,F401 2 | 3 | languages = ["en"] 4 | idf_targets = [ 5 | "esp8266", 6 | "esp32", 7 | "esp32s2", 8 | "esp32s3", 9 | "esp32c3", 10 | "esp32c2", 11 | "esp32c6", 12 | "esp32h2", 13 | "esp32p4", 14 | "esp32c5", 15 | "esp32c61", 16 | ] 17 | 18 | # link roles config 19 | github_repo = "espressif/esptool" 20 | 21 | # context used by sphinx_idf_theme 22 | html_context["github_user"] = "espressif" 23 | html_context["github_repo"] = "esptool" 24 | 25 | html_static_path = ["../_static"] 26 | 27 | # Conditional content 28 | extensions += [ 29 | "esp_docs.esp_extensions.dummy_build_system", 30 | "sphinx.ext.autodoc", 31 | "sphinx.ext.napoleon", 32 | "sphinx_tabs.tabs", 33 | ] 34 | 35 | sphinx_tabs_disable_tab_closing = True 36 | 37 | ESP8266_DOCS = [] 38 | 39 | ESP32_DOCS = [ 40 | "espefuse/*", 41 | "espsecure/*", 42 | ] 43 | 44 | conditional_include_dict = { 45 | "esp8266": ESP8266_DOCS, 46 | "esp32": ESP32_DOCS, 47 | "esp32s2": ESP32_DOCS, 48 | "esp32c3": ESP32_DOCS, 49 | "esp32s3": ESP32_DOCS, 50 | "esp32c2": ESP32_DOCS, 51 | "esp32c6": ESP32_DOCS, 52 | "esp32h2": ESP32_DOCS, 53 | "esp32p4": ESP32_DOCS, 54 | "esp32c5": ESP32_DOCS, 55 | "esp32c61": ESP32_DOCS, 56 | } 57 | 58 | # Extra options required by sphinx_idf_theme 59 | project_slug = "esptool" 60 | 61 | versions_url = "./_static/esptool_versions.js" 62 | -------------------------------------------------------------------------------- /docs/en/about.rst: -------------------------------------------------------------------------------- 1 | About 2 | ===== 3 | 4 | Esptool was started by Fredrik Ahlberg (`themadinventor `_) as an unofficial community project. Later, it was maintained by Angus Gratton (`projectgus `_). It is now supported by `Espressif Systems `_. 5 | 6 | Esptool source code and this documentation are released as Free Software under GNU General Public License Version 2 or later. See `the LICENSE `_ for a copy. 7 | -------------------------------------------------------------------------------- /docs/en/advanced-topics/diag/command_packet_format.diag: -------------------------------------------------------------------------------- 1 | packetdiag command_packet_format{ 2 | colwidth = 16 3 | node_width = 50 4 | node_height = 50 5 | default_fontsize = 16 6 | 7 | 0: "0x00"; 8 | 1: "Cmd"; 9 | 2-3: "Size"; 10 | 4-7: "Checksum"; 11 | 8-15: "Data" [color = lightgrey]; 12 | 16-31: "..." [color = lightgrey]; 13 | } 14 | -------------------------------------------------------------------------------- /docs/en/advanced-topics/diag/download_procedure_chart.diag: -------------------------------------------------------------------------------- 1 | blockdiag download_procedure_diagram { 2 | node_height = 40; 3 | node_width = 150; 4 | span_width = 40; 5 | span_height = 45; 6 | default_fontsize = 12 7 | orientation = portrait; 8 | edge_layout = flowchart; 9 | default_group_color = none; 10 | 11 | // nodes 12 | start [label = "Start", shape = flowchart.terminator]; 13 | sync [label = "Synchronization", shape = box]; 14 | success_cond [label = "Success?", shape = flowchart.condition]; 15 | erase_data [label = "Erase data", shape = box]; 16 | transmit_data [label = "Transmit data", shape = box]; 17 | finish_cond [label = "Finish?", shape = flowchart.condition]; 18 | transmit_finish [label = "Transmit finish frame", shape = box]; 19 | finish [label = "Finish", shape = flowchart.terminator]; 20 | // fake nodes to adjust shape and edge label position 21 | succ_fin [shape = none]; 22 | fincon_fin [shape = none]; 23 | 24 | // edges 25 | start -> sync -> success_cond; 26 | success_cond -> erase_data [label = "Yes"]; 27 | erase_data -> transmit_data; 28 | transmit_data -> finish_cond; 29 | success_cond -- succ_fin [label = "Timeout"]; 30 | finish_cond -> transmit_finish [label = "Yes"]; 31 | finish_cond -- fincon_fin [label = "Failure"]; 32 | succ_fin -- fincon_fin; 33 | fincon_fin -> finish; 34 | transmit_finish -> finish; 35 | 36 | // group 37 | group{transmit_finish, fincon_fin}; 38 | group{erase_data, succ_fin}; 39 | } 40 | -------------------------------------------------------------------------------- /docs/en/advanced-topics/diag/firmware_image_ext_header_format.diag: -------------------------------------------------------------------------------- 1 | packetdiag command_packet_format{ 2 | colwidth = 16 3 | node_width = 50 4 | node_height = 50 5 | default_fontsize = 16 6 | 7 | 0: "WP"; 8 | 1-3: "Drive settings"; 9 | 4-5: "Chip ID"; 10 | 6: "Rev." [color = grey]; 11 | 7-8: "Min rev."; 12 | 9-10: "Max rev."; 13 | 11-14: "Reserved" [color = grey]; 14 | 15: "Hash"; 15 | } 16 | -------------------------------------------------------------------------------- /docs/en/advanced-topics/diag/firmware_image_format.diag: -------------------------------------------------------------------------------- 1 | packetdiag command_packet_format{ 2 | colwidth = 16 3 | node_width = 50 4 | node_height = 50 5 | default_fontsize = 16 6 | 7 | 0-7: "Image header"; 8 | 8-23: "Image extended header"; 9 | 24-31: "Segmets" [color = lightgrey]; 10 | 32-47: "..." [color = lightgrey]; 11 | 48-63: "Footer"; 12 | } 13 | -------------------------------------------------------------------------------- /docs/en/advanced-topics/diag/firmware_image_format_esp8266.diag: -------------------------------------------------------------------------------- 1 | packetdiag command_packet_format{ 2 | colwidth = 16 3 | node_width = 50 4 | node_height = 50 5 | default_fontsize = 16 6 | 7 | 0-7: "Image header"; 8 | 8-23: "Segmets" [color = lightgrey]; 9 | 24-31: "..." [color = lightgrey]; 10 | 32-47: "Footer"; 11 | } 12 | -------------------------------------------------------------------------------- /docs/en/advanced-topics/diag/firmware_image_header_format.diag: -------------------------------------------------------------------------------- 1 | packetdiag command_packet_format{ 2 | colwidth = 8 3 | node_width = 100 4 | node_height = 50 5 | default_fontsize = 16 6 | 7 | 0: "0xE9"; 8 | 1: "Number of\nsegments"; 9 | 2: "Flash Mode"; 10 | 3: "Flash\nsize/freq"; 11 | 4-7: "Entry point"; 12 | } 13 | -------------------------------------------------------------------------------- /docs/en/advanced-topics/diag/response_packet_format.diag: -------------------------------------------------------------------------------- 1 | packetdiag command_packet_format{ 2 | colwidth = 16 3 | node_width = 50 4 | node_height = 50 5 | default_fontsize = 16 6 | 7 | 0: "0x01"; 8 | 1: "Cmd"; 9 | 2-3: "Size"; 10 | 4-7: "Value"; 11 | 8-15: "Data" [color = lightgrey]; 12 | 16-31: "..." [color = lightgrey]; 13 | } 14 | -------------------------------------------------------------------------------- /docs/en/advanced-topics/index.rst: -------------------------------------------------------------------------------- 1 | Advanced Topics 2 | =============== 3 | 4 | This sections contains advanced topics and technical documentation useful if you're developing ``esptool`` or hacking system internals: 5 | 6 | .. toctree:: 7 | :maxdepth: 1 8 | 9 | Firmware Image Format 10 | Serial Protocol 11 | SPI Flash Modes 12 | Boot Mode Selection 13 | -------------------------------------------------------------------------------- /docs/en/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # 3 | # English Language RTD & Sphinx config file 4 | # 5 | # Uses ../conf_common.py for most non-language-specific settings. 6 | 7 | # Importing conf_common adds all the non-language-specific 8 | # parts to this conf module 9 | 10 | import datetime 11 | 12 | try: 13 | from conf_common import * # noqa: F403,F401 14 | except ImportError: 15 | import os 16 | import sys 17 | 18 | sys.path.insert(0, os.path.abspath("../")) 19 | from conf_common import * # noqa: F403,F401 20 | 21 | # General information about the project. 22 | project = "esptool.py" 23 | copyright = "2016 - {}, Espressif Systems (Shanghai) Co., Ltd".format( 24 | datetime.datetime.now().year 25 | ) 26 | autodoc_typehints_format = "short" 27 | 28 | # The language for content autogenerated by Sphinx. Refer to documentation 29 | # for a list of supported languages. 30 | language = "en" 31 | -------------------------------------------------------------------------------- /docs/en/contributing.rst: -------------------------------------------------------------------------------- 1 | .. _contribute: 2 | 3 | .. include:: ../../CONTRIBUTING.rst 4 | -------------------------------------------------------------------------------- /docs/en/espefuse/adc-info-cmd.rst: -------------------------------------------------------------------------------- 1 | .. _adc-info-cmd: 2 | 3 | Adc Info 4 | ======== 5 | 6 | The ``espefuse.py adc-info`` command displays information about ADC calibration data stored in eFuse. 7 | 8 | .. only:: esp32 9 | 10 | .. code-block:: none 11 | 12 | > espefuse.py adc-info 13 | 14 | === Run "adc-info" command === 15 | ADC VRef calibration: 1121mV 16 | 17 | .. only:: esp32c3 or esp32s2 or esp32s3 18 | 19 | .. code-block:: none 20 | 21 | > espefuse.py adc-info 22 | 23 | === Run "adc-info" command === 24 | Temperature Sensor Calibration = -2.1C 25 | 26 | ADC1 readings stored in efuse BLOCK2: 27 | MODE0 D1 reading (250mV): 76 28 | MODE0 D2 reading (600mV): 340 29 | MODE1 D1 reading (250mV): -100 30 | MODE1 D2 reading (800mV): 356 31 | MODE2 D1 reading (250mV): 116 32 | MODE2 D2 reading (1000mV): -136 33 | MODE3 D1 reading (250mV): 8 34 | MODE3 D2 reading (2000mV): 304 35 | 36 | ADC2 readings stored in efuse BLOCK2: 37 | MODE0 D1 reading (250mV): 0 38 | MODE0 D2 reading (600mV): 168 39 | MODE1 D1 reading (250mV): 0 40 | MODE1 D2 reading (800mV): 300 41 | MODE2 D1 reading (250mV): 0 42 | MODE2 D2 reading (1000mV): -404 43 | MODE3 D1 reading (250mV): 0 44 | MODE3 D2 reading (2000mV): -32 45 | 46 | .. only:: esp32c2 47 | 48 | .. code-block:: none 49 | 50 | > espefuse.py adc-info 51 | 52 | === Run "adc-info" command === 53 | RF_REF_I_BIAS_CONFIG: 0 54 | LDO_VOL_BIAS_CONFIG_LOW: 0 55 | LDO_VOL_BIAS_CONFIG_HIGH: 0 56 | PVT_LOW: 0 57 | PVT_HIGH: 0 58 | ADC_CALIBRATION_0: 0 59 | ADC_CALIBRATION_1: 0 60 | ADC_CALIBRATION_2: 0 61 | -------------------------------------------------------------------------------- /docs/en/espefuse/burn-bit-cmd.rst: -------------------------------------------------------------------------------- 1 | .. _burn-bit-cmd: 2 | 3 | Burn Bit 4 | ======== 5 | 6 | The ``espefuse.py burn-bit`` command burns bits in eFuse blocks by bit number. This is useful when the fields are not represented in the eFuse table. 7 | 8 | Positional arguments: 9 | 10 | - ``block`` - eFuse block. 11 | - ``bit number`` - Bit number in the eFuse block [0..BLK_LEN-1] (list of numbers, like 10 15 18 17 5 etc.). 12 | 13 | Optional arguments: 14 | 15 | - ``--force-write-always``. Burn it even if it looks like it is already been written, or is write protected. Note that this option can not disable write protection, or clear any bit which has already been set. 16 | 17 | Usage 18 | ----- 19 | 20 | Burning bits to BLOCK2: 21 | 22 | .. code-block:: none 23 | 24 | > espefuse.py burn-bit BLOCK2 15 16 17 18 19 20 25 | 26 | === Run "burn-bit" command === 27 | bit_number: [255]........................................................[0] 28 | BLOCK2 : 0x00000000000000000000000000000000000000000000000000000000001f8000 29 | BLOCK2 (secure_boot_v1 s) [2 ] regs_to_write: 001f8000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 30 | 31 | Check all blocks for burn... 32 | idx, BLOCK_NAME, Conclusion 33 | [02] BLOCK2 is empty, will burn the new value 34 | . 35 | This is an irreversible operation! 36 | Type 'BURN' (all capitals) to continue. 37 | BURN 38 | BURN BLOCK2 - OK (write block == read block) 39 | Reading updated efuses... 40 | Successful 41 | 42 | Burning in Multiple Blocks 43 | ^^^^^^^^^^^^^^^^^^^^^^^^^^ 44 | 45 | .. code-block:: none 46 | 47 | > espefuse.py --virt burn-bit BLOCK2 15 16 17 18 19 20 \ 48 | burn-bit BLOCK3 15 16 17 18 19 20 49 | 50 | === Run "burn-bit" command === 51 | bit_number: [255]........................................................[0] 52 | BLOCK2 : 0x00000000000000000000000000000000000000000000000000000000001f8000 53 | BLOCK2 (secure_boot_v1 s) [2 ] regs_to_write: 001f8000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 54 | 55 | Batch mode is enabled, the burn will be done at the end of the command. 56 | 57 | === Run "burn-bit" command === 58 | bit_number: [255]........................................................[0] 59 | BLOCK3 : 0x00000000000000000000000000000000000000000000000000000000001f8000 60 | BLOCK3 ( ) [3 ] regs_to_write: 001f8000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 61 | 62 | Batch mode is enabled, the burn will be done at the end of the command. 63 | 64 | Check all blocks for burn... 65 | idx, BLOCK_NAME, Conclusion 66 | [02] BLOCK2 is empty, will burn the new value 67 | [03] BLOCK3 is empty, will burn the new value 68 | . 69 | This is an irreversible operation! 70 | Type 'BURN' (all capitals) to continue. 71 | BURN 72 | BURN BLOCK3 - OK (write block == read block) 73 | BURN BLOCK2 - OK (write block == read block) 74 | Reading updated efuses... 75 | -------------------------------------------------------------------------------- /docs/en/espefuse/burn-block-data-cmd.rst: -------------------------------------------------------------------------------- 1 | .. _burn-block-data-cmd: 2 | 3 | Burn Block Data 4 | =============== 5 | 6 | The ``espefuse.py burn-block-data`` command allows writing arbitrary data (non-key data) from a file into an eFuse block, for software use. 7 | 8 | This command is available in ``espefuse.py`` v2.6 and newer. 9 | 10 | Positional arguments: 11 | 12 | * ``Name of key block`` 13 | * ``Datafile``. File containing data to burn into the eFuse block. The file size can be smaller than the eFuse block size. 14 | 15 | It can be list of blocks and datafiles (like BLOCK1 datafile1.bin BLOCK2 datafile2.bin etc.). 16 | 17 | Optional arguments: 18 | 19 | * ``--force-write-always``. Write the eFuse key even if it looks like it is already been written, or is write protected. Note that this option can't disable write protection, or clear any bit which has already been set. 20 | * ``--offset``. Byte offset in the eFuse block. 21 | 22 | **Example:** Write to eFuse BLOCK3 from binary file ``device_id.bin``, starting at eFuse byte offset 6: 23 | 24 | .. code-block:: none 25 | 26 | > espefuse.py -p PORT burn-block-data --offset 6 BLOCK3 device_id.bin 27 | 28 | === Run "burn-block-data" command === 29 | [03] BLOCK3 size=32 bytes, offset=06 - > [00 00 00 00 00 00 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 00 00 00 00 00 00 00 00 00 00]. 30 | 31 | Check all blocks for burn... 32 | idx, BLOCK_NAME, Conclusion 33 | [03] BLOCK3 is empty, will burn the new value 34 | . 35 | This is an irreversible operation! 36 | Type 'BURN' (all capitals) to continue. 37 | BURN 38 | BURN BLOCK3 - OK (write block == read block) 39 | Reading updated efuses... 40 | Successful 41 | 42 | Peculiarities 43 | ------------- 44 | 45 | 1. Data is written to the eFuse block in normal byte order (treating the eFuse block as if it was an array of bytes). It can be read back in firmware using eFuse API or from the eFuse read registers (but these reads must be always be complete register words, 4-byte aligned). 46 | 47 | .. code-block:: none 48 | 49 | > espefuse.py dump 50 | ... 51 | BLOCK3 ( ) [3 ] read_regs: 00000000 01000000 05040302 09080706 0d0c0b0a 00000f0e 00000000 00000000 52 | 53 | > espefuse.py summary 54 | .... 55 | BLOCK3 (BLOCK3): Variable Block 3 56 | = 00 00 00 00 00 00 00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f 00 00 00 00 00 00 00 00 00 00 R/W 57 | 58 | 2. Part of the eFuse block can be written at a time. The ``--offset`` argument allows writing to a byte offset inside the eFuse block itself. 59 | 3. This command is not suitable for writing key data which will be used by flash encryption or secure boot hardware, use ``burn-key`` for this. 60 | -------------------------------------------------------------------------------- /docs/en/espefuse/get-custom-mac-cmd.rst: -------------------------------------------------------------------------------- 1 | .. _get-custom-mac-cmd: 2 | 3 | Get Custom Mac 4 | ============== 5 | 6 | The ``espefuse.py get-custom-mac`` command prints the Custom MAC Address (``CUSTOM_MAC``). 7 | 8 | The chips also have a factory MAC address (eFuse name ``MAC``), which is written at the factory. It can not be changed with this tool. 9 | 10 | .. only:: esp32 11 | 12 | .. code-block:: none 13 | 14 | > espefuse.py get-custom-mac 15 | 16 | === Run "get-custom-mac" command === 17 | Custom MAC Address version 1: 48:63:92:15:72:16 (CRC 0x75 OK) 18 | 19 | If the custom MAC address is not burned, then you will see the message "Custom MAC Address is not set in the device". And in the summary, those eFuses associated with custom MAC addresses will not show up. 20 | 21 | .. only:: not esp32 22 | 23 | .. code-block:: none 24 | 25 | > espefuse.py get-custom-mac 26 | 27 | === Run "get-custom-mac" command === 28 | Custom MAC Address: 48:63:92:15:72:16 (OK) 29 | 30 | If the custom MAC address is not burned, then you will see the message "Custom MAC Address: 00:00:00:00:00:00 (OK)". 31 | -------------------------------------------------------------------------------- /docs/en/espefuse/read-write-protections-cmd.rst: -------------------------------------------------------------------------------- 1 | .. _read-write-protections-cmd: 2 | 3 | Read Write Protection 4 | ===================== 5 | 6 | There are two commands (to get the correct list of eFuse fields that can be protected, specify the chip with ``--chip``): 7 | 8 | - ``espefuse.py read-protect-efuse``. It sets read protection for given eFuse names. 9 | - ``espefuse.py write-protect-efuse``. It sets write protection for given eFuse names. 10 | 11 | Positional arguments: 12 | 13 | - eFuse name. It can receive a list of eFuse names (like EFUSE_NAME1 EFUSE_NAME2 etc.). 14 | 15 | Read protection prevents software from reading eFuse fields, only hardware can access such eFuses. Such eFuses are read as zero and the data is marked as ``??`` in this tool. 16 | 17 | Write protection prevents further changes of eFuse fields. 18 | 19 | Not all eFuses have read and write protections. See the help for these commands for the eFuse names that can be protected. 20 | 21 | eFuses are often read/write protected as a group, so protecting one of eFuse will result in some related eFuses becoming protected. The tool will show the full list of eFuses that will be protected. 22 | 23 | Read and Write Protection Status 24 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 25 | 26 | The ``R/W`` output indicates a protection status of a specific eFuse field/block: 27 | 28 | - ``-/W`` indicates that read protection is set. Value of such eFuse field will always show all-zeroes, even though hardware may use the correct value. In espefuse v2.6 and newer, read-protected eFuse values are displayed as question marks (``??``). On earlier versions, they are displayed as zeroes. 29 | 30 | .. code-block:: none 31 | 32 | BLOCK1 (BLOCK1): 33 | = ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? ?? -/W 34 | 35 | - ``R/-`` indicates that write protection is set. No further bits can be set. 36 | - ``-/-`` means both read and write protection are set. 37 | 38 | Usage 39 | ----- 40 | 41 | .. code-block:: none 42 | 43 | > espefuse.py read-protect-efuse BLOCK2 BLOCK3 MAC_VERSION 44 | 45 | === Run "read-protect-efuse" command === 46 | If Secure Boot V2 is used, BLOCK2 must be readable, please stop this operation! 47 | Permanently read-disabling efuse BLOCK2 48 | Permanently read-disabling efuses MAC_VERSION, BLOCK3 49 | Permanently read-disabling efuses MAC_VERSION, BLOCK3 50 | 51 | Check all blocks for burn... 52 | idx, BLOCK_NAME, Conclusion 53 | [00] BLOCK0 is empty, will burn the new value 54 | . 55 | This is an irreversible operation! 56 | Type 'BURN' (all capitals) to continue. 57 | BURN 58 | BURN BLOCK0 - OK (write block == read block) 59 | Reading updated efuses... 60 | Checking efuses... 61 | Successful 62 | 63 | .. code-block:: none 64 | 65 | > espefuse.py write-protect-efuse WR_DIS FLASH_CRYPT_CNT 66 | 67 | === Run "write-protect-efuse" command === 68 | Permanently write-disabling efuse WR_DIS 69 | Permanently write-disabling efuses FLASH_CRYPT_CNT, UART_DOWNLOAD_DIS 70 | 71 | Check all blocks for burn... 72 | idx, BLOCK_NAME, Conclusion 73 | [00] BLOCK0 is empty, will burn the new value 74 | . 75 | This is an irreversible operation! 76 | Type 'BURN' (all capitals) to continue. 77 | BURN 78 | BURN BLOCK0 - OK (write block == read block) 79 | Reading updated efuses... 80 | Checking efuses... 81 | Successful 82 | -------------------------------------------------------------------------------- /docs/en/esptool/entering-bootloader.rst: -------------------------------------------------------------------------------- 1 | .. _entering-the-bootloader: 2 | 3 | Entering the Bootloader 4 | ======================= 5 | 6 | Espressif chips have to be reset in a certain way in order to launch the serial bootloader, only then can ``esptool.py`` communicate with the ESP chip. 7 | 8 | On some development boards (including NodeMCU, WeMOS, HUZZAH Feather, Core Board, ESP32-WROVER-KIT), esptool can :ref:`automatically trigger a reset into the serial bootloader ` - in which case you don't need to read this section. 9 | 10 | For everyone else, three things must happen to enter the serial bootloader (firmware download mode) - a reset, required pins set correctly, and a correct strapping pin pulled low. For more information, see the detailed :ref:`Boot Mode Selection` guide. 11 | 12 | Boot Mode 13 | --------- 14 | 15 | Espressif chips choose the boot mode each time they reset. A reset event can happen in one of several ways: 16 | 17 | .. list:: 18 | 19 | * Power applied to chip. 20 | :esp8266: * The nRESET pin was low and is pulled high. 21 | * The CH_PD/EN pin ("enable") pin was low and is pulled high. 22 | 23 | .. only:: esp8266 24 | 25 | On {IDF_TARGET_NAME}, both the nRESET and CH_PD pins must be pulled high for the chip to start operating. 26 | -------------------------------------------------------------------------------- /docs/en/esptool/flasher-stub.rst: -------------------------------------------------------------------------------- 1 | .. _stub: 2 | 3 | Flasher Stub 4 | ============ 5 | 6 | ``esptool.py`` is a serial flasher utility. It communicates with the ROM bootloader in `Espressif SoCs `_ in order to load user applications or read chip data via serial port. 7 | 8 | The ROM bootloader is burned into the ESP chip during manufacturing and cannot be updated. A new version is issued only when a new chip revision is released. 9 | 10 | ``esptool.py`` works around the limitations imposed by a fixed ROM bootloader by implementing a flasher stub (also known as "stub loader" or just "stub"). It is a small application used as a temporary substitute or extension for the ROM. 11 | 12 | When ``esptool.py`` connects to a chip, it first uploads the flasher stub, which basically replaces the original bootloader. All following operations are then handled by the stub. 13 | 14 | Benefits 15 | -------- 16 | 17 | The flasher stub behaves the same as the original bootloader, but uses more heavily optimized UART routines. 18 | 19 | The main benefit is improved performance of flashing and some other operations (like reading flash). Additionally, it also allows to work around any bugs in ROM bootloaders. 20 | 21 | Disabling the Stub Loader 22 | ------------------------- 23 | 24 | There might be cases where it is necessary to disable the stub loader (e.g. debugging). To do that, run ``esptool.py`` with the ``--no-stub`` argument. All operations will then be handled by the original ROM bootloader. See the related :ref:`advanced options page `. 25 | -------------------------------------------------------------------------------- /docs/en/esptool/index.rst: -------------------------------------------------------------------------------- 1 | .. _esptool: 2 | 3 | esptool.py 4 | ========== 5 | 6 | Use ``esptool.py -h`` to see a summary of all available commands and command line options. 7 | 8 | To see all options for a particular command, append ``-h`` to the command name. ie ``esptool.py write-flash -h``. 9 | 10 | .. toctree:: 11 | :maxdepth: 1 12 | 13 | Basic Options 14 | Basic Commands 15 | Advanced Options 16 | Advanced Commands 17 | Entering the Bootloader 18 | Serial Connection 19 | Flashing Firmware 20 | Flasher Stub 21 | Flash Modes 22 | Configuration File 23 | Scripting 24 | 25 | .. only:: not esp8266 26 | 27 | Instructions for other tools bundled with esptool: 28 | 29 | * :ref:`espefuse` 30 | * :ref:`espsecure` 31 | * :ref:`esp_rfc2217_server.py ` 32 | -------------------------------------------------------------------------------- /docs/en/esptool/serial-connection.rst: -------------------------------------------------------------------------------- 1 | {IDF_TARGET_BAUD_RATE:default="115200", esp8266="74880 "} 2 | 3 | Serial Connection 4 | ================= 5 | 6 | The ROM serial bootloader of Espressif chips uses a 3.3V UART serial connection. Many development boards make the serial connections for you onboard. 7 | 8 | However, if you are wiring the chip yourself to a USB/Serial adapter or similar then the following connections must be made: 9 | 10 | +---------------------+-------------------+ 11 | | ESP Chip Pin | Serial Port Pin | 12 | +=====================+===================+ 13 | | TX | RX (receive) | 14 | +---------------------+-------------------+ 15 | | RX | TX (transmit) | 16 | +---------------------+-------------------+ 17 | | Ground | Ground | 18 | +---------------------+-------------------+ 19 | 20 | Note that TX (transmit) on the ESP chip is connected to RX (receive) on the serial port connection, and vice versa. 21 | 22 | Do not connect the chip to 5V TTL serial adapters, and especially not to "standard" RS-232 adapters! 3.3V serial only! 23 | 24 | .. _serial-port-settings: 25 | 26 | Serial Port Settings 27 | -------------------- 28 | 29 | When communicating with the {IDF_TARGET_NAME} ROM serial bootloader, the following serial port settings are recommended: 30 | 31 | +---------------------+-------------------+ 32 | | Baud rate | {IDF_TARGET_BAUD_RATE} | 33 | +---------------------+-------------------+ 34 | | Data bits | 8 | 35 | +---------------------+-------------------+ 36 | | Stop bits | 1 | 37 | +---------------------+-------------------+ 38 | | Parity | None | 39 | +---------------------+-------------------+ 40 | | Flow control | None | 41 | +---------------------+-------------------+ 42 | 43 | .. only:: esp32c2 44 | 45 | .. note:: 46 | 47 | You might experience issues when using low baud rates on {IDF_TARGET_NAME}. If you encounter any problems when connecting, please use at least 115200 or higher. 48 | 49 | .. only:: esp8266 50 | 51 | .. note:: 52 | 53 | Baud rate {IDF_TARGET_BAUD_RATE} is what the {IDF_TARGET_NAME} bootloader uses. The apps on top of the Espressif SDK (e.g. Arduino sketch) talk at 115200 if not specified otherwise. 54 | -------------------------------------------------------------------------------- /docs/en/remote-serial-ports.rst: -------------------------------------------------------------------------------- 1 | Remote Serial Ports 2 | =================== 3 | 4 | If you would like to connect to an Espressif SoC that is not directly connected to your system, you can use a remote serial port. This is useful when the chip is on a different machine, or for example when using WSL on Windows. 5 | 6 | It is possible to connect to any networked remote serial port that supports `RFC2217 `__ (Telnet) protocol. To do this, specify the serial port to esptool as ``rfc2217://:``. For example, to read information about your chip's SPI flash, run: 7 | 8 | :: 9 | 10 | esptool.py --port rfc2217://192.168.1.77:4000 flash-id 11 | 12 | Custom baud rates and DTR/RTS automatic resetting are supported over the RFC2217 protocol, the same as for a local serial port. 13 | 14 | .. _rfc2217_server: 15 | 16 | Pyserial Example Servers 17 | ------------------------ 18 | 19 | PySerial (which is a dependency of esptool) includes two RFC2217 example programs - `a single-port example `__ and a `multi-port example `__. 20 | These example servers can run on any OS that supports pyserial, and are the simplest way to connect to an Espressif SoC over the network. 21 | 22 | There is an issue with `automatic resetting due to network latency `__. In order to work around this issue, a modified version of the single-port server example called ``esp_rfc2217_server.py`` is provided with esptool. 23 | 24 | On server: 25 | 26 | :: 27 | 28 | esp_rfc2217_server.py -p 4000 /dev/ttyUSB1 29 | 30 | On client: 31 | 32 | :: 33 | 34 | esptool.py --port rfc2217://ADDRESS_OF_SERVER:4000?ign_set_control flash-id 35 | 36 | 37 | Raw Sockets 38 | ----------- 39 | 40 | For servers or hardware network/serial adapters which don't support the full RFC2217, it is also possible to specify ``--port socket://:`` syntax for a simple "raw TCP socket" protocol. 41 | 42 | These raw sockets don't support setting the baud rate or automatic resetting into the bootloader. If using this mode, don't pass the ``--baud`` option to esptool. You need to set the baud rate manually on the server, and manually reset the chip into the bootloader mode (or use some other signalling/control method to tell the server to do so). 43 | 44 | Here's a very basic example using the common Linux/macOS command line "netcat" and "stty" commands: 45 | 46 | On server: 47 | 48 | :: 49 | 50 | stty -F /dev/ttyUSB1 230400 # set baud rate 51 | nc -p 4000 -lk < /dev/ttyUSB1 > /dev/ttyUSB1 52 | 53 | On client: 54 | 55 | :: 56 | 57 | esptool.py -p socket://localhost:4000 flash-id 58 | 59 | .. note:: 60 | 61 | Using RFC2217 is strongly recommended where possible. 62 | 63 | More Details 64 | ------------ 65 | 66 | All of the remote serial port support comes via pyserial. Read more `here `__. (Please keep in mind that the link points to documentation for the most recent pyserial version. You may have an older version.) 67 | -------------------------------------------------------------------------------- /docs/en/resources.rst: -------------------------------------------------------------------------------- 1 | .. _resources: 2 | 3 | Resources 4 | ========= 5 | 6 | 7 | Useful Links 8 | ------------- 9 | 10 | * The `esp32.com forum `_ is a place to ask questions and find community resources. 11 | 12 | * Check the `Issues `_ section on GitHub if you find a bug or have a feature request. Please check existing `issues `_ before opening a new one. 13 | 14 | * Several `books `_ have been written about the ESP8266 or ESP32 series of SoCs and they are listed on `Espressif `__ web site. 15 | 16 | * If you're interested in contributing to esptool.py, please check the :ref:`contribute` page. 17 | 18 | * For additional {IDF_TARGET_NAME} product related information, please refer to the `documentation `_ section of `Espressif `__ web site. 19 | 20 | Webinars and Trainings 21 | ---------------------- 22 | 23 | Mastering the Basics of Espressif Chips: An In-Depth Look at Chip Flashing 24 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 25 | 26 | The content of this webinar is designed for developers, engineers and hobbyists interested in getting a better understanding of how to use esptool.py or other tools for the development with the ESP8266 or ESP32 series of SoCs. 27 | 28 | It offers an in-depth look at the inner mechanisms of esptool.py, including the :ref:`boot-mode` process. 29 | 30 | .. image:: https://img.youtube.com/vi/zh-Y_s4X6zs/maxresdefault.jpg 31 | :alt: Mastering the Basics of Espressif Chips: An In-Depth Look at Chip Flashing 32 | :target: https://www.youtube.com/watch?v=zh-Y_s4X6zs 33 | 34 | DevCon22: esptool.py: Espressif's Swiss Army Knife 35 | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 36 | This talk aims to show how simple, yet powerful, esptool.py is, and how to use it to tame your ESP. 37 | 38 | .. image:: https://img.youtube.com/vi/GjWGKzu3XTk/maxresdefault.jpg 39 | :alt: DevCon22: esptool.py: Espressif's Swiss Army Knife 40 | :target: https://www.youtube.com/watch?v=GjWGKzu3XTk 41 | -------------------------------------------------------------------------------- /docs/en/versions.rst: -------------------------------------------------------------------------------- 1 | .. _versions: 2 | 3 | Versions 4 | ======== 5 | 6 | Starting from ``v4.0.0``, ``esptool.py`` adopts the `semantic versioning specification `_, following the ``MAJOR.MINOR.PATCH`` version number. 7 | 8 | Major release ``v4`` is under active development, receiving new features and bugfixes, while ``v3`` only keeps receiving important bugfixes. 9 | 10 | There are no support periods defined and bugfixes are not planned, therefore it is strongly recommended to install the latest version possible. 11 | 12 | .. note:: 13 | 14 | The following information is directed mainly towards package maintainers. Regular users should always use the most recent version of ``esptool.py`` to benefit from the latest features and bugfixes. 15 | 16 | Use the Latest Esptool (Recommended) 17 | ------------------------------------ 18 | 19 | If your use case doesn't impose any constraints on ``esptool.py``, the latest release should be always used. 20 | To see the latest available version and its release notes, visit the `release page on GitHub `_. 21 | 22 | To get the latest possible version, simply define your dependency as ``esptool`` (without any release operator and a version identifier). 23 | 24 | Use the Latest Bugfix Release of a Minor Esptool Release 25 | -------------------------------------------------------- 26 | 27 | Some use cases might require a specific ``esptool.py`` version without getting new features, but with automatic bugfixes. 28 | 29 | This can be achieved by defining your dependency as ``esptool~=4.0.1`` (explicitly stating the ``MAJOR``, ``MINOR``, and ``PATCH`` numbers). 30 | This notation selects the latest version of ``esptool.py``, greater than or equal to ``v4.0.1``, but still in the ``v4.0.*`` version (this compatible release clause is approximately equivalent to the pair of comparison clauses ``>= 4.0.1``, ``== 4.0.*``). 31 | So, for example, ``v4.1.0`` won't be downloaded. More information about compatible release clauses `can be found here `_. 32 | 33 | Use the Latest Esptool Without Any Future Breaking Change 34 | --------------------------------------------------------- 35 | 36 | If you also want to get new features (instead of just bugfixes), define your version requirement as ``esptool~=4.0`` (explicitly stating only the ``MAJOR`` and ``MINOR`` numbers). This way the latest minor versions (``>= 4.0``, ``== 4.*``) are automatically installed. 37 | Backward-compatibility is still ensured, because ``esptool.py`` respects the semantic versioning specification (which states that breaking changes should occur only in ``MAJOR`` versions). 38 | 39 | Use the Previous Major Esptool Release (Only if You Cannot Upgrade) 40 | ------------------------------------------------------------------- 41 | 42 | If your use case is not compatible with the latest ``MAJOR`` release of ``esptool.py``, a previous compatible version has to be specified. 43 | This can be achieved by defining your dependency as ``esptool~=3.0`` (explicitly stating your desired ``MAJOR`` number and at least also the ``MINOR`` number, ``PATCH`` can also be specified). 44 | 45 | Use a Specific Esptool Release 46 | ------------------------------ 47 | 48 | If a very specific release is required, define your dependency as ``esptool==4.1.2``. This specific version will be used and no new features or bugfixes will be automatically installed. 49 | -------------------------------------------------------------------------------- /docs/utils.sh: -------------------------------------------------------------------------------- 1 | # Bash helper functions for adding SSH keys 2 | 3 | function add_ssh_keys() { 4 | local key_string="${1}" 5 | mkdir -p ~/.ssh 6 | chmod 700 ~/.ssh 7 | echo -n "${key_string}" >~/.ssh/id_rsa_base64 8 | base64 --decode --ignore-garbage ~/.ssh/id_rsa_base64 >~/.ssh/id_rsa 9 | chmod 600 ~/.ssh/id_rsa 10 | } 11 | 12 | function add_doc_server_ssh_keys() { 13 | local key_string="${1}" 14 | local server_url="${2}" 15 | local server_user="${3}" 16 | add_ssh_keys "${key_string}" 17 | echo -e "Host ${server_url}\n\tStrictHostKeyChecking no\n\tUser ${server_user}\n" >>~/.ssh/config 18 | } 19 | -------------------------------------------------------------------------------- /esp_rfc2217_server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # SPDX-FileCopyrightText: 2014-2024 Fredrik Ahlberg, Angus Gratton, 4 | # Espressif Systems (Shanghai) CO LTD, other contributors as noted. 5 | # 6 | # SPDX-License-Identifier: BSD-3-Clause 7 | 8 | # This executable script is a thin wrapper around the main functionality 9 | # in the esp_rfc2217_server Python package 10 | 11 | # When updating this script, please also update esptool.py, espefuse.py and espsecure.py 12 | 13 | ################################################################################### 14 | # Redirect data from a TCP/IP connection to a serial port and vice versa using RFC 2217. 15 | # 16 | # This is a modified version of rfc2217_server.py provided by the pyserial package 17 | # (pythonhosted.org/pyserial/examples.html#single-port-tcp-ip-serial-bridge-rfc-2217). 18 | # It uses a custom PortManager to properly apply the RTS & DTR signals 19 | # for resetting ESP chips. 20 | # 21 | # Run the following command on the server side to make 22 | # connection between /dev/ttyUSB1 and TCP port 4000: 23 | # 24 | # python esp_rfc2217_server.py -p 4000 /dev/ttyUSB1 25 | # 26 | # Esptool can connect to the ESP device through that server as it is 27 | # demonstrated in the following example: 28 | # 29 | # esptool.py --port rfc2217://localhost:4000?ign_set_control flash-id 30 | # 31 | 32 | import contextlib 33 | import os 34 | import sys 35 | 36 | if os.name != "nt": 37 | # Linux/macOS: remove current script directory to avoid importing this file 38 | # as a module; we want to import the installed esp_rfc2217_server module instead 39 | with contextlib.suppress(ValueError): 40 | executable_dir = os.path.dirname(sys.executable) 41 | sys.path = [ 42 | path 43 | for path in sys.path 44 | if not path.endswith(("/bin", "/sbin")) and path != executable_dir 45 | ] 46 | 47 | # Linux/macOS: delete imported module entry to force Python to load 48 | # the module from scratch; this enables importing esp_rfc2217_server module in 49 | # other Python scripts 50 | with contextlib.suppress(KeyError): 51 | del sys.modules["esp_rfc2217_server"] 52 | 53 | import esp_rfc2217_server 54 | 55 | if __name__ == "__main__": 56 | esp_rfc2217_server.main() 57 | -------------------------------------------------------------------------------- /esp_rfc2217_server/__main__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2014-2024 Fredrik Ahlberg, Angus Gratton, 2 | # Espressif Systems (Shanghai) CO LTD, other contributors as noted. 3 | # 4 | # SPDX-License-Identifier: BSD-3-Clause 5 | 6 | import esp_rfc2217_server 7 | 8 | if __name__ == "__main__": 9 | esp_rfc2217_server.main() 10 | -------------------------------------------------------------------------------- /esp_rfc2217_server/redirector.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2014-2024 Fredrik Ahlberg, Angus Gratton, 2 | # Espressif Systems (Shanghai) CO LTD, other contributors as noted. 3 | # 4 | # SPDX-License-Identifier: BSD-3-Clause 5 | import threading 6 | import time 7 | import logging 8 | import socket 9 | 10 | from esp_rfc2217_server.esp_port_manager import EspPortManager 11 | 12 | 13 | class Redirector(object): 14 | def __init__(self, serial_instance, socket, debug=False, esp32r0delay=False): 15 | self.serial = serial_instance 16 | self.socket = socket 17 | self._write_lock = threading.Lock() 18 | self.rfc2217 = EspPortManager( 19 | self.serial, 20 | self, 21 | esp32r0delay, 22 | logger=logging.getLogger("rfc2217.server") if debug else None, 23 | ) 24 | self.log = logging.getLogger("redirector") 25 | self.force_exit = False 26 | 27 | def statusline_poller(self): 28 | self.log.debug("status line poll thread started") 29 | while self.alive: 30 | time.sleep(1) 31 | self.rfc2217.check_modem_lines() 32 | self.log.debug("status line poll thread terminated") 33 | 34 | def shortcircuit(self): 35 | """connect the serial port to the TCP port by copying everything 36 | from one side to the other""" 37 | self.alive = True 38 | self.thread_read = threading.Thread(target=self.reader) 39 | self.thread_read.daemon = True 40 | self.thread_read.name = "serial->socket" 41 | self.thread_read.start() 42 | self.thread_poll = threading.Thread(target=self.statusline_poller) 43 | self.thread_poll.daemon = True 44 | self.thread_poll.name = "status line poll" 45 | self.thread_poll.start() 46 | self.writer() 47 | 48 | def reader(self): 49 | """loop forever and copy serial->socket""" 50 | self.log.debug("reader thread started") 51 | while self.alive: 52 | try: 53 | data = self.serial.read(self.serial.in_waiting or 1) 54 | if data: 55 | # escape outgoing data when needed (Telnet IAC (0xff) character) 56 | self.write(b"".join(self.rfc2217.escape(data))) 57 | except socket.error as msg: 58 | self.log.error("{}".format(msg)) 59 | # probably got disconnected 60 | break 61 | self.alive = False 62 | self.log.debug("reader thread terminated") 63 | 64 | def write(self, data): 65 | """thread safe socket write with no data escaping. used to send telnet stuff""" 66 | with self._write_lock: 67 | self.socket.sendall(data) 68 | 69 | def writer(self): 70 | """loop forever and copy socket->serial""" 71 | while self.alive: 72 | try: 73 | data = self.socket.recv(1024) 74 | if not data: 75 | break 76 | self.serial.write(b"".join(self.rfc2217.filter(data))) 77 | except socket.error as msg: 78 | self.log.error("{}".format(msg)) 79 | # probably got disconnected 80 | break 81 | self.stop() 82 | 83 | def stop(self): 84 | """Stop copying""" 85 | self.log.debug("stopping") 86 | if self.alive: 87 | self.alive = False 88 | self.thread_read.join() 89 | self.thread_poll.join() 90 | -------------------------------------------------------------------------------- /espefuse.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # SPDX-FileCopyrightText: 2014-2022 Fredrik Ahlberg, Angus Gratton, 4 | # Espressif Systems (Shanghai) CO LTD, other contributors as noted. 5 | # 6 | # SPDX-License-Identifier: GPL-2.0-or-later 7 | 8 | # This executable script is a thin wrapper around the main functionality 9 | # in the espefuse Python package 10 | 11 | # When updating this script, please also update esptool.py and espsecure.py 12 | 13 | import contextlib 14 | import os 15 | import sys 16 | 17 | if os.name != "nt": 18 | # Linux/macOS: remove current script directory to avoid importing this file 19 | # as a module; we want to import the installed espefuse module instead 20 | with contextlib.suppress(ValueError): 21 | executable_dir = os.path.dirname(sys.executable) 22 | sys.path = [ 23 | path 24 | for path in sys.path 25 | if not path.endswith(("/bin", "/sbin")) and path != executable_dir 26 | ] 27 | 28 | # Linux/macOS: delete imported module entry to force Python to load 29 | # the module from scratch; this enables importing espefuse module in 30 | # other Python scripts 31 | with contextlib.suppress(KeyError): 32 | del sys.modules["espefuse"] 33 | 34 | import espefuse 35 | 36 | if __name__ == "__main__": 37 | espefuse._main() 38 | -------------------------------------------------------------------------------- /espefuse/__main__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2016-2022 Espressif Systems (Shanghai) CO LTD 2 | # 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | 5 | import espefuse 6 | 7 | if __name__ == "__main__": 8 | espefuse._main() 9 | -------------------------------------------------------------------------------- /espefuse/efuse/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/espefuse/efuse/__init__.py -------------------------------------------------------------------------------- /espefuse/efuse/esp32/__init__.py: -------------------------------------------------------------------------------- 1 | from . import operations 2 | from .emulate_efuse_controller import EmulateEfuseController 3 | from .fields import EspEfuses 4 | 5 | commands = operations.ESP32Commands 6 | -------------------------------------------------------------------------------- /espefuse/efuse/esp32c2/__init__.py: -------------------------------------------------------------------------------- 1 | from . import operations 2 | from .emulate_efuse_controller import EmulateEfuseController 3 | from .fields import EspEfuses 4 | 5 | commands = operations.ESP32C2Commands 6 | -------------------------------------------------------------------------------- /espefuse/efuse/esp32c3/__init__.py: -------------------------------------------------------------------------------- 1 | from . import operations 2 | from .emulate_efuse_controller import EmulateEfuseController 3 | from .fields import EspEfuses 4 | 5 | commands = operations.ESP32C3Commands 6 | -------------------------------------------------------------------------------- /espefuse/efuse/esp32c3/emulate_efuse_controller.py: -------------------------------------------------------------------------------- 1 | # This file describes eFuses controller for ESP32-C3 chip 2 | # 3 | # SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD 4 | # 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | import reedsolo 8 | 9 | from .mem_definition import EfuseDefineBlocks, EfuseDefineFields, EfuseDefineRegisters 10 | from ..emulate_efuse_controller_base import EmulateEfuseControllerBase, FatalError 11 | 12 | 13 | class EmulateEfuseController(EmulateEfuseControllerBase): 14 | """The class for virtual efuse operation. Using for HOST_TEST.""" 15 | 16 | CHIP_NAME = "ESP32-C3" 17 | mem = None 18 | debug = False 19 | 20 | def __init__(self, efuse_file=None, debug=False): 21 | self.Blocks = EfuseDefineBlocks 22 | self.Fields = EfuseDefineFields(None) 23 | self.REGS = EfuseDefineRegisters 24 | super(EmulateEfuseController, self).__init__(efuse_file, debug) 25 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 26 | 27 | """ esptool method start >>""" 28 | 29 | def get_major_chip_version(self): 30 | return 0 31 | 32 | def get_minor_chip_version(self): 33 | return 4 34 | 35 | def get_crystal_freq(self): 36 | return 40 # MHz (common for all chips) 37 | 38 | def get_security_info(self): 39 | return { 40 | "flags": 0, 41 | "flash_crypt_cnt": 0, 42 | "key_purposes": 0, 43 | "chip_id": 0, 44 | "api_version": 0, 45 | } 46 | 47 | """ << esptool method end """ 48 | 49 | def handle_writing_event(self, addr, value): 50 | if addr == self.REGS.EFUSE_CMD_REG: 51 | if value & self.REGS.EFUSE_PGM_CMD: 52 | self.copy_blocks_wr_regs_to_rd_regs(updated_block=(value >> 2) & 0xF) 53 | self.clean_blocks_wr_regs() 54 | self.check_rd_protection_area() 55 | self.write_reg(addr, 0) 56 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 57 | elif value == self.REGS.EFUSE_READ_CMD: 58 | self.write_reg(addr, 0) 59 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 60 | self.save_to_file() 61 | 62 | def get_bitlen_of_block(self, blk, wr=False): 63 | if blk.id == 0: 64 | if wr: 65 | return 32 * 8 66 | else: 67 | return 32 * blk.len 68 | else: 69 | if wr: 70 | rs_coding = 32 * 3 71 | return 32 * 8 + rs_coding 72 | else: 73 | return 32 * blk.len 74 | 75 | def handle_coding_scheme(self, blk, data): 76 | if blk.id != 0: 77 | # CODING_SCHEME RS applied only for all blocks except BLK0. 78 | coded_bytes = 12 79 | data.pos = coded_bytes * 8 80 | plain_data = data.readlist("32*uint:8")[::-1] 81 | # takes 32 bytes 82 | # apply RS encoding 83 | rs = reedsolo.RSCodec(coded_bytes) 84 | # 32 byte of data + 12 bytes RS 85 | calc_encoded_data = list(rs.encode([x for x in plain_data])) 86 | data.pos = 0 87 | if calc_encoded_data != data.readlist("44*uint:8")[::-1]: 88 | raise FatalError("Error in coding scheme data") 89 | data = data[coded_bytes * 8 :] 90 | if blk.len < 8: 91 | data = data[(8 - blk.len) * 32 :] 92 | return data 93 | -------------------------------------------------------------------------------- /espefuse/efuse/esp32c5/__init__.py: -------------------------------------------------------------------------------- 1 | from . import operations 2 | from .emulate_efuse_controller import EmulateEfuseController 3 | from .fields import EspEfuses 4 | 5 | commands = operations.ESP32C5Commands 6 | -------------------------------------------------------------------------------- /espefuse/efuse/esp32c5/emulate_efuse_controller.py: -------------------------------------------------------------------------------- 1 | # This file describes eFuses controller for ESP32-C5 chip 2 | # 3 | # SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD 4 | # 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | import reedsolo 8 | 9 | from .mem_definition import EfuseDefineBlocks, EfuseDefineFields, EfuseDefineRegisters 10 | from ..emulate_efuse_controller_base import EmulateEfuseControllerBase, FatalError 11 | 12 | 13 | class EmulateEfuseController(EmulateEfuseControllerBase): 14 | """The class for virtual efuse operation. Using for HOST_TEST.""" 15 | 16 | CHIP_NAME = "ESP32-C5" 17 | mem = None 18 | debug = False 19 | 20 | def __init__(self, efuse_file=None, debug=False): 21 | self.Blocks = EfuseDefineBlocks 22 | self.Fields = EfuseDefineFields(None) 23 | self.REGS = EfuseDefineRegisters 24 | super(EmulateEfuseController, self).__init__(efuse_file, debug) 25 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 26 | 27 | """ esptool method start >>""" 28 | 29 | def get_major_chip_version(self): 30 | return 0 31 | 32 | def get_minor_chip_version(self): 33 | return 0 34 | 35 | def get_crystal_freq(self): 36 | return 40 # MHz (common for all chips) 37 | 38 | def get_security_info(self): 39 | return { 40 | "flags": 0, 41 | "flash_crypt_cnt": 0, 42 | "key_purposes": 0, 43 | "chip_id": 0, 44 | "api_version": 0, 45 | } 46 | 47 | """ << esptool method end """ 48 | 49 | def handle_writing_event(self, addr, value): 50 | if addr == self.REGS.EFUSE_CMD_REG: 51 | if value & self.REGS.EFUSE_PGM_CMD: 52 | self.copy_blocks_wr_regs_to_rd_regs(updated_block=(value >> 2) & 0xF) 53 | self.clean_blocks_wr_regs() 54 | self.check_rd_protection_area() 55 | self.write_reg(addr, 0) 56 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 57 | elif value == self.REGS.EFUSE_READ_CMD: 58 | self.write_reg(addr, 0) 59 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 60 | self.save_to_file() 61 | 62 | def get_bitlen_of_block(self, blk, wr=False): 63 | if blk.id == 0: 64 | if wr: 65 | return 32 * 8 66 | else: 67 | return 32 * blk.len 68 | else: 69 | if wr: 70 | rs_coding = 32 * 3 71 | return 32 * 8 + rs_coding 72 | else: 73 | return 32 * blk.len 74 | 75 | def handle_coding_scheme(self, blk, data): 76 | if blk.id != 0: 77 | # CODING_SCHEME RS applied only for all blocks except BLK0. 78 | coded_bytes = 12 79 | data.pos = coded_bytes * 8 80 | plain_data = data.readlist("32*uint:8")[::-1] 81 | # takes 32 bytes 82 | # apply RS encoding 83 | rs = reedsolo.RSCodec(coded_bytes) 84 | # 32 byte of data + 12 bytes RS 85 | calc_encoded_data = list(rs.encode([x for x in plain_data])) 86 | data.pos = 0 87 | if calc_encoded_data != data.readlist("44*uint:8")[::-1]: 88 | raise FatalError("Error in coding scheme data") 89 | data = data[coded_bytes * 8 :] 90 | if blk.len < 8: 91 | data = data[(8 - blk.len) * 32 :] 92 | return data 93 | -------------------------------------------------------------------------------- /espefuse/efuse/esp32c6/__init__.py: -------------------------------------------------------------------------------- 1 | from . import operations 2 | from .emulate_efuse_controller import EmulateEfuseController 3 | from .fields import EspEfuses 4 | 5 | commands = operations.ESP32C6Commands 6 | -------------------------------------------------------------------------------- /espefuse/efuse/esp32c6/emulate_efuse_controller.py: -------------------------------------------------------------------------------- 1 | # This file describes eFuses controller for ESP32-C6 chip 2 | # 3 | # SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD 4 | # 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | import reedsolo 8 | 9 | from .mem_definition import EfuseDefineBlocks, EfuseDefineFields, EfuseDefineRegisters 10 | from ..emulate_efuse_controller_base import EmulateEfuseControllerBase, FatalError 11 | 12 | 13 | class EmulateEfuseController(EmulateEfuseControllerBase): 14 | """The class for virtual efuse operation. Using for HOST_TEST.""" 15 | 16 | CHIP_NAME = "ESP32-C6" 17 | mem = None 18 | debug = False 19 | 20 | def __init__(self, efuse_file=None, debug=False): 21 | self.Blocks = EfuseDefineBlocks 22 | self.Fields = EfuseDefineFields(None) 23 | self.REGS = EfuseDefineRegisters 24 | super(EmulateEfuseController, self).__init__(efuse_file, debug) 25 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 26 | 27 | """ esptool method start >>""" 28 | 29 | def get_major_chip_version(self): 30 | return 0 31 | 32 | def get_minor_chip_version(self): 33 | return 0 34 | 35 | def get_crystal_freq(self): 36 | return 40 # MHz (common for all chips) 37 | 38 | def get_security_info(self): 39 | return { 40 | "flags": 0, 41 | "flash_crypt_cnt": 0, 42 | "key_purposes": 0, 43 | "chip_id": 0, 44 | "api_version": 0, 45 | } 46 | 47 | """ << esptool method end """ 48 | 49 | def handle_writing_event(self, addr, value): 50 | if addr == self.REGS.EFUSE_CMD_REG: 51 | if value & self.REGS.EFUSE_PGM_CMD: 52 | self.copy_blocks_wr_regs_to_rd_regs(updated_block=(value >> 2) & 0xF) 53 | self.clean_blocks_wr_regs() 54 | self.check_rd_protection_area() 55 | self.write_reg(addr, 0) 56 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 57 | elif value == self.REGS.EFUSE_READ_CMD: 58 | self.write_reg(addr, 0) 59 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 60 | self.save_to_file() 61 | 62 | def get_bitlen_of_block(self, blk, wr=False): 63 | if blk.id == 0: 64 | if wr: 65 | return 32 * 8 66 | else: 67 | return 32 * blk.len 68 | else: 69 | if wr: 70 | rs_coding = 32 * 3 71 | return 32 * 8 + rs_coding 72 | else: 73 | return 32 * blk.len 74 | 75 | def handle_coding_scheme(self, blk, data): 76 | if blk.id != 0: 77 | # CODING_SCHEME RS applied only for all blocks except BLK0. 78 | coded_bytes = 12 79 | data.pos = coded_bytes * 8 80 | plain_data = data.readlist("32*uint:8")[::-1] 81 | # takes 32 bytes 82 | # apply RS encoding 83 | rs = reedsolo.RSCodec(coded_bytes) 84 | # 32 byte of data + 12 bytes RS 85 | calc_encoded_data = list(rs.encode([x for x in plain_data])) 86 | data.pos = 0 87 | if calc_encoded_data != data.readlist("44*uint:8")[::-1]: 88 | raise FatalError("Error in coding scheme data") 89 | data = data[coded_bytes * 8 :] 90 | if blk.len < 8: 91 | data = data[(8 - blk.len) * 32 :] 92 | return data 93 | -------------------------------------------------------------------------------- /espefuse/efuse/esp32c61/__init__.py: -------------------------------------------------------------------------------- 1 | from . import operations 2 | from .emulate_efuse_controller import EmulateEfuseController 3 | from .fields import EspEfuses 4 | 5 | commands = operations.ESP32C61Commands 6 | -------------------------------------------------------------------------------- /espefuse/efuse/esp32c61/emulate_efuse_controller.py: -------------------------------------------------------------------------------- 1 | # This file describes eFuses controller for ESP32-C61 chip 2 | # 3 | # SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD 4 | # 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | import reedsolo 8 | 9 | from .mem_definition import EfuseDefineBlocks, EfuseDefineFields, EfuseDefineRegisters 10 | from ..emulate_efuse_controller_base import EmulateEfuseControllerBase, FatalError 11 | 12 | 13 | class EmulateEfuseController(EmulateEfuseControllerBase): 14 | """The class for virtual efuse operation. Using for HOST_TEST.""" 15 | 16 | CHIP_NAME = "ESP32-C61" 17 | mem = None 18 | debug = False 19 | 20 | def __init__(self, efuse_file=None, debug=False): 21 | self.Blocks = EfuseDefineBlocks 22 | self.Fields = EfuseDefineFields(None) 23 | self.REGS = EfuseDefineRegisters 24 | super(EmulateEfuseController, self).__init__(efuse_file, debug) 25 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 26 | 27 | """ esptool method start >>""" 28 | 29 | def get_major_chip_version(self): 30 | return 0 31 | 32 | def get_minor_chip_version(self): 33 | return 0 34 | 35 | def get_crystal_freq(self): 36 | return 40 # MHz (common for all chips) 37 | 38 | def get_security_info(self): 39 | return { 40 | "flags": 0, 41 | "flash_crypt_cnt": 0, 42 | "key_purposes": 0, 43 | "chip_id": 0, 44 | "api_version": 0, 45 | } 46 | 47 | """ << esptool method end """ 48 | 49 | def handle_writing_event(self, addr, value): 50 | if addr == self.REGS.EFUSE_CMD_REG: 51 | if value & self.REGS.EFUSE_PGM_CMD: 52 | self.copy_blocks_wr_regs_to_rd_regs(updated_block=(value >> 2) & 0xF) 53 | self.clean_blocks_wr_regs() 54 | self.check_rd_protection_area() 55 | self.write_reg(addr, 0) 56 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 57 | elif value == self.REGS.EFUSE_READ_CMD: 58 | self.write_reg(addr, 0) 59 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 60 | self.save_to_file() 61 | 62 | def get_bitlen_of_block(self, blk, wr=False): 63 | if blk.id == 0: 64 | if wr: 65 | return 32 * 8 66 | else: 67 | return 32 * blk.len 68 | else: 69 | if wr: 70 | rs_coding = 32 * 3 71 | return 32 * 8 + rs_coding 72 | else: 73 | return 32 * blk.len 74 | 75 | def handle_coding_scheme(self, blk, data): 76 | if blk.id != 0: 77 | # CODING_SCHEME RS applied only for all blocks except BLK0. 78 | coded_bytes = 12 79 | data.pos = coded_bytes * 8 80 | plain_data = data.readlist("32*uint:8")[::-1] 81 | # takes 32 bytes 82 | # apply RS encoding 83 | rs = reedsolo.RSCodec(coded_bytes) 84 | # 32 byte of data + 12 bytes RS 85 | calc_encoded_data = list(rs.encode([x for x in plain_data])) 86 | data.pos = 0 87 | if calc_encoded_data != data.readlist("44*uint:8")[::-1]: 88 | raise FatalError("Error in coding scheme data") 89 | data = data[coded_bytes * 8 :] 90 | if blk.len < 8: 91 | data = data[(8 - blk.len) * 32 :] 92 | return data 93 | -------------------------------------------------------------------------------- /espefuse/efuse/esp32h2/__init__.py: -------------------------------------------------------------------------------- 1 | from . import operations 2 | from .emulate_efuse_controller import EmulateEfuseController 3 | from .fields import EspEfuses 4 | 5 | commands = operations.ESP32H2Commands 6 | -------------------------------------------------------------------------------- /espefuse/efuse/esp32h2/emulate_efuse_controller.py: -------------------------------------------------------------------------------- 1 | # This file describes eFuses controller for ESP32-H2 chip 2 | # 3 | # SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD 4 | # 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | import reedsolo 8 | 9 | from .mem_definition import EfuseDefineBlocks, EfuseDefineFields, EfuseDefineRegisters 10 | from ..emulate_efuse_controller_base import EmulateEfuseControllerBase, FatalError 11 | 12 | 13 | class EmulateEfuseController(EmulateEfuseControllerBase): 14 | """The class for virtual efuse operation. Using for HOST_TEST.""" 15 | 16 | CHIP_NAME = "ESP32-H2" 17 | mem = None 18 | debug = False 19 | 20 | def __init__(self, efuse_file=None, debug=False): 21 | self.Blocks = EfuseDefineBlocks 22 | self.Fields = EfuseDefineFields(None) 23 | self.REGS = EfuseDefineRegisters 24 | super(EmulateEfuseController, self).__init__(efuse_file, debug) 25 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 26 | 27 | """ esptool method start >>""" 28 | 29 | def get_major_chip_version(self): 30 | return 0 31 | 32 | def get_minor_chip_version(self): 33 | return 0 34 | 35 | def get_crystal_freq(self): 36 | return 32 # MHz 37 | 38 | def get_security_info(self): 39 | return { 40 | "flags": 0, 41 | "flash_crypt_cnt": 0, 42 | "key_purposes": 0, 43 | "chip_id": 0, 44 | "api_version": 0, 45 | } 46 | 47 | """ << esptool method end """ 48 | 49 | def handle_writing_event(self, addr, value): 50 | if addr == self.REGS.EFUSE_CMD_REG: 51 | if value & self.REGS.EFUSE_PGM_CMD: 52 | self.copy_blocks_wr_regs_to_rd_regs(updated_block=(value >> 2) & 0xF) 53 | self.clean_blocks_wr_regs() 54 | self.check_rd_protection_area() 55 | self.write_reg(addr, 0) 56 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 57 | elif value == self.REGS.EFUSE_READ_CMD: 58 | self.write_reg(addr, 0) 59 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 60 | self.save_to_file() 61 | 62 | def get_bitlen_of_block(self, blk, wr=False): 63 | if blk.id == 0: 64 | if wr: 65 | return 32 * 8 66 | else: 67 | return 32 * blk.len 68 | else: 69 | if wr: 70 | rs_coding = 32 * 3 71 | return 32 * 8 + rs_coding 72 | else: 73 | return 32 * blk.len 74 | 75 | def handle_coding_scheme(self, blk, data): 76 | if blk.id != 0: 77 | # CODING_SCHEME RS applied only for all blocks except BLK0. 78 | coded_bytes = 12 79 | data.pos = coded_bytes * 8 80 | plain_data = data.readlist("32*uint:8")[::-1] 81 | # takes 32 bytes 82 | # apply RS encoding 83 | rs = reedsolo.RSCodec(coded_bytes) 84 | # 32 byte of data + 12 bytes RS 85 | calc_encoded_data = list(rs.encode([x for x in plain_data])) 86 | data.pos = 0 87 | if calc_encoded_data != data.readlist("44*uint:8")[::-1]: 88 | raise FatalError("Error in coding scheme data") 89 | data = data[coded_bytes * 8 :] 90 | if blk.len < 8: 91 | data = data[(8 - blk.len) * 32 :] 92 | return data 93 | -------------------------------------------------------------------------------- /espefuse/efuse/esp32h21/__init__.py: -------------------------------------------------------------------------------- 1 | from . import operations 2 | from .emulate_efuse_controller import EmulateEfuseController 3 | from .fields import EspEfuses 4 | 5 | commands = operations.ESP32H21Commands 6 | -------------------------------------------------------------------------------- /espefuse/efuse/esp32h21/emulate_efuse_controller.py: -------------------------------------------------------------------------------- 1 | # This file describes eFuses controller for ESP32-H21 chip 2 | # 3 | # SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD 4 | # 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | import reedsolo 8 | 9 | from .mem_definition import EfuseDefineBlocks, EfuseDefineFields, EfuseDefineRegisters 10 | from ..emulate_efuse_controller_base import EmulateEfuseControllerBase, FatalError 11 | 12 | 13 | class EmulateEfuseController(EmulateEfuseControllerBase): 14 | """The class for virtual efuse operation. Using for HOST_TEST.""" 15 | 16 | CHIP_NAME = "ESP32-H21" 17 | mem = None 18 | debug = False 19 | 20 | def __init__(self, efuse_file=None, debug=False): 21 | self.Blocks = EfuseDefineBlocks 22 | self.Fields = EfuseDefineFields(None) 23 | self.REGS = EfuseDefineRegisters 24 | super(EmulateEfuseController, self).__init__(efuse_file, debug) 25 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 26 | 27 | """ esptool method start >>""" 28 | 29 | def get_major_chip_version(self): 30 | return 0 31 | 32 | def get_minor_chip_version(self): 33 | return 0 34 | 35 | def get_crystal_freq(self): 36 | return 32 # MHz 37 | 38 | def get_security_info(self): 39 | return { 40 | "flags": 0, 41 | "flash_crypt_cnt": 0, 42 | "key_purposes": 0, 43 | "chip_id": 0, 44 | "api_version": 0, 45 | } 46 | 47 | """ << esptool method end """ 48 | 49 | def handle_writing_event(self, addr, value): 50 | if addr == self.REGS.EFUSE_CMD_REG: 51 | if value & self.REGS.EFUSE_PGM_CMD: 52 | self.copy_blocks_wr_regs_to_rd_regs(updated_block=(value >> 2) & 0xF) 53 | self.clean_blocks_wr_regs() 54 | self.check_rd_protection_area() 55 | self.write_reg(addr, 0) 56 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 57 | elif value == self.REGS.EFUSE_READ_CMD: 58 | self.write_reg(addr, 0) 59 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 60 | self.save_to_file() 61 | 62 | def get_bitlen_of_block(self, blk, wr=False): 63 | if blk.id == 0: 64 | if wr: 65 | return 32 * 8 66 | else: 67 | return 32 * blk.len 68 | else: 69 | if wr: 70 | rs_coding = 32 * 3 71 | return 32 * 8 + rs_coding 72 | else: 73 | return 32 * blk.len 74 | 75 | def handle_coding_scheme(self, blk, data): 76 | if blk.id != 0: 77 | # CODING_SCHEME RS applied only for all blocks except BLK0. 78 | coded_bytes = 12 79 | data.pos = coded_bytes * 8 80 | plain_data = data.readlist("32*uint:8")[::-1] 81 | # takes 32 bytes 82 | # apply RS encoding 83 | rs = reedsolo.RSCodec(coded_bytes) 84 | # 32 byte of data + 12 bytes RS 85 | calc_encoded_data = list(rs.encode([x for x in plain_data])) 86 | data.pos = 0 87 | if calc_encoded_data != data.readlist("44*uint:8")[::-1]: 88 | raise FatalError("Error in coding scheme data") 89 | data = data[coded_bytes * 8 :] 90 | if blk.len < 8: 91 | data = data[(8 - blk.len) * 32 :] 92 | return data 93 | -------------------------------------------------------------------------------- /espefuse/efuse/esp32h4/__init__.py: -------------------------------------------------------------------------------- 1 | from . import operations 2 | from .emulate_efuse_controller import EmulateEfuseController 3 | from .fields import EspEfuses 4 | 5 | commands = operations.ESP32H4Commands 6 | -------------------------------------------------------------------------------- /espefuse/efuse/esp32h4/emulate_efuse_controller.py: -------------------------------------------------------------------------------- 1 | # This file describes eFuses controller for ESP32-H4 chip 2 | # 3 | # SPDX-FileCopyrightText: 2025 Espressif Systems (Shanghai) CO LTD 4 | # 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | import reedsolo 8 | 9 | from .mem_definition import EfuseDefineBlocks, EfuseDefineFields, EfuseDefineRegisters 10 | from ..emulate_efuse_controller_base import EmulateEfuseControllerBase, FatalError 11 | 12 | 13 | class EmulateEfuseController(EmulateEfuseControllerBase): 14 | """The class for virtual efuse operation. Using for HOST_TEST.""" 15 | 16 | CHIP_NAME = "ESP32-H4" 17 | mem = None 18 | debug = False 19 | 20 | def __init__(self, efuse_file=None, debug=False): 21 | self.Blocks = EfuseDefineBlocks 22 | self.Fields = EfuseDefineFields(None) 23 | self.REGS = EfuseDefineRegisters 24 | super(EmulateEfuseController, self).__init__(efuse_file, debug) 25 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 26 | 27 | """ esptool method start >>""" 28 | 29 | def get_major_chip_version(self): 30 | return 0 31 | 32 | def get_minor_chip_version(self): 33 | return 0 34 | 35 | def get_crystal_freq(self): 36 | return 32 # MHz 37 | 38 | def get_security_info(self): 39 | return { 40 | "flags": 0, 41 | "flash_crypt_cnt": 0, 42 | "key_purposes": 0, 43 | "chip_id": 0, 44 | "api_version": 0, 45 | } 46 | 47 | """ << esptool method end """ 48 | 49 | def handle_writing_event(self, addr, value): 50 | if addr == self.REGS.EFUSE_CMD_REG: 51 | if value & self.REGS.EFUSE_PGM_CMD: 52 | self.copy_blocks_wr_regs_to_rd_regs(updated_block=(value >> 2) & 0xF) 53 | self.clean_blocks_wr_regs() 54 | self.check_rd_protection_area() 55 | self.write_reg(addr, 0) 56 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 57 | elif value == self.REGS.EFUSE_READ_CMD: 58 | self.write_reg(addr, 0) 59 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 60 | self.save_to_file() 61 | 62 | def get_bitlen_of_block(self, blk, wr=False): 63 | if blk.id == 0: 64 | if wr: 65 | return 32 * 8 66 | else: 67 | return 32 * blk.len 68 | else: 69 | if wr: 70 | rs_coding = 32 * 3 71 | return 32 * 8 + rs_coding 72 | else: 73 | return 32 * blk.len 74 | 75 | def handle_coding_scheme(self, blk, data): 76 | if blk.id != 0: 77 | # CODING_SCHEME RS applied only for all blocks except BLK0. 78 | coded_bytes = 12 79 | data.pos = coded_bytes * 8 80 | plain_data = data.readlist("32*uint:8")[::-1] 81 | # takes 32 bytes 82 | # apply RS encoding 83 | rs = reedsolo.RSCodec(coded_bytes) 84 | # 32 byte of data + 12 bytes RS 85 | calc_encoded_data = list(rs.encode([x for x in plain_data])) 86 | data.pos = 0 87 | if calc_encoded_data != data.readlist("44*uint:8")[::-1]: 88 | raise FatalError("Error in coding scheme data") 89 | data = data[coded_bytes * 8 :] 90 | if blk.len < 8: 91 | data = data[(8 - blk.len) * 32 :] 92 | return data 93 | -------------------------------------------------------------------------------- /espefuse/efuse/esp32p4/__init__.py: -------------------------------------------------------------------------------- 1 | from . import operations 2 | from .emulate_efuse_controller import EmulateEfuseController 3 | from .fields import EspEfuses 4 | 5 | commands = operations.ESP32P4Commands 6 | -------------------------------------------------------------------------------- /espefuse/efuse/esp32p4/emulate_efuse_controller.py: -------------------------------------------------------------------------------- 1 | # This file describes eFuses controller for ESP32-P4 chip 2 | # 3 | # SPDX-FileCopyrightText: 2023 Espressif Systems (Shanghai) CO LTD 4 | # 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | import reedsolo 8 | 9 | from .mem_definition import EfuseDefineBlocks, EfuseDefineFields, EfuseDefineRegisters 10 | from ..emulate_efuse_controller_base import EmulateEfuseControllerBase, FatalError 11 | 12 | 13 | class EmulateEfuseController(EmulateEfuseControllerBase): 14 | """The class for virtual efuse operation. Using for HOST_TEST.""" 15 | 16 | CHIP_NAME = "ESP32-P4" 17 | mem = None 18 | debug = False 19 | 20 | def __init__(self, efuse_file=None, debug=False): 21 | self.Blocks = EfuseDefineBlocks 22 | self.Fields = EfuseDefineFields(None) 23 | self.REGS = EfuseDefineRegisters 24 | super(EmulateEfuseController, self).__init__(efuse_file, debug) 25 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 26 | 27 | """ esptool method start >>""" 28 | 29 | def get_major_chip_version(self): 30 | return 0 31 | 32 | def get_minor_chip_version(self): 33 | return 0 34 | 35 | def get_crystal_freq(self): 36 | return 40 # MHz (common for all chips) 37 | 38 | def get_security_info(self): 39 | return { 40 | "flags": 0, 41 | "flash_crypt_cnt": 0, 42 | "key_purposes": 0, 43 | "chip_id": 0, 44 | "api_version": 0, 45 | } 46 | 47 | """ << esptool method end """ 48 | 49 | def handle_writing_event(self, addr, value): 50 | if addr == self.REGS.EFUSE_CMD_REG: 51 | if value & self.REGS.EFUSE_PGM_CMD: 52 | self.copy_blocks_wr_regs_to_rd_regs(updated_block=(value >> 2) & 0xF) 53 | self.clean_blocks_wr_regs() 54 | self.check_rd_protection_area() 55 | self.write_reg(addr, 0) 56 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 57 | elif value == self.REGS.EFUSE_READ_CMD: 58 | self.write_reg(addr, 0) 59 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 60 | self.save_to_file() 61 | 62 | def get_bitlen_of_block(self, blk, wr=False): 63 | if blk.id == 0: 64 | if wr: 65 | return 32 * 8 66 | else: 67 | return 32 * blk.len 68 | else: 69 | if wr: 70 | rs_coding = 32 * 3 71 | return 32 * 8 + rs_coding 72 | else: 73 | return 32 * blk.len 74 | 75 | def handle_coding_scheme(self, blk, data): 76 | if blk.id != 0: 77 | # CODING_SCHEME RS applied only for all blocks except BLK0. 78 | coded_bytes = 12 79 | data.pos = coded_bytes * 8 80 | plain_data = data.readlist("32*uint:8")[::-1] 81 | # takes 32 bytes 82 | # apply RS encoding 83 | rs = reedsolo.RSCodec(coded_bytes) 84 | # 32 byte of data + 12 bytes RS 85 | calc_encoded_data = list(rs.encode([x for x in plain_data])) 86 | data.pos = 0 87 | if calc_encoded_data != data.readlist("44*uint:8")[::-1]: 88 | raise FatalError("Error in coding scheme data") 89 | data = data[coded_bytes * 8 :] 90 | if blk.len < 8: 91 | data = data[(8 - blk.len) * 32 :] 92 | return data 93 | -------------------------------------------------------------------------------- /espefuse/efuse/esp32s2/__init__.py: -------------------------------------------------------------------------------- 1 | from . import operations 2 | from .emulate_efuse_controller import EmulateEfuseController 3 | from .fields import EspEfuses 4 | 5 | commands = operations.ESP32S2Commands 6 | -------------------------------------------------------------------------------- /espefuse/efuse/esp32s2/emulate_efuse_controller.py: -------------------------------------------------------------------------------- 1 | # This file describes eFuses controller for ESP32-S2 chip 2 | # 3 | # SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD 4 | # 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | import reedsolo 8 | 9 | from .mem_definition import EfuseDefineBlocks, EfuseDefineFields, EfuseDefineRegisters 10 | from ..emulate_efuse_controller_base import EmulateEfuseControllerBase, FatalError 11 | 12 | 13 | class EmulateEfuseController(EmulateEfuseControllerBase): 14 | """The class for virtual efuse operation. Using for HOST_TEST.""" 15 | 16 | CHIP_NAME = "ESP32-S2" 17 | mem = None 18 | debug = False 19 | 20 | def __init__(self, efuse_file=None, debug=False): 21 | self.Blocks = EfuseDefineBlocks 22 | self.Fields = EfuseDefineFields(None) 23 | self.REGS = EfuseDefineRegisters 24 | super(EmulateEfuseController, self).__init__(efuse_file, debug) 25 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 26 | 27 | """ esptool method start >>""" 28 | 29 | def get_major_chip_version(self): 30 | return 1 31 | 32 | def get_minor_chip_version(self): 33 | return 0 34 | 35 | def get_crystal_freq(self): 36 | return 40 # MHz (common for all chips) 37 | 38 | def get_security_info(self): 39 | return { 40 | "flags": 0, 41 | "flash_crypt_cnt": 0, 42 | "key_purposes": 0, 43 | "chip_id": None, 44 | "api_version": None, 45 | } 46 | 47 | """ << esptool method end """ 48 | 49 | def handle_writing_event(self, addr, value): 50 | if addr == self.REGS.EFUSE_CMD_REG: 51 | if value & self.REGS.EFUSE_PGM_CMD: 52 | self.copy_blocks_wr_regs_to_rd_regs(updated_block=(value >> 2) & 0xF) 53 | self.clean_blocks_wr_regs() 54 | self.check_rd_protection_area() 55 | self.write_reg(addr, 0) 56 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 57 | elif value == self.REGS.EFUSE_READ_CMD: 58 | self.write_reg(addr, 0) 59 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 60 | self.save_to_file() 61 | 62 | def get_bitlen_of_block(self, blk, wr=False): 63 | if blk.id == 0: 64 | if wr: 65 | return 32 * 8 66 | else: 67 | return 32 * blk.len 68 | else: 69 | if wr: 70 | rs_coding = 32 * 3 71 | return 32 * 8 + rs_coding 72 | else: 73 | return 32 * blk.len 74 | 75 | def handle_coding_scheme(self, blk, data): 76 | if blk.id != 0: 77 | # CODING_SCHEME RS applied only for all blocks except BLK0. 78 | coded_bytes = 12 79 | data.pos = coded_bytes * 8 80 | plain_data = data.readlist("32*uint:8")[::-1] 81 | # takes 32 bytes 82 | # apply RS encoding 83 | rs = reedsolo.RSCodec(coded_bytes) 84 | # 32 byte of data + 12 bytes RS 85 | calc_encoded_data = list(rs.encode([x for x in plain_data])) 86 | data.pos = 0 87 | if calc_encoded_data != data.readlist("44*uint:8")[::-1]: 88 | raise FatalError("Error in coding scheme data") 89 | data = data[coded_bytes * 8 :] 90 | if blk.len < 8: 91 | data = data[(8 - blk.len) * 32 :] 92 | return data 93 | -------------------------------------------------------------------------------- /espefuse/efuse/esp32s3/__init__.py: -------------------------------------------------------------------------------- 1 | from . import operations 2 | from .emulate_efuse_controller import EmulateEfuseController 3 | from .fields import EspEfuses 4 | 5 | commands = operations.ESP32S3Commands 6 | -------------------------------------------------------------------------------- /espefuse/efuse/esp32s3/emulate_efuse_controller.py: -------------------------------------------------------------------------------- 1 | # This file describes eFuses controller for ESP32-S3 chip 2 | # 3 | # SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD 4 | # 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | import reedsolo 8 | 9 | from .mem_definition import EfuseDefineBlocks, EfuseDefineFields, EfuseDefineRegisters 10 | from ..emulate_efuse_controller_base import EmulateEfuseControllerBase, FatalError 11 | 12 | 13 | class EmulateEfuseController(EmulateEfuseControllerBase): 14 | """The class for virtual efuse operation. Using for HOST_TEST.""" 15 | 16 | CHIP_NAME = "ESP32-S3" 17 | mem = None 18 | debug = False 19 | 20 | def __init__(self, efuse_file=None, debug=False): 21 | self.Blocks = EfuseDefineBlocks 22 | self.Fields = EfuseDefineFields(None) 23 | self.REGS = EfuseDefineRegisters 24 | super(EmulateEfuseController, self).__init__(efuse_file, debug) 25 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 26 | 27 | """ esptool method start >>""" 28 | 29 | def get_major_chip_version(self): 30 | return 0 31 | 32 | def get_minor_chip_version(self): 33 | return 2 34 | 35 | def get_crystal_freq(self): 36 | return 40 # MHz (common for all chips) 37 | 38 | def get_security_info(self): 39 | return { 40 | "flags": 0, 41 | "flash_crypt_cnt": 0, 42 | "key_purposes": 0, 43 | "chip_id": 0, 44 | "api_version": 0, 45 | } 46 | 47 | """ << esptool method end """ 48 | 49 | def handle_writing_event(self, addr, value): 50 | if addr == self.REGS.EFUSE_CMD_REG: 51 | if value & self.REGS.EFUSE_PGM_CMD: 52 | self.copy_blocks_wr_regs_to_rd_regs(updated_block=(value >> 2) & 0xF) 53 | self.clean_blocks_wr_regs() 54 | self.check_rd_protection_area() 55 | self.write_reg(addr, 0) 56 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 57 | elif value == self.REGS.EFUSE_READ_CMD: 58 | self.write_reg(addr, 0) 59 | self.write_reg(self.REGS.EFUSE_CMD_REG, 0) 60 | self.save_to_file() 61 | 62 | def get_bitlen_of_block(self, blk, wr=False): 63 | if blk.id == 0: 64 | if wr: 65 | return 32 * 8 66 | else: 67 | return 32 * blk.len 68 | else: 69 | if wr: 70 | rs_coding = 32 * 3 71 | return 32 * 8 + rs_coding 72 | else: 73 | return 32 * blk.len 74 | 75 | def handle_coding_scheme(self, blk, data): 76 | if blk.id != 0: 77 | # CODING_SCHEME RS applied only for all blocks except BLK0. 78 | coded_bytes = 12 79 | data.pos = coded_bytes * 8 80 | plain_data = data.readlist("32*uint:8")[::-1] 81 | # takes 32 bytes 82 | # apply RS encoding 83 | rs = reedsolo.RSCodec(coded_bytes) 84 | # 32 byte of data + 12 bytes RS 85 | calc_encoded_data = list(rs.encode([x for x in plain_data])) 86 | data.pos = 0 87 | if calc_encoded_data != data.readlist("44*uint:8")[::-1]: 88 | raise FatalError("Error in coding scheme data") 89 | data = data[coded_bytes * 8 :] 90 | if blk.len < 8: 91 | data = data[(8 - blk.len) * 32 :] 92 | return data 93 | -------------------------------------------------------------------------------- /espefuse/efuse/util.py: -------------------------------------------------------------------------------- 1 | # This file consists of the common useful functions for eFuse 2 | # 3 | # SPDX-FileCopyrightText: 2020-2022 Espressif Systems (Shanghai) CO LTD 4 | # 5 | # SPDX-License-Identifier: GPL-2.0-or-later 6 | 7 | import esptool 8 | 9 | 10 | def hexify(bitstring, separator=""): 11 | as_bytes = tuple(b for b in bitstring) 12 | return separator.join(("%02x" % b) for b in as_bytes) 13 | 14 | 15 | def popcnt(b): 16 | """Return number of "1" bits set in 'b'""" 17 | return len([x for x in bin(b) if x == "1"]) 18 | 19 | 20 | def check_duplicate_name_in_list(name_list): 21 | duples_name = [name for i, name in enumerate(name_list) if name in name_list[:i]] 22 | if duples_name != []: 23 | raise esptool.FatalError( 24 | "Found repeated {} in the name list".format(duples_name) 25 | ) 26 | 27 | 28 | class SdkConfig(object): 29 | def __init__(self, path_to_file): 30 | self.sdkconfig = dict() 31 | if path_to_file is None: 32 | return 33 | with open(path_to_file, "r") as file: 34 | for line in file.readlines(): 35 | if line.startswith("#"): 36 | continue 37 | config = line.strip().split("=", 1) 38 | if len(config) == 2: 39 | self.sdkconfig[config[0]] = ( 40 | True if config[1] == "y" else config[1].strip('"') 41 | ) 42 | 43 | def __getitem__(self, config_name): 44 | try: 45 | return self.sdkconfig[config_name] 46 | except KeyError: 47 | return False 48 | -------------------------------------------------------------------------------- /espefuse/efuse_defs/esp32h2_v0.0_v1.1.yaml: -------------------------------------------------------------------------------- 1 | VER_NO: 44563d2af4ebdba4db6c0a34a50c94f9 2 | EFUSES: 3 | ECDSA_FORCE_USE_HARDWARE_K : {show: y, blk : 0, word: 3, pos: 18, len : 1, start: 114, type : bool, wr_dis : 17, rd_dis: null, alt : '', dict : '', desc: 'Represents whether hardware random number k is forced used in ESDCA. 1: force used. 0: not force used', rloc: 'EFUSE_RD_REPEAT_DATA2_REG[18]', bloc: 'B14[2]'} 4 | -------------------------------------------------------------------------------- /espsecure.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # SPDX-FileCopyrightText: 2014-2022 Fredrik Ahlberg, Angus Gratton, 4 | # Espressif Systems (Shanghai) CO LTD, other contributors as noted. 5 | # 6 | # SPDX-License-Identifier: GPL-2.0-or-later 7 | 8 | # This executable script is a thin wrapper around the main functionality 9 | # in the espsecure Python package 10 | 11 | # When updating this script, please also update esptool.py and espefuse.py 12 | 13 | import contextlib 14 | import os 15 | import sys 16 | 17 | if os.name != "nt": 18 | # Linux/macOS: remove current script directory to avoid importing this file 19 | # as a module; we want to import the installed espsecure module instead 20 | with contextlib.suppress(ValueError): 21 | executable_dir = os.path.dirname(sys.executable) 22 | sys.path = [ 23 | path 24 | for path in sys.path 25 | if not path.endswith(("/bin", "/sbin")) and path != executable_dir 26 | ] 27 | 28 | # Linux/macOS: delete imported module entry to force Python to load 29 | # the module from scratch; this enables importing espsecure module in 30 | # other Python scripts 31 | with contextlib.suppress(KeyError): 32 | del sys.modules["espsecure"] 33 | 34 | import espsecure 35 | 36 | if __name__ == "__main__": 37 | espsecure._main() 38 | -------------------------------------------------------------------------------- /espsecure/__main__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2016-2022 Espressif Systems (Shanghai) CO LTD 2 | # 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | 5 | import espsecure 6 | 7 | if __name__ == "__main__": 8 | espsecure._main() 9 | -------------------------------------------------------------------------------- /espsecure/esp_hsm_sign/exceptions.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD 2 | # 3 | # SPDX-License-Identifier: GPL-2.0-or-later 4 | 5 | from esptool.logger import log 6 | 7 | from pkcs11.exceptions import ( 8 | AlreadyInitialized, 9 | AnotherUserAlreadyLoggedIn, 10 | ArgumentsBad, 11 | DeviceRemoved, 12 | DomainParamsInvalid, 13 | FunctionFailed, 14 | MechanismInvalid, 15 | NoSuchKey, 16 | NoSuchToken, 17 | OperationNotInitialized, 18 | SessionClosed, 19 | ) 20 | 21 | 22 | def handle_exceptions(e, info=""): 23 | exception_type = e.__class__ 24 | if exception_type == MechanismInvalid: 25 | log.error(f"The External HSM does not support the given mechanism: {info}") 26 | elif exception_type == FunctionFailed: 27 | log.error( 28 | "Please ensure proper configuration, privileges and environment variables." 29 | ) 30 | elif exception_type == AlreadyInitialized: 31 | log.error("pkcs11 is already initialized with another library.") 32 | elif exception_type == AnotherUserAlreadyLoggedIn: 33 | log.error("Another User has been already logged in.") 34 | elif exception_type == ArgumentsBad: 35 | log.error("Please check the arguments supplied to the function.") 36 | elif exception_type == DomainParamsInvalid: 37 | log.error( 38 | "Invalid or unsupported domain parameters were supplied to the function." 39 | ) 40 | elif exception_type == DeviceRemoved: 41 | log.error( 42 | "The token has been removed from its slot during " 43 | "the execution of the function." 44 | ) 45 | elif exception_type == NoSuchToken: 46 | log.error("No such token found.") 47 | elif exception_type == NoSuchKey: 48 | log.error("No such key found.") 49 | elif exception_type == OperationNotInitialized: 50 | log.error("Operation not initialized.") 51 | elif exception_type == SessionClosed: 52 | log.error("Session already closed.") 53 | else: 54 | log.error(f"{e.__class__}: {info}") 55 | -------------------------------------------------------------------------------- /esptool.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # SPDX-FileCopyrightText: 2014-2022 Fredrik Ahlberg, Angus Gratton, 4 | # Espressif Systems (Shanghai) CO LTD, other contributors as noted. 5 | # 6 | # SPDX-License-Identifier: GPL-2.0-or-later 7 | 8 | # This executable script is a thin wrapper around the main functionality 9 | # in the esptool Python package 10 | 11 | # When updating this script, please also update espefuse.py and espsecure.py 12 | 13 | import contextlib 14 | import os 15 | import sys 16 | 17 | if os.name != "nt": 18 | # Linux/macOS: remove current script directory to avoid importing this file 19 | # as a module; we want to import the installed esptool module instead 20 | with contextlib.suppress(ValueError): 21 | executable_dir = os.path.dirname(sys.executable) 22 | sys.path = [ 23 | path 24 | for path in sys.path 25 | if not path.endswith(("/bin", "/sbin")) and path != executable_dir 26 | ] 27 | 28 | # Linux/macOS: delete imported module entry to force Python to load 29 | # the module from scratch; this enables importing esptool module in 30 | # other Python scripts 31 | with contextlib.suppress(KeyError): 32 | del sys.modules["esptool"] 33 | 34 | import esptool 35 | 36 | if __name__ == "__main__": 37 | esptool._main() 38 | -------------------------------------------------------------------------------- /esptool/__main__.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2014-2022 Fredrik Ahlberg, Angus Gratton, 2 | # Espressif Systems (Shanghai) CO LTD, other contributors as noted. 3 | # 4 | # SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | import esptool 7 | 8 | if __name__ == "__main__": 9 | esptool._main() 10 | -------------------------------------------------------------------------------- /esptool/targets/__init__.py: -------------------------------------------------------------------------------- 1 | from .esp32 import ESP32ROM 2 | from .esp32c2 import ESP32C2ROM 3 | from .esp32c3 import ESP32C3ROM 4 | from .esp32c5 import ESP32C5ROM 5 | from .esp32c6 import ESP32C6ROM 6 | from .esp32c61 import ESP32C61ROM 7 | from .esp32h2 import ESP32H2ROM 8 | from .esp32h21 import ESP32H21ROM 9 | from .esp32h4 import ESP32H4ROM 10 | from .esp32p4 import ESP32P4ROM 11 | from .esp32s2 import ESP32S2ROM 12 | from .esp32s3 import ESP32S3ROM 13 | from .esp8266 import ESP8266ROM 14 | 15 | 16 | CHIP_DEFS = { 17 | "esp8266": ESP8266ROM, 18 | "esp32": ESP32ROM, 19 | "esp32s2": ESP32S2ROM, 20 | "esp32s3": ESP32S3ROM, 21 | "esp32c3": ESP32C3ROM, 22 | "esp32c2": ESP32C2ROM, 23 | "esp32c6": ESP32C6ROM, 24 | "esp32c61": ESP32C61ROM, 25 | "esp32c5": ESP32C5ROM, 26 | "esp32h2": ESP32H2ROM, 27 | "esp32h21": ESP32H21ROM, 28 | "esp32p4": ESP32P4ROM, 29 | "esp32h4": ESP32H4ROM, 30 | } 31 | 32 | CHIP_LIST = list(CHIP_DEFS.keys()) 33 | ROM_LIST = list(CHIP_DEFS.values()) 34 | -------------------------------------------------------------------------------- /esptool/targets/esp32h21.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024-2025 Fredrik Ahlberg, Angus Gratton, 2 | # Espressif Systems (Shanghai) CO LTD, other contributors as noted. 3 | # 4 | # SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | 7 | from .esp32h2 import ESP32H2ROM 8 | from ..loader import StubMixin 9 | from ..logger import log 10 | from ..util import FatalError 11 | 12 | 13 | class ESP32H21ROM(ESP32H2ROM): 14 | CHIP_NAME = "ESP32-H21" 15 | IMAGE_CHIP_ID = 25 16 | 17 | UF2_FAMILY_ID = 0xB6DD00AF 18 | 19 | DR_REG_LP_WDT_BASE = 0x600B1C00 20 | RTC_CNTL_WDTCONFIG0_REG = DR_REG_LP_WDT_BASE + 0x0 # LP_WDT_RWDT_CONFIG0_REG 21 | RTC_CNTL_WDTWPROTECT_REG = DR_REG_LP_WDT_BASE + 0x001C # LP_WDT_RWDT_WPROTECT_REG 22 | 23 | RTC_CNTL_SWD_CONF_REG = DR_REG_LP_WDT_BASE + 0x0020 # LP_WDT_SWD_CONFIG_REG 24 | RTC_CNTL_SWD_AUTO_FEED_EN = 1 << 18 25 | RTC_CNTL_SWD_WPROTECT_REG = DR_REG_LP_WDT_BASE + 0x0024 # LP_WDT_SWD_WPROTECT_REG 26 | RTC_CNTL_SWD_WKEY = 0x50D83AA1 # LP_WDT_SWD_WKEY, same as WDT key in this case 27 | 28 | EFUSE_BASE = 0x600B4000 29 | EFUSE_BLOCK1_ADDR = EFUSE_BASE + 0x044 30 | MAC_EFUSE_REG = EFUSE_BASE + 0x044 31 | 32 | EFUSE_RD_REG_BASE = EFUSE_BASE + 0x030 # BLOCK0 read base address 33 | 34 | EFUSE_PURPOSE_KEY0_REG = EFUSE_BASE + 0x34 35 | EFUSE_PURPOSE_KEY0_SHIFT = 24 36 | EFUSE_PURPOSE_KEY1_REG = EFUSE_BASE + 0x34 37 | EFUSE_PURPOSE_KEY1_SHIFT = 28 38 | EFUSE_PURPOSE_KEY2_REG = EFUSE_BASE + 0x38 39 | EFUSE_PURPOSE_KEY2_SHIFT = 0 40 | EFUSE_PURPOSE_KEY3_REG = EFUSE_BASE + 0x38 41 | EFUSE_PURPOSE_KEY3_SHIFT = 4 42 | EFUSE_PURPOSE_KEY4_REG = EFUSE_BASE + 0x38 43 | EFUSE_PURPOSE_KEY4_SHIFT = 8 44 | EFUSE_PURPOSE_KEY5_REG = EFUSE_BASE + 0x38 45 | EFUSE_PURPOSE_KEY5_SHIFT = 12 46 | 47 | EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT_REG = EFUSE_RD_REG_BASE 48 | EFUSE_DIS_DOWNLOAD_MANUAL_ENCRYPT = 1 << 20 49 | 50 | EFUSE_SPI_BOOT_CRYPT_CNT_REG = EFUSE_BASE + 0x034 51 | EFUSE_SPI_BOOT_CRYPT_CNT_MASK = 0x7 << 18 52 | 53 | EFUSE_SECURE_BOOT_EN_REG = EFUSE_BASE + 0x038 54 | EFUSE_SECURE_BOOT_EN_MASK = 1 << 20 55 | 56 | def get_pkg_version(self): 57 | return 0 58 | 59 | def get_minor_chip_version(self): 60 | return 0 61 | 62 | def get_major_chip_version(self): 63 | return 0 64 | 65 | def get_chip_description(self): 66 | chip_name = { 67 | 0: "ESP32-H21", 68 | }.get(self.get_pkg_version(), "Unknown ESP32-H21") 69 | major_rev = self.get_major_chip_version() 70 | minor_rev = self.get_minor_chip_version() 71 | return f"{chip_name} (revision v{major_rev}.{minor_rev})" 72 | 73 | def get_chip_features(self): 74 | return ["BT 5 (LE)", "IEEE802.15.4", "Single Core", "96MHz"] 75 | 76 | def get_crystal_freq(self): 77 | # ESP32H21 XTAL is fixed to 32MHz 78 | return 32 79 | 80 | def check_spi_connection(self, spi_connection): 81 | if not set(spi_connection).issubset(set(range(0, 28))): 82 | raise FatalError("SPI Pin numbers must be in the range 0-27.") 83 | if any([v for v in spi_connection if v in [26, 27]]): 84 | log.warning( 85 | "GPIO pins 26 and 27 are used by USB-Serial/JTAG, " 86 | "consider using other pins for SPI flash connection." 87 | ) 88 | 89 | 90 | class ESP32H21StubLoader(StubMixin, ESP32H21ROM): 91 | """Stub loader for ESP32-H21, runs on top of ROM.""" 92 | 93 | pass 94 | 95 | 96 | ESP32H21ROM.STUB_CLASS = ESP32H21StubLoader 97 | -------------------------------------------------------------------------------- /esptool/targets/stub_flasher/1/README.md: -------------------------------------------------------------------------------- 1 | # Licensing 2 | 3 | The binaries in JSON format distributed in this directory are released as Free Software under GNU General Public License Version 2 or later. They were released at https://github.com/espressif/esptool-legacy-flasher-stub/releases/tag/v1.5.1 from where the sources can be obtained. 4 | -------------------------------------------------------------------------------- /esptool/targets/stub_flasher/2/LICENSE-MIT: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2025 Espressif Systems (Shanghai) CO LTD 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /esptool/targets/stub_flasher/2/README.md: -------------------------------------------------------------------------------- 1 | # Licensing 2 | 3 | The binaries in JSON format distributed in this directory are dual licensed under the Apache License Version 2.0 or the MIT license. They were released at https://github.com/espressif/esp-flasher-stub/releases/tag/v0.1.0 from where the sources can be obtained. 4 | -------------------------------------------------------------------------------- /esptool/targets/stub_flasher/2/esp32.json: -------------------------------------------------------------------------------- 1 | { 2 | "entry": 1074520064, 3 | "text": "NmEADAgQoSCJARARIOUAAKgBjEoQESBlAQAd8DZhAH0BKQeoByUCAD3wHfA2YQB9ASkHqAflAQA98B3wNmEAfQEpBz3wHfAANmEAfQEpBz3wHfAANmEAfQEpBz3wHfAA", 4 | "text_start": 1074520064 5 | } -------------------------------------------------------------------------------- /esptool/targets/stub_flasher/2/esp32c2.json: -------------------------------------------------------------------------------- 1 | { 2 | "entry": 1077411840, 3 | "text": "ARFoAAbOAsY5IDJFEcEVIPJABWGCgAERBs4izAAQIyak/gMlxP49KAEA8kBiRAVhgoABEQbOIswAECMmpP4DJcT+JSgBAPJAYkQFYYKAAREGziLMABAjJqT+AQDyQGJEBWGCgAERBs4izAAQIyak/gEA8kBiRAVhgoABEQbOIswAECMmpP4BAPJAYkQFYYKA", 4 | "text_start": 1077411840 5 | } -------------------------------------------------------------------------------- /esptool/targets/stub_flasher/2/esp32c3.json: -------------------------------------------------------------------------------- 1 | { 2 | "entry": 1077411840, 3 | "text": "ARFoAAbOAsY5IDJFEcEVIPJABWGCgAERBs4izAAQIyak/gMlxP49KAEA8kBiRAVhgoABEQbOIswAECMmpP4DJcT+JSgBAPJAYkQFYYKAAREGziLMABAjJqT+AQDyQGJEBWGCgAERBs4izAAQIyak/gEA8kBiRAVhgoABEQbOIswAECMmpP4BAPJAYkQFYYKA", 4 | "text_start": 1077411840 5 | } -------------------------------------------------------------------------------- /esptool/targets/stub_flasher/2/esp32c5.json: -------------------------------------------------------------------------------- 1 | { 2 | "entry": 1082130432, 3 | "text": "ARFoAAbOAsY5IDJFEcEVIPJABWGCgAERBs4izAAQIyak/gMlxP49KAEA8kBiRAVhgoABEQbOIswAECMmpP4DJcT+JSgBAPJAYkQFYYKAAREGziLMABAjJqT+AQDyQGJEBWGCgAERBs4izAAQIyak/gEA8kBiRAVhgoABEQbOIswAECMmpP4BAPJAYkQFYYKA", 4 | "text_start": 1082130432 5 | } -------------------------------------------------------------------------------- /esptool/targets/stub_flasher/2/esp32c6.json: -------------------------------------------------------------------------------- 1 | { 2 | "entry": 1082130432, 3 | "text": "ARFoAAbOAsY5IDJFEcEVIPJABWGCgAERBs4izAAQIyak/gMlxP49KAEA8kBiRAVhgoABEQbOIswAECMmpP4DJcT+JSgBAPJAYkQFYYKAAREGziLMABAjJqT+AQDyQGJEBWGCgAERBs4izAAQIyak/gEA8kBiRAVhgoABEQbOIswAECMmpP4BAPJAYkQFYYKA", 4 | "text_start": 1082130432 5 | } -------------------------------------------------------------------------------- /esptool/targets/stub_flasher/2/esp32c61.json: -------------------------------------------------------------------------------- 1 | { 2 | "entry": 1082130432, 3 | "text": "ARFoAAbOAsY5IDJFEcEVIPJABWGCgAERBs4izAAQIyak/gMlxP49KAEA8kBiRAVhgoABEQbOIswAECMmpP4DJcT+JSgBAPJAYkQFYYKAAREGziLMABAjJqT+AQDyQGJEBWGCgAERBs4izAAQIyak/gEA8kBiRAVhgoABEQbOIswAECMmpP4BAPJAYkQFYYKA", 4 | "text_start": 1082130432 5 | } -------------------------------------------------------------------------------- /esptool/targets/stub_flasher/2/esp32h2.json: -------------------------------------------------------------------------------- 1 | { 2 | "entry": 1082130432, 3 | "text": "ARFoAAbOAsY5IDJFEcEVIPJABWGCgAERBs4izAAQIyak/gMlxP49KAEA8kBiRAVhgoABEQbOIswAECMmpP4DJcT+JSgBAPJAYkQFYYKAAREGziLMABAjJqT+AQDyQGJEBWGCgAERBs4izAAQIyak/gEA8kBiRAVhgoABEQbOIswAECMmpP4BAPJAYkQFYYKA", 4 | "text_start": 1082130432 5 | } -------------------------------------------------------------------------------- /esptool/targets/stub_flasher/2/esp32p4.json: -------------------------------------------------------------------------------- 1 | { 2 | "entry": 1341194240, 3 | "text": "ARFoAAbOAsY5IDJFEcEVIPJABWGCgAERBs4izAAQIyak/gMlxP49KAEA8kBiRAVhgoABEQbOIswAECMmpP4DJcT+JSgBAPJAYkQFYYKAAREGziLMABAjJqT+AQDyQGJEBWGCgAERBs4izAAQIyak/gEA8kBiRAVhgoABEQbOIswAECMmpP4BAPJAYkQFYYKA", 4 | "text_start": 1341194240 5 | } -------------------------------------------------------------------------------- /esptool/targets/stub_flasher/2/esp32s2.json: -------------------------------------------------------------------------------- 1 | { 2 | "entry": 1073905664, 3 | "text": "NmEADAgQoSCJARARIOUAAKgBjEoQESBlAQAd8DZhAH0BKQeoByUCAD3wHfA2YQB9ASkHqAflAQA98B3wNmEAfQEpBz3wHfAANmEAfQEpBz3wHfAANmEAfQEpBz3wHfAA", 4 | "text_start": 1073905664 5 | } -------------------------------------------------------------------------------- /esptool/targets/stub_flasher/2/esp32s3.json: -------------------------------------------------------------------------------- 1 | { 2 | "entry": 1077379072, 3 | "text": "NmEADAgQoSCJARARIOUAAKgBjEoQESBlAQAd8DZhAH0BKQeoByUCAD3wHfA2YQB9ASkHqAflAQA98B3wNmEAfQEpBz3wHfAANmEAfQEpBz3wHfAANmEAfQEpBz3wHfAA", 4 | "text_start": 1077379072 5 | } -------------------------------------------------------------------------------- /esptool/targets/stub_flasher/2/esp8266.json: -------------------------------------------------------------------------------- 1 | { 2 | "entry": 1074843652, 3 | "text": "qBAAQAH//0YAAAAAEsHgIqAAImEALQECYQcFAQAoAYwShQIACHESwSAN8AASweAJcflh/QEpDygPRQQAPfAdDwhx+GESwSAN8AAAABLB4Alx+WH9ASkPKA+FAwA98B0PCHH4YRLBIA3wAAAAEsHg+XH9ASkPPfAdD/hxEsEgDfASweD5cf0BKQ898B0P+HESwSAN8BLB4Plx/QEpDz3wHQ/4cRLBIA3w", 4 | "text_start": 1074843648 5 | } -------------------------------------------------------------------------------- /esptool/uf2_writer.py: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2020-2025 Espressif Systems (Shanghai) CO LTD 2 | # SPDX-License-Identifier: GPL-2.0-or-later 3 | # Code was originally licensed under Apache 2.0 before the release of ESP-IDF v5.2 4 | 5 | import hashlib 6 | import struct 7 | 8 | from esptool.util import div_roundup 9 | 10 | 11 | class UF2Writer(object): 12 | # The UF2 format is described here: https://github.com/microsoft/uf2 13 | UF2_BLOCK_SIZE = 512 14 | # max value of CHUNK_SIZE reduced by optional parts. Currently, MD5_PART only. 15 | UF2_DATA_SIZE = 476 16 | UF2_MD5_PART_SIZE = 24 17 | UF2_FIRST_MAGIC = 0x0A324655 18 | UF2_SECOND_MAGIC = 0x9E5D5157 19 | UF2_FINAL_MAGIC = 0x0AB16F30 20 | UF2_FLAG_FAMILYID_PRESENT = 0x00002000 21 | UF2_FLAG_MD5_PRESENT = 0x00004000 22 | 23 | def __init__( 24 | self, 25 | chip_id: int, 26 | output_file: str, 27 | chunk_size: int | None, 28 | md5_enabled: bool = True, 29 | ) -> None: 30 | if not md5_enabled: 31 | self.UF2_MD5_PART_SIZE = 0 32 | self.UF2_FLAG_MD5_PRESENT = 0x00000000 33 | self.md5_enabled = md5_enabled 34 | self.chip_id = chip_id 35 | self.CHUNK_SIZE = ( 36 | self.UF2_DATA_SIZE - self.UF2_MD5_PART_SIZE 37 | if chunk_size is None 38 | else chunk_size 39 | ) 40 | self.f = open(output_file, "wb") 41 | 42 | def __enter__(self) -> "UF2Writer": 43 | return self 44 | 45 | def __exit__(self, exc_type: str, exc_val: int, exc_tb: list) -> None: 46 | if self.f: 47 | self.f.close() 48 | 49 | @staticmethod 50 | def _to_uint32(num: int) -> bytes: 51 | return struct.pack(" None: 56 | assert len_chunk > 0 57 | assert len_chunk <= self.CHUNK_SIZE 58 | assert block_no < blocks 59 | block = struct.pack( 60 | " None: 84 | blocks = div_roundup(len(image), self.CHUNK_SIZE) 85 | chunks = [ 86 | image[i : i + self.CHUNK_SIZE] 87 | for i in range(0, len(image), self.CHUNK_SIZE) 88 | ] 89 | for i, chunk in enumerate(chunks): 90 | len_chunk = len(chunk) 91 | self._write_block(addr, chunk, len_chunk, i, blocks) 92 | addr += len_chunk 93 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import os 2 | from setuptools import setup 3 | 4 | if os.name != "nt": 5 | scripts = ["esptool.py", "espefuse.py", "espsecure.py", "esp_rfc2217_server.py"] 6 | entry_points = {} 7 | else: 8 | scripts = [] 9 | entry_points = { 10 | "console_scripts": [ 11 | "esptool.py=esptool.__init__:_main", 12 | "espsecure.py=espsecure.__init__:_main", 13 | "espefuse.py=espefuse.__init__:_main", 14 | "esp_rfc2217_server.py=esp_rfc2217_server.__init__:main", 15 | ], 16 | } 17 | 18 | setup( 19 | scripts=scripts, 20 | entry_points=entry_points, 21 | ) 22 | -------------------------------------------------------------------------------- /test/.covconf: -------------------------------------------------------------------------------- 1 | [run] 2 | parallel = true 3 | 4 | [paths] 5 | source = 6 | ./ 7 | ./ 8 | C:\GitLab-Runner\builds\*\*\espressif\esptool\ -------------------------------------------------------------------------------- /test/README.md: -------------------------------------------------------------------------------- 1 | # esptool.py test suite 2 | 3 | See the [Automated Integration Tests section in `esptool.py` documentation](https://docs.espressif.com/projects/esptool/en/latest/esp32/contributing.html#automated-integration-tests) to learn about the test suite and how to run it. 4 | -------------------------------------------------------------------------------- /test/conftest.py: -------------------------------------------------------------------------------- 1 | import pytest 2 | import os 3 | 4 | 5 | def pytest_addoption(parser): 6 | # test_esptool.py and test_espefuse.py 7 | parser.addoption( 8 | "--port", action="store", default="/dev/ttyUSB0", help="Serial port" 9 | ) 10 | parser.addoption("--chip", action="store", default="esp32", help="Chip type") 11 | 12 | # test_esptool.py only 13 | parser.addoption("--baud", action="store", default=115200, help="Baud rate") 14 | parser.addoption("--with-trace", action="store_true", default=False, help="Trace") 15 | parser.addoption( 16 | "--preload-port", 17 | action="store", 18 | default=False, 19 | help="Port for dummy binary preloading for USB-JTAG/Serial tests", 20 | ) 21 | 22 | # test_espefuse.py only 23 | parser.addoption( 24 | "--reset-port", action="store", default=None, help="FPGA reset port" 25 | ) 26 | 27 | 28 | def pytest_configure(config): 29 | # test_esptool.py and test_espefuse.py 30 | global arg_port, arg_chip 31 | arg_port = config.getoption("--port") 32 | arg_chip = config.getoption("--chip") 33 | 34 | # test_esptool.py only 35 | global arg_baud, arg_trace, arg_preload_port 36 | arg_baud = config.getoption("--baud") 37 | arg_trace = config.getoption("--with-trace") 38 | arg_preload_port = config.getoption("--preload-port") 39 | 40 | # test_espefuse.py only 41 | global arg_reset_port 42 | arg_reset_port = config.getoption("--reset-port") 43 | 44 | # register custom markers 45 | config.addinivalue_line( 46 | "markers", 47 | "host_test: mark esptool tests that run on the host machine only " 48 | "(don't require a real chip connected).", 49 | ) 50 | 51 | config.addinivalue_line( 52 | "markers", 53 | "quick_test: mark esptool tests checking basic functionality.", 54 | ) 55 | 56 | 57 | def need_to_install_package_err(): 58 | pytest.exit( 59 | "To run the tests, install esptool in development mode. " 60 | "Instructions: https://docs.espressif.com/projects/esptool/en/latest/" 61 | "contributing.html#development-setup" 62 | ) 63 | 64 | 65 | @pytest.fixture(scope="session", autouse=True) 66 | def set_terminal_width(): 67 | """Make sure terminal width is set to 120 columns for consistent test output.""" 68 | os.environ["COLUMNS"] = "120" 69 | -------------------------------------------------------------------------------- /test/ecdsa_secure_boot_signing_key2.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MHcCAQEEIINRYjKaXM0dQJn4FLwoHYj3ovmpRee7UWv8ksQ9IS2toAoGCCqGSM49 3 | AwEHoUQDQgAEYWCmqAxxAmbr8cZk4AjTYkQJ0pCZOsESk2bPAe6lrzHrFKKR2t2W 4 | ge+cNvXU2dYswEdgWr/fdnyAbHHEVEBSrA== 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /test/efuse_scripts/efuse_burn1.py: -------------------------------------------------------------------------------- 1 | # flake8: noqa 2 | # SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD 3 | # 4 | # SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | import json 7 | 8 | config = json.load(args.configfiles[0]) 9 | 10 | 11 | assert args.index == 10, "Index should be 10" 12 | 13 | for cmd in config["burn_efuses1"]: 14 | cmd = cmd.format(index=args.index) 15 | print(cmd) 16 | espefuse(esp, efuses, args, cmd) 17 | 18 | assert args.index == 10, "Index should be 10" 19 | -------------------------------------------------------------------------------- /test/efuse_scripts/efuse_burn2.py: -------------------------------------------------------------------------------- 1 | # flake8: noqa 2 | # SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD 3 | # 4 | # SPDX-License-Identifier: GPL-2.0-or-later 5 | 6 | import json 7 | 8 | config = json.load(args.configfiles[0]) 9 | 10 | 11 | assert args.index == 28, "Should be index from the first script = 28" 12 | 13 | for cmd in config["burn_efuses2"]: 14 | cmd = cmd.format(index=args.index) 15 | print(cmd) 16 | espefuse(esp, efuses, args, cmd) 17 | 18 | assert args.index == 28, "Should be index from the first script = 28" 19 | -------------------------------------------------------------------------------- /test/efuse_scripts/esp32/config1.json: -------------------------------------------------------------------------------- 1 | { 2 | "burn_efuses1": [ 3 | "burn_bit BLOCK3 0 1 2 3 4 5 6 7 8 9 {index}", 4 | "burn_bit BLOCK3 29 30 31" 5 | ] 6 | } -------------------------------------------------------------------------------- /test/efuse_scripts/esp32/config2.json: -------------------------------------------------------------------------------- 1 | { 2 | "burn_efuses2": [ 3 | "burn_bit BLOCK3 11 12 13 14 15 16 17 18 19", 4 | "burn_bit BLOCK3 20 21 22 23 24 25 26 27 {index}", 5 | "execute_scripts efuse_scripts/efuse_burn1.py --index 10 --configfiles efuse_scripts/esp32/config1.json", 6 | "burn_bit BLOCK2 {index}" 7 | ] 8 | } -------------------------------------------------------------------------------- /test/efuse_scripts/esp32/execute_efuse_script.py: -------------------------------------------------------------------------------- 1 | # flake8: noqa 2 | # fmt: off 3 | espefuse(esp, efuses, args, "burn_efuse JTAG_DISABLE 1 DISABLE_SDIO_HOST 1 CONSOLE_DEBUG_DISABLE 1") 4 | espefuse(esp, efuses, args, "burn_key flash_encryption ../../images/efuse/256bit --no-protect-key") 5 | espefuse(esp, efuses, args, "burn_key_digest ../../secure_images/rsa_secure_boot_signing_key.pem") 6 | espefuse(esp, efuses, args, "burn_bit BLOCK3 64 66 69 72 78 82 83 90") 7 | espefuse(esp, efuses, args, "burn_custom_mac AA:BB:CC:DD:EE:88") 8 | 9 | efuses.burn_all() 10 | 11 | espefuse(esp, efuses, args, "summary") 12 | espefuse(esp, efuses, args, "adc_info") 13 | espefuse(esp, efuses, args, "get_custom_mac") 14 | 15 | 16 | # Checks written eFuses 17 | if efuses["JTAG_DISABLE"].get() != 1: 18 | raise esptool.FatalError("JTAG_DISABLE was not set") 19 | if efuses["DISABLE_SDIO_HOST"].get() != 1: 20 | raise esptool.FatalError("DISABLE_SDIO_HOST was not set") 21 | if efuses["CONSOLE_DEBUG_DISABLE"].get() != 1: 22 | raise esptool.FatalError("CONSOLE_DEBUG_DISABLE was not set") 23 | 24 | 25 | if efuses["BLOCK1"].get_meaning() != "bf be bd bc bb ba b9 b8 b7 b6 b5 b4 b3 b2 b1 b0 af ae ad ac ab aa a9 a8 a7 a6 a5 a4 a3 a2 a1 a0": 26 | raise esptool.FatalError("BLOCK1 was not set correctly") 27 | 28 | if not efuses["BLOCK1"].is_readable() or not efuses["BLOCK1"].is_writeable(): 29 | raise esptool.FatalError("BLOCK1 should be readable and writeable") 30 | 31 | 32 | if efuses["BLOCK2"].get_meaning() != "cb 27 91 a3 71 b0 c0 32 2b f7 37 04 78 ba 09 62 22 4c ab 1c f2 28 78 79 e4 29 67 3e 7d a8 44 63": 33 | raise esptool.FatalError("BLOCK2 was not set correctly") 34 | 35 | if not efuses["BLOCK2"].is_readable() or efuses["BLOCK2"].is_writeable(): 36 | raise esptool.FatalError("BLOCK2 should not be readable and not writeable") 37 | 38 | 39 | if efuses["BLOCK3"].get_meaning() != "69 aa bb cc dd ee 88 00 25 41 0c 04 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 00": 40 | raise esptool.FatalError("BLOCK3 was not set correctly") 41 | 42 | if efuses["CUSTOM_MAC"].get_meaning() != "aa:bb:cc:dd:ee:88 (CRC 0x69 OK)": 43 | raise esptool.FatalError("CUSTOM_MAC was not set correctly") 44 | 45 | 46 | espefuse(esp, efuses, args, "read_protect_efuse BLOCK1") 47 | espefuse(esp, efuses, args, "write_protect_efuse BLOCK1") 48 | efuses.burn_all() 49 | if efuses["BLOCK1"].is_readable() or efuses["BLOCK1"].is_writeable(): 50 | raise esptool.FatalError("BLOCK_KEY0 should be not readable and not writeable") 51 | -------------------------------------------------------------------------------- /test/efuse_scripts/esp32/execute_efuse_script2.py: -------------------------------------------------------------------------------- 1 | # flake8: noqa 2 | # fmt: off 3 | espefuse(esp, efuses, args, "burn_efuse JTAG_DISABLE 1 DISABLE_SDIO_HOST 1 CONSOLE_DEBUG_DISABLE 1") 4 | if efuses["JTAG_DISABLE"].get() != 0: 5 | raise esptool.FatalError("Burn should be at the end") 6 | 7 | espefuse(esp, efuses, args, "burn_key flash_encryption ../../images/efuse/256bit --no-protect-key") 8 | if efuses["BLOCK1"].get_meaning() != "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00": 9 | raise esptool.FatalError("Burn should be at the end") 10 | if not efuses["BLOCK1"].is_readable() or not efuses["BLOCK1"].is_writeable(): 11 | raise esptool.FatalError("Burn should be at the end") 12 | 13 | espefuse(esp, efuses, args, "burn_key_digest ../../secure_images/rsa_secure_boot_signing_key.pem") 14 | if efuses["BLOCK2"].get_meaning() != "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00": 15 | raise esptool.FatalError("Burn should be at the end") 16 | if not efuses["BLOCK2"].is_readable() or not efuses["BLOCK2"].is_writeable(): 17 | raise esptool.FatalError("Burn should be at the end") 18 | 19 | espefuse(esp, efuses, args, "burn_bit BLOCK3 64 66 69 72 78 82 83 90") 20 | espefuse(esp, efuses, args, "burn_custom_mac AA:BB:CC:DD:EE:88") 21 | 22 | if efuses["BLOCK3"].get_meaning() != "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00": 23 | raise esptool.FatalError("Burn should be at the end") 24 | -------------------------------------------------------------------------------- /test/efuse_scripts/esp32xx/config1.json: -------------------------------------------------------------------------------- 1 | { 2 | "burn_efuses1": [ 3 | "burn_bit BLOCK_KEY4 0 1 2 3 4 5 6 7 8 9 {index}", 4 | "burn_bit BLOCK_KEY4 29 30 31" 5 | ] 6 | } -------------------------------------------------------------------------------- /test/efuse_scripts/esp32xx/config2.json: -------------------------------------------------------------------------------- 1 | { 2 | "burn_efuses2": [ 3 | "burn_bit BLOCK_KEY4 11 12 13 14 15 16 17 18 19", 4 | "burn_bit BLOCK_KEY4 20 21 22 23 24 25 26 27 {index}", 5 | "execute_scripts efuse_scripts/efuse_burn1.py --index 10 --configfiles efuse_scripts/esp32xx/config1.json", 6 | "burn_bit BLOCK_KEY3 {index}" 7 | ] 8 | } -------------------------------------------------------------------------------- /test/efuse_scripts/esp32xx/execute_efuse_script.py: -------------------------------------------------------------------------------- 1 | # flake8: noqa 2 | # fmt: off 3 | espefuse(esp, efuses, args, 'burn_efuse DIS_FORCE_DOWNLOAD 1 DIS_DOWNLOAD_MODE 1') 4 | espefuse(esp, efuses, args, 'burn_bit BLOCK_USR_DATA 64 66 69 72 78 82 83 90') 5 | espefuse(esp, efuses, args, 'read_protect_efuse BLOCK_SYS_DATA2') 6 | espefuse(esp, efuses, args, 'write_protect_efuse BLOCK_SYS_DATA2') 7 | espefuse(esp, efuses, args, 'burn_block_data BLOCK_KEY5 ../../images/efuse/256bit') 8 | espefuse(esp, efuses, args, 'burn_key BLOCK_KEY0 ../../images/efuse/256bit XTS_AES_128_KEY --no-read-protect') 9 | espefuse(esp, efuses, args, 'burn_key_digest BLOCK_KEY1 ../../secure_images/rsa_secure_boot_signing_key.pem SECURE_BOOT_DIGEST0') 10 | 11 | efuses.burn_all() 12 | 13 | espefuse(esp, efuses, args, 'summary') 14 | espefuse(esp, efuses, args, 'adc_info') 15 | 16 | 17 | # Checks written eFuses 18 | if efuses["DIS_FORCE_DOWNLOAD"].get() != 1: 19 | raise esptool.FatalError("DIS_FORCE_DOWNLOAD was not set") 20 | if efuses["DIS_DOWNLOAD_MODE"].get() != 1: 21 | raise esptool.FatalError("DIS_DOWNLOAD_MODE was not set") 22 | 23 | if efuses["BLOCK_USR_DATA"].get_meaning() != "00 00 00 00 00 00 00 00 25 41 0c 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00": 24 | raise esptool.FatalError("BLOCK_USR_DATA was not set correctly") 25 | 26 | 27 | if efuses["BLOCK_SYS_DATA2"].is_readable() or efuses["BLOCK_SYS_DATA2"].is_writeable(): 28 | raise esptool.FatalError("BLOCK_SYS_DATA2 should be read and write protected") 29 | 30 | 31 | if efuses["BLOCK_KEY5"].get_meaning() != "a0 a1 a2 a3 a4 a5 a6 a7 a8 a9 aa ab ac ad ae af b0 b1 b2 b3 b4 b5 b6 b7 b8 b9 ba bb bc bd be bf": 32 | raise esptool.FatalError("BLOCK_KEY5 was not set correctly") 33 | 34 | 35 | if efuses["BLOCK_KEY0"].get_meaning() != "bf be bd bc bb ba b9 b8 b7 b6 b5 b4 b3 b2 b1 b0 af ae ad ac ab aa a9 a8 a7 a6 a5 a4 a3 a2 a1 a0": 36 | raise esptool.FatalError("BLOCK_KEY0 was not set correctly") 37 | 38 | if not efuses["BLOCK_KEY0"].is_readable() or efuses["BLOCK_KEY0"].is_writeable(): 39 | raise esptool.FatalError("BLOCK_KEY0 should be readable and not writable") 40 | 41 | if efuses["KEY_PURPOSE_0"].get_meaning() != "XTS_AES_128_KEY": 42 | raise esptool.FatalError("KEY_PURPOSE_0 was not set XTS_AES_128_KEY") 43 | 44 | if efuses["KEY_PURPOSE_0"].is_writeable(): 45 | raise esptool.FatalError("KEY_PURPOSE_0 should be write-protected") 46 | 47 | 48 | if efuses["BLOCK_KEY1"].get_meaning() != "cb 27 91 a3 71 b0 c0 32 2b f7 37 04 78 ba 09 62 22 4c ab 1c f2 28 78 79 e4 29 67 3e 7d a8 44 63": 49 | raise esptool.FatalError("BLOCK_KEY1 was not set correctly") 50 | 51 | if efuses["KEY_PURPOSE_1"].get_meaning() != "SECURE_BOOT_DIGEST0": 52 | raise esptool.FatalError("KEY_PURPOSE_1 was not set SECURE_BOOT_DIGEST0") 53 | 54 | if efuses["KEY_PURPOSE_1"].is_writeable(): 55 | raise esptool.FatalError("KEY_PURPOSE_1 should be write-protected") 56 | 57 | if not efuses["BLOCK_KEY1"].is_readable() or efuses["BLOCK_KEY1"].is_writeable(): 58 | raise esptool.FatalError("BLOCK_KEY1 should be readable and not writable") 59 | 60 | 61 | espefuse(esp, efuses, args, 'burn_key BLOCK_KEY0 ../../images/efuse/256bit XTS_AES_128_KEY') 62 | efuses.burn_all() 63 | if efuses["BLOCK_KEY0"].is_readable() or efuses["BLOCK_KEY0"].is_writeable(): 64 | raise esptool.FatalError("BLOCK_KEY0 should be not readable and not writeable") 65 | -------------------------------------------------------------------------------- /test/efuse_scripts/esp32xx/execute_efuse_script2.py: -------------------------------------------------------------------------------- 1 | # flake8: noqa 2 | # fmt: off 3 | espefuse(esp, efuses, args, 'burn_efuse DIS_FORCE_DOWNLOAD 1 DIS_DOWNLOAD_MODE 1') 4 | if efuses["DIS_FORCE_DOWNLOAD"].get() != 0: 5 | raise esptool.FatalError("Burn should be at the end") 6 | 7 | espefuse(esp, efuses, args, 'burn_bit BLOCK_USR_DATA 64 66 69 72 78 82 83 90') 8 | if efuses["BLOCK_USR_DATA"].get_meaning() != "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00": 9 | raise esptool.FatalError("Burn should be at the end") 10 | 11 | espefuse(esp, efuses, args, 'read_protect_efuse BLOCK_SYS_DATA2') 12 | espefuse(esp, efuses, args, 'write_protect_efuse BLOCK_SYS_DATA2') 13 | if not efuses["BLOCK_SYS_DATA2"].is_readable() or not efuses["BLOCK_SYS_DATA2"].is_writeable(): 14 | raise esptool.FatalError("Burn should be at the end") 15 | 16 | espefuse(esp, efuses, args, 'burn_block_data BLOCK_KEY5 ../../images/efuse/256bit') 17 | if efuses["BLOCK_KEY5"].get_meaning() != "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00": 18 | raise esptool.FatalError("Burn should be at the end") 19 | 20 | espefuse(esp, efuses, args, 'burn_key BLOCK_KEY0 ../../images/efuse/256bit XTS_AES_128_KEY --no-read-protect') 21 | if efuses["BLOCK_KEY0"].get_meaning() != "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00": 22 | raise esptool.FatalError("Burn should be at the end") 23 | if not efuses["BLOCK_KEY0"].is_readable() or not efuses["BLOCK_KEY0"].is_writeable(): 24 | raise esptool.FatalError("Burn should be at the end") 25 | 26 | espefuse(esp, efuses, args, 'burn_key_digest BLOCK_KEY1 ../../secure_images/rsa_secure_boot_signing_key.pem SECURE_BOOT_DIGEST0') 27 | if efuses["BLOCK_KEY1"].get_meaning() != "00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00": 28 | raise esptool.FatalError("Burn should be at the end") 29 | if not efuses["BLOCK_KEY1"].is_readable() or not efuses["BLOCK_KEY1"].is_writeable(): 30 | raise esptool.FatalError("Burn should be at the end") 31 | -------------------------------------------------------------------------------- /test/elf2image/esp32-app-template.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/elf2image/esp32-app-template.elf -------------------------------------------------------------------------------- /test/elf2image/esp32-bootloader.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/elf2image/esp32-bootloader.elf -------------------------------------------------------------------------------- /test/elf2image/esp32-too-many-sections.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/elf2image/esp32-too-many-sections.elf -------------------------------------------------------------------------------- /test/elf2image/esp32-too-many-sections/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for generating and compiling an Xtensa-ESP32 ELF file that has a lot 2 | # (too many) sections. 3 | # 4 | # To generate the C file and compile it, simply use the following command: 5 | # make 6 | 7 | # Adjustable parameters 8 | BASH=/bin/bash 9 | SECTIONS_COUNT=350 10 | 11 | # Do not touch the following variables 12 | CC=xtensa-esp32-elf-gcc 13 | CFLAGS=-W -std=c99 14 | LDFLAGS=-nostdlib -ffunction-sections -fdata-sections 15 | OBJ=esp32-too-many-sections.o 16 | BIN=esp32-too-many-sections.elf 17 | SRC=esp32-too-many-sections.c 18 | 19 | # The following command will generate the C file to compile. 20 | # This is the simplest way to have a working and easily maintainable 21 | # C file as it is almost only way out repetitions. 22 | define generate_c_code = 23 | # Generate the constants, one per section. 24 | # Is it necessary to align the sections on an 16-byte bounds in order 25 | # to prevent esptool to merge them while generating the binary. 26 | # Indeed, by aligning them, there will be padding between them. 27 | echo "Generating $(SRC) ..." 28 | echo "// This has file been automatically generated, please check Makefile for\ 29 | more information." > $(SRC); \ 30 | for i in {1..$(SECTIONS_COUNT)}; \ 31 | do \ 32 | echo "const int number$$i __attribute__ ((section (\".NUM$$i\"), aligned((16)))) = $$i;" >> $(SRC) ;\ 33 | done; 34 | echo -e "\n" >> $(SRC) ; \ 35 | echo "int _start(void) {" >> $(SRC) ; \ 36 | echo " volatile long int res =" >> $(SRC) ; \ 37 | for i in {1..$(SECTIONS_COUNT)}; \ 38 | do \ 39 | echo " (unsigned int) number$$i +" >> $(SRC) ;\ 40 | done; 41 | # Adding 0 at the end it simpler than making a special case for the last 42 | # loop iteration 43 | echo " 0;" >> $(SRC) ; 44 | echo " return res;" >> $(SRC) ; 45 | echo "}" >> $(SRC) ; 46 | endef 47 | 48 | .PHONY: all clean generate-src 49 | 50 | all: $(BIN) 51 | 52 | $(BIN): $(OBJ) 53 | $(CC) -o $@ $^ $(LDFLAGS) 54 | 55 | # By default, make uses sh as script language, use bash to generate the C file 56 | $(SRC): SHELL:=$(BASH) 57 | $(SRC): 58 | @$(generate_c_code) 59 | 60 | %.o: %.c 61 | $(CC) -c -o $@ $^ $(CFLAGS) 62 | 63 | clean: 64 | rm -f $(SRC) $(BIN) $(OBJ) 65 | -------------------------------------------------------------------------------- /test/elf2image/esp32-zephyr.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/elf2image/esp32-zephyr.elf -------------------------------------------------------------------------------- /test/elf2image/esp32c6-appdesc.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/elf2image/esp32c6-appdesc.elf -------------------------------------------------------------------------------- /test/elf2image/esp32c6-appdesc/Makefile: -------------------------------------------------------------------------------- 1 | CC = riscv32-esp-elf-gcc 2 | CFLAGS = -Os -ffreestanding -nostdlib 3 | LDFLAGS = -T esp32c6-appdesc.ld 4 | 5 | TARGET = esp32c6-appdesc.elf 6 | SRC = main.c 7 | OBJ = main.o 8 | 9 | all: $(TARGET) 10 | 11 | $(TARGET): $(OBJ) 12 | $(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) 13 | 14 | %.o: %.c 15 | $(CC) $(CFLAGS) -c $< -o $@ 16 | 17 | clean: 18 | rm -f $(OBJ) $(TARGET) -------------------------------------------------------------------------------- /test/elf2image/esp32c6-appdesc/esp32c6-appdesc.ld: -------------------------------------------------------------------------------- 1 | MEMORY 2 | { 3 | /** 4 | * 0x42000000 is start of flash + 0x20 for image + extended header and segment header 5 | * 0x14c is length of esp_app_desc_t structure 6 | */ 7 | drom_seg (R) : org = 0x42000020, len = 0x14c 8 | } 9 | 10 | SECTIONS 11 | { 12 | .flash.appdesc : 13 | { 14 | KEEP(*(.flash.appdesc)) 15 | } > drom_seg 16 | } -------------------------------------------------------------------------------- /test/elf2image/esp32c6-appdesc/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // This is the structure of the application description section in the binary image (taken from ESP-IDF). 4 | typedef struct { 5 | uint32_t magic_word; 6 | uint32_t secure_version; 7 | uint32_t reserv1[2]; 8 | char version[32]; 9 | char project_name[32]; 10 | char time[16]; 11 | char date[16]; 12 | char idf_ver[32]; 13 | uint8_t app_elf_sha256[32]; 14 | uint16_t min_efuse_blk_rev_full; 15 | uint16_t max_efuse_blk_rev_full; 16 | uint8_t mmu_page_size; 17 | uint8_t reserv3[3]; 18 | uint32_t reserv2[18]; 19 | } esp_app_desc_t; 20 | 21 | __attribute__((section(".flash.appdesc"))) 22 | esp_app_desc_t my_app_desc = { 23 | .magic_word = 0xABCD5432, 24 | .secure_version = 0xffffffff, 25 | .reserv1 = {0xffffffff, 0xffffffff}, 26 | .version = "_______________________________", 27 | .project_name = "-------------------------------", 28 | .time = "xxxxxxxxxxxxxxx", 29 | .date = "yyyyyyyyyyyyyyy", 30 | .idf_ver = "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz", 31 | .app_elf_sha256 = { 32 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 34 | }, 35 | .min_efuse_blk_rev_full = 0xffff, 36 | .max_efuse_blk_rev_full = 0xffff, 37 | .mmu_page_size = 0, 38 | .reserv3 = {0xff, 0xff, 0xff}, 39 | .reserv2 = { 40 | 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 41 | 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 42 | 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 43 | 0xffffffff, 0xffffffff, 0xffffffff 44 | }, 45 | }; -------------------------------------------------------------------------------- /test/elf2image/esp8266-nonossdkv12-example.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/elf2image/esp8266-nonossdkv12-example.elf -------------------------------------------------------------------------------- /test/elf2image/esp8266-nonossdkv20-at-v2.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/elf2image/esp8266-nonossdkv20-at-v2.elf -------------------------------------------------------------------------------- /test/elf2image/esp8266-nonosssdk20-iotdemo.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/elf2image/esp8266-nonosssdk20-iotdemo.elf -------------------------------------------------------------------------------- /test/elf2image/esp8266-openrtos-blink-v2.elf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/elf2image/esp8266-openrtos-blink-v2.elf -------------------------------------------------------------------------------- /test/images/aes_key.bin: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/images/bootloader_esp32.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/bootloader_esp32.bin -------------------------------------------------------------------------------- /test/images/bootloader_esp32_v5_2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/bootloader_esp32_v5_2.bin -------------------------------------------------------------------------------- /test/images/bootloader_esp32c3.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/bootloader_esp32c3.bin -------------------------------------------------------------------------------- /test/images/bootloader_esp8266.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/bootloader_esp8266.bin -------------------------------------------------------------------------------- /test/images/efuse/128bit: -------------------------------------------------------------------------------- 1 |  2 |  -------------------------------------------------------------------------------- /test/images/efuse/128bit_key: -------------------------------------------------------------------------------- 1 |  2 |  -------------------------------------------------------------------------------- /test/images/efuse/192bit: -------------------------------------------------------------------------------- 1 |   -------------------------------------------------------------------------------- /test/images/efuse/192bit_1: -------------------------------------------------------------------------------- 1 |  2 | ! -------------------------------------------------------------------------------- /test/images/efuse/192bit_2: -------------------------------------------------------------------------------- 1 | " 2 | " -------------------------------------------------------------------------------- /test/images/efuse/224bit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/efuse/224bit -------------------------------------------------------------------------------- /test/images/efuse/256bit: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/efuse/256bit -------------------------------------------------------------------------------- /test/images/efuse/256bit_1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/efuse/256bit_1 -------------------------------------------------------------------------------- /test/images/efuse/256bit_1_256bit_2_combined: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/efuse/256bit_1_256bit_2_combined -------------------------------------------------------------------------------- /test/images/efuse/256bit_2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/efuse/256bit_2 -------------------------------------------------------------------------------- /test/images/efuse/256bit_3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/efuse/256bit_3 -------------------------------------------------------------------------------- /test/images/efuse/64bit: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /test/images/efuse/92bit: -------------------------------------------------------------------------------- 1 |  -------------------------------------------------------------------------------- /test/images/efuse/96bit: -------------------------------------------------------------------------------- 1 |  2 | -------------------------------------------------------------------------------- /test/images/efuse/esp_efuse_custom_table.csv: -------------------------------------------------------------------------------- 1 | # field_name, | efuse_block, | bit_start, | bit_count, | comment 2 | MODULE_VERSION, EFUSE_BLK3, 56, 8, Module version 3 | DEVICE_ROLE, EFUSE_BLK3, 64, 3, Device role 4 | SETTING_1, EFUSE_BLK3, 67, 6, [SETTING_1_ALT_NAME] Setting 1 5 | SETTING_2, EFUSE_BLK3, 73, 5, Setting 2 6 | ID_NUM, EFUSE_BLK3, 140, 8, [MY_ID_NUM] comment 7 | , EFUSE_BLK3, 132, 8, [MY_ID_NUM] comment 8 | , EFUSE_BLK3, 122, 8, [MY_ID_NUM] comment 9 | CUSTOM_SECURE_VERSION, EFUSE_BLK3, 78, 16, Custom secure version 10 | ID_NUMK, EFUSE_BLK3, 150, 8, [MY_ID_NUMK] comment 11 | , EFUSE_BLK3, 182, 8, [MY_ID_NUMK] comment 12 | MY_DATA, EFUSE_BLK3, 190, 10, My data 13 | MY_DATA.FIELD1, EFUSE_BLK3, 190, 7, Field1 -------------------------------------------------------------------------------- /test/images/esp32c3_header_min_rev.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/esp32c3_header_min_rev.bin -------------------------------------------------------------------------------- /test/images/esp32s3_header.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/esp32s3_header.bin -------------------------------------------------------------------------------- /test/images/esp8266_deepsleep.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/esp8266_deepsleep.bin -------------------------------------------------------------------------------- /test/images/esp_idf_blink_esp32s2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/esp_idf_blink_esp32s2.bin -------------------------------------------------------------------------------- /test/images/fifty_kb.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/fifty_kb.bin -------------------------------------------------------------------------------- /test/images/not_4_byte_aligned.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/not_4_byte_aligned.bin -------------------------------------------------------------------------------- /test/images/one_kb.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/one_kb.bin -------------------------------------------------------------------------------- /test/images/one_kb_all_ef.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/one_kb_all_ef.bin -------------------------------------------------------------------------------- /test/images/one_mb.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/one_mb.bin -------------------------------------------------------------------------------- /test/images/onebyte.bin: -------------------------------------------------------------------------------- 1 | a -------------------------------------------------------------------------------- /test/images/partitions_singleapp.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/partitions_singleapp.bin -------------------------------------------------------------------------------- /test/images/ram_helloworld/helloworld-esp32.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/ram_helloworld/helloworld-esp32.bin -------------------------------------------------------------------------------- /test/images/ram_helloworld/helloworld-esp32_edit.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/ram_helloworld/helloworld-esp32_edit.bin -------------------------------------------------------------------------------- /test/images/ram_helloworld/helloworld-esp32c2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/ram_helloworld/helloworld-esp32c2.bin -------------------------------------------------------------------------------- /test/images/ram_helloworld/helloworld-esp32c3.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/ram_helloworld/helloworld-esp32c3.bin -------------------------------------------------------------------------------- /test/images/ram_helloworld/helloworld-esp32c5.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/ram_helloworld/helloworld-esp32c5.bin -------------------------------------------------------------------------------- /test/images/ram_helloworld/helloworld-esp32c6.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/ram_helloworld/helloworld-esp32c6.bin -------------------------------------------------------------------------------- /test/images/ram_helloworld/helloworld-esp32c61.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/ram_helloworld/helloworld-esp32c61.bin -------------------------------------------------------------------------------- /test/images/ram_helloworld/helloworld-esp32h2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/ram_helloworld/helloworld-esp32h2.bin -------------------------------------------------------------------------------- /test/images/ram_helloworld/helloworld-esp32p4.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/ram_helloworld/helloworld-esp32p4.bin -------------------------------------------------------------------------------- /test/images/ram_helloworld/helloworld-esp32s3.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/ram_helloworld/helloworld-esp32s3.bin -------------------------------------------------------------------------------- /test/images/ram_helloworld/helloworld-esp8266.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/ram_helloworld/helloworld-esp8266.bin -------------------------------------------------------------------------------- /test/images/ram_helloworld/source/ld/app_32.ld: -------------------------------------------------------------------------------- 1 | MEMORY { 2 | iram : org = 0x4008c000, len = 0x1000 3 | dram : org = 0x3ffc0000, len = 0xc000 4 | } 5 | 6 | ENTRY(ram_main) 7 | 8 | SECTIONS { 9 | .text : ALIGN(4) { 10 | *(.literal) 11 | *(.text .text.*) 12 | } > iram 13 | 14 | .bss : ALIGN(4) { 15 | _bss_start = ABSOLUTE(.); 16 | *(.bss) 17 | _bss_end = ABSOLUTE(.); 18 | } > dram 19 | 20 | .data : ALIGN(4) { 21 | *(.data) 22 | *(.rodata .rodata.*) 23 | } > dram 24 | } 25 | 26 | INCLUDE "../../../../flasher_stub/ld/rom_32.ld" 27 | -------------------------------------------------------------------------------- /test/images/ram_helloworld/source/ld/app_32c2.ld: -------------------------------------------------------------------------------- 1 | MEMORY { 2 | iram : org = 0x40390000, len = 0x100 3 | dram : org = 0x3FCD0000, len = 0x100 4 | } 5 | 6 | ENTRY(ram_main) 7 | 8 | SECTIONS { 9 | .text : ALIGN(4) { 10 | *(.literal) 11 | *(.text .text.*) 12 | } > iram 13 | 14 | .bss : ALIGN(4) { 15 | _bss_start = ABSOLUTE(.); 16 | *(.bss) 17 | _bss_end = ABSOLUTE(.); 18 | } > dram 19 | 20 | .data : ALIGN(4) { 21 | *(.data) 22 | *(.rodata .rodata.*) 23 | } > dram 24 | } 25 | 26 | INCLUDE "../../../../flasher_stub/ld/rom_32c2.ld" 27 | -------------------------------------------------------------------------------- /test/images/ram_helloworld/source/ld/app_32c3.ld: -------------------------------------------------------------------------------- 1 | MEMORY { 2 | iram : org = 0x403DFD00, len = 0x100 3 | dram : org = 0x3FCDFD00, len = 0x100 4 | } 5 | 6 | ENTRY(ram_main) 7 | 8 | SECTIONS { 9 | .text : ALIGN(4) { 10 | *(.literal) 11 | *(.text .text.*) 12 | } > iram 13 | 14 | .bss : ALIGN(4) { 15 | _bss_start = ABSOLUTE(.); 16 | *(.bss) 17 | _bss_end = ABSOLUTE(.); 18 | } > dram 19 | 20 | .data : ALIGN(4) { 21 | *(.data) 22 | *(.rodata .rodata.*) 23 | } > dram 24 | } 25 | 26 | INCLUDE "../../../../flasher_stub/ld/rom_32c3.ld" 27 | -------------------------------------------------------------------------------- /test/images/ram_helloworld/source/ld/app_32c5.ld: -------------------------------------------------------------------------------- 1 | MEMORY { 2 | iram : org = 0x40810f5c, len = 0x100 3 | dram : org = 0x4081105c, len = 0x100 4 | } 5 | 6 | ENTRY(ram_main) 7 | 8 | SECTIONS { 9 | .text : ALIGN(4) { 10 | *(.literal) 11 | *(.text .text.*) 12 | } > iram 13 | 14 | .bss : ALIGN(4) { 15 | _bss_start = ABSOLUTE(.); 16 | *(.bss) 17 | _bss_end = ABSOLUTE(.); 18 | } > dram 19 | 20 | .data : ALIGN(4) { 21 | *(.data) 22 | *(.rodata .rodata.*) 23 | } > dram 24 | } 25 | 26 | INCLUDE "../../../../flasher_stub/ld/rom_32c5.ld" 27 | -------------------------------------------------------------------------------- /test/images/ram_helloworld/source/ld/app_32c6.ld: -------------------------------------------------------------------------------- 1 | MEMORY { 2 | iram : org = 0x40860000, len = 0x100 3 | dram : org = 0x40870000, len = 0x100 4 | } 5 | 6 | ENTRY(ram_main) 7 | 8 | SECTIONS { 9 | .text : ALIGN(4) { 10 | *(.literal) 11 | *(.text .text.*) 12 | } > iram 13 | 14 | .bss : ALIGN(4) { 15 | _bss_start = ABSOLUTE(.); 16 | *(.bss) 17 | _bss_end = ABSOLUTE(.); 18 | } > dram 19 | 20 | .data : ALIGN(4) { 21 | *(.data) 22 | *(.rodata .rodata.*) 23 | } > dram 24 | } 25 | 26 | INCLUDE "../../../../flasher_stub/ld/rom_32c6.ld" 27 | -------------------------------------------------------------------------------- /test/images/ram_helloworld/source/ld/app_32c61.ld: -------------------------------------------------------------------------------- 1 | MEMORY { 2 | iram : org = 0x40830000, len = 0x100 3 | dram : org = 0x40830100, len = 0x100 4 | } 5 | 6 | ENTRY(ram_main) 7 | 8 | SECTIONS { 9 | .text : ALIGN(4) { 10 | *(.literal) 11 | *(.text .text.*) 12 | } > iram 13 | 14 | .bss : ALIGN(4) { 15 | _bss_start = ABSOLUTE(.); 16 | *(.bss) 17 | _bss_end = ABSOLUTE(.); 18 | } > dram 19 | 20 | .data : ALIGN(4) { 21 | *(.data) 22 | *(.rodata .rodata.*) 23 | } > dram 24 | } 25 | 26 | INCLUDE "../../../../flasher_stub/ld/rom_32c61.ld" 27 | -------------------------------------------------------------------------------- /test/images/ram_helloworld/source/ld/app_32h2.ld: -------------------------------------------------------------------------------- 1 | MEMORY { 2 | iram : org = 0x40804000, len = 0x100 3 | dram : org = 0x40848000, len = 0x100 4 | } 5 | 6 | ENTRY(ram_main) 7 | 8 | SECTIONS { 9 | .text : ALIGN(4) { 10 | *(.literal) 11 | *(.text .text.*) 12 | } > iram 13 | 14 | .bss : ALIGN(4) { 15 | _bss_start = ABSOLUTE(.); 16 | *(.bss) 17 | _bss_end = ABSOLUTE(.); 18 | } > dram 19 | 20 | .data : ALIGN(4) { 21 | *(.data) 22 | *(.rodata .rodata.*) 23 | } > dram 24 | } 25 | 26 | INCLUDE "../../../../flasher_stub/ld/rom_32h2.ld" 27 | -------------------------------------------------------------------------------- /test/images/ram_helloworld/source/ld/app_32p4.ld: -------------------------------------------------------------------------------- 1 | MEMORY { 2 | iram : org = 0x4FF60000, len = 0x100 3 | dram : org = 0x4FF70000, len = 0x100 4 | } 5 | 6 | ENTRY(ram_main) 7 | 8 | SECTIONS { 9 | .text : ALIGN(4) { 10 | *(.literal) 11 | *(.text .text.*) 12 | } > iram 13 | 14 | .bss : ALIGN(4) { 15 | _bss_start = ABSOLUTE(.); 16 | *(.bss) 17 | _bss_end = ABSOLUTE(.); 18 | } > dram 19 | 20 | .data : ALIGN(4) { 21 | *(.data) 22 | *(.rodata .rodata.*) 23 | } > dram 24 | } 25 | 26 | INCLUDE "../../../../flasher_stub/ld/rom_32p4.ld" 27 | -------------------------------------------------------------------------------- /test/images/ram_helloworld/source/ld/app_32s2.ld: -------------------------------------------------------------------------------- 1 | MEMORY { 2 | iram : org = 0x40020000, len = 0x8000 3 | dram : org = 0x3FFC8000, len = 0x8000 4 | } 5 | 6 | ENTRY(ram_main) 7 | 8 | SECTIONS { 9 | .text : ALIGN(4) { 10 | *(.literal) 11 | *(.text .text.*) 12 | } > iram 13 | 14 | .bss : ALIGN(4) { 15 | _bss_start = ABSOLUTE(.); 16 | *(.bss) 17 | _bss_end = ABSOLUTE(.); 18 | } > dram 19 | 20 | .data : ALIGN(4) { 21 | *(.data) 22 | *(.rodata .rodata.*) 23 | } > dram 24 | } 25 | 26 | INCLUDE "../../../../flasher_stub/ld/rom_32s2.ld" 27 | -------------------------------------------------------------------------------- /test/images/ram_helloworld/source/ld/app_32s3.ld: -------------------------------------------------------------------------------- 1 | MEMORY { 2 | iram : org = 0x40380000, len = 0x100 3 | dram : org = 0x3FCA0000, len = 0x100 4 | } 5 | 6 | ENTRY(ram_main) 7 | 8 | SECTIONS { 9 | .text : ALIGN(4) { 10 | *(.literal) 11 | *(.text .text.*) 12 | } > iram 13 | 14 | .bss : ALIGN(4) { 15 | _bss_start = ABSOLUTE(.); 16 | *(.bss) 17 | _bss_end = ABSOLUTE(.); 18 | } > dram 19 | 20 | .data : ALIGN(4) { 21 | *(.data) 22 | *(.rodata .rodata.*) 23 | } > dram 24 | } 25 | 26 | INCLUDE "../../../../flasher_stub/ld/rom_32s3.ld" 27 | -------------------------------------------------------------------------------- /test/images/ram_helloworld/source/ld/app_8266.ld: -------------------------------------------------------------------------------- 1 | MEMORY { 2 | iram : org = 0x40108000, len = 0x2000 3 | dram : org = 0x3FFE8000, len = 0x100 4 | } 5 | 6 | ENTRY(ram_main) 7 | 8 | SECTIONS { 9 | .text : ALIGN(4) { 10 | *(.literal) 11 | *(.text .text.*) 12 | } > iram 13 | 14 | .bss : ALIGN(4) { 15 | _bss_start = ABSOLUTE(.); 16 | *(.bss) 17 | _bss_end = ABSOLUTE(.); 18 | } > dram 19 | 20 | .data : ALIGN(4) { 21 | *(.data) 22 | *(.rodata .rodata.*) 23 | } > dram 24 | } 25 | 26 | INCLUDE "../../../../flasher_stub/ld/rom_8266.ld" 27 | 28 | PROVIDE(SPIFlashModeConfig = 0x40004568); 29 | PROVIDE(SPIParamCfg = 0x40004c2c); 30 | -------------------------------------------------------------------------------- /test/images/ram_helloworld/source/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void ets_printf(const char *s); // not the correct prototype, but should be enough! 4 | 5 | void __attribute__((noreturn)) ram_main() 6 | { 7 | while (1) { 8 | ets_printf("Hello world!\n"); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/images/sector.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/sector.bin -------------------------------------------------------------------------------- /test/images/zerolength.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/images/zerolength.bin -------------------------------------------------------------------------------- /test/secure_images/256bit_iv.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/256bit_iv.bin -------------------------------------------------------------------------------- /test/secure_images/256bit_key.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/256bit_key.bin -------------------------------------------------------------------------------- /test/secure_images/512bit_key.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/512bit_key.bin -------------------------------------------------------------------------------- /test/secure_images/bootloader-encrypted-aes-xts.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/bootloader-encrypted-aes-xts.bin -------------------------------------------------------------------------------- /test/secure_images/bootloader-encrypted-conf0.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/bootloader-encrypted-conf0.bin -------------------------------------------------------------------------------- /test/secure_images/bootloader-encrypted-conf3.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/bootloader-encrypted-conf3.bin -------------------------------------------------------------------------------- /test/secure_images/bootloader-encrypted-conf9.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/bootloader-encrypted-conf9.bin -------------------------------------------------------------------------------- /test/secure_images/bootloader-encrypted-confc.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/bootloader-encrypted-confc.bin -------------------------------------------------------------------------------- /test/secure_images/bootloader-encrypted.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/bootloader-encrypted.bin -------------------------------------------------------------------------------- /test/secure_images/bootloader.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/bootloader.bin -------------------------------------------------------------------------------- /test/secure_images/bootloader_digested.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/bootloader_digested.bin -------------------------------------------------------------------------------- /test/secure_images/bootloader_multi_signed_v2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/bootloader_multi_signed_v2.bin -------------------------------------------------------------------------------- /test/secure_images/bootloader_signed.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/bootloader_signed.bin -------------------------------------------------------------------------------- /test/secure_images/bootloader_signed_v2_ecdsa192.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/bootloader_signed_v2_ecdsa192.bin -------------------------------------------------------------------------------- /test/secure_images/bootloader_signed_v2_ecdsa256.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/bootloader_signed_v2_ecdsa256.bin -------------------------------------------------------------------------------- /test/secure_images/bootloader_signed_v2_ecdsa384.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/bootloader_signed_v2_ecdsa384.bin -------------------------------------------------------------------------------- /test/secure_images/bootloader_signed_v2_rsa.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/bootloader_signed_v2_rsa.bin -------------------------------------------------------------------------------- /test/secure_images/bootloader_unsigned_v2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/bootloader_unsigned_v2.bin -------------------------------------------------------------------------------- /test/secure_images/digest_iv.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/digest_iv.bin -------------------------------------------------------------------------------- /test/secure_images/ecdsa192_public_key_digest_v2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/ecdsa192_public_key_digest_v2.bin -------------------------------------------------------------------------------- /test/secure_images/ecdsa192_secure_boot_signing_key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MF8CAQEEGDgqTbDQIFX5seT7lyWPCzJnHXu+0uV8LaAKBggqhkjOPQMBAaE0AzIA 3 | BCMqf3dGSg3CVZTCKeAMmPQ7C7zDNEnQHfMBUFGypYiI/pvuHagTiBXf8nUg6cKD 4 | Rw== 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /test/secure_images/ecdsa192_secure_boot_signing_key2.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MF8CAQEEGN8BlXFldc9m6wFIYcvhcWQGqk6QbeNIu6AKBggqhkjOPQMBAaE0AzIA 3 | BHfat0gF2icTWTD9v9Aj+pXei8Ua7canoHoPzuGwNY1lJr9C1LhYPPfnJU5olnbM 4 | ZA== 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /test/secure_images/ecdsa192_secure_boot_signing_key_v2.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MF8CAQEEGE9xt5UjgSPLFIb1BnykBMu9BQWeYl3EyKAKBggqhkjOPQMBAaE0AzIA 3 | BF3CvK6wDL6/jyjhm5gDGmCGI4CvrIgFi5hGOLBJeD18kL1LpnPi3NVNaWjoArvD 4 | uw== 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /test/secure_images/ecdsa192_secure_boot_signing_pubkey.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MEkwEwYHKoZIzj0CAQYIKoZIzj0DAQEDMgAEIyp/d0ZKDcJVlMIp4AyY9DsLvMM0 3 | SdAd8wFQUbKliIj+m+4dqBOIFd/ydSDpwoNH 4 | -----END PUBLIC KEY----- 5 | -------------------------------------------------------------------------------- /test/secure_images/ecdsa192_secure_boot_signing_pubkey2.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MEkwEwYHKoZIzj0CAQYIKoZIzj0DAQEDMgAEd9q3SAXaJxNZMP2/0CP6ld6LxRrt 3 | xqegeg/O4bA1jWUmv0LUuFg89+clTmiWdsxk 4 | -----END PUBLIC KEY----- 5 | -------------------------------------------------------------------------------- /test/secure_images/ecdsa256_public_key_digest_v2.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/ecdsa256_public_key_digest_v2.bin -------------------------------------------------------------------------------- /test/secure_images/ecdsa256_secure_boot_signing_key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MHcCAQEEIOI40eSC7ch6PxDSIclIGFCjfhCoXfHVqbbDn8XdY0GVoAoGCCqGSM49 3 | AwEHoUQDQgAENM762z/ushk+c0XOIYpi8wLSWuF5COnU0VAQnt3spTSX6l3bpwfu 4 | ppsemDdwy+aKbdgeyMYDxFbROLOPTRbYJw== 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /test/secure_images/ecdsa256_secure_boot_signing_key2.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MHcCAQEEIP9iY7XY8g3qSaUkKwTbq6HEq/AwenIxrssLqXGTS0z3oAoGCCqGSM49 3 | AwEHoUQDQgAEG+Ah4OAejTBYKQNvJkEOP9AifgulBMr4E9f+OqRU1Uno9Efi1kMc 4 | fzwZyx0A4mib0HfLUg9JNh8dNrUxLeVb4Q== 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /test/secure_images/ecdsa256_secure_boot_signing_key_pkcs8.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg4jjR5ILtyHo/ENIh 3 | yUgYUKN+EKhd8dWptsOfxd1jQZWhRANCAAQ0zvrbP+6yGT5zRc4himLzAtJa4XkI 4 | 6dTRUBCe3eylNJfqXdunB+6mmx6YN3DL5opt2B7IxgPEVtE4s49NFtgn 5 | -----END PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /test/secure_images/ecdsa256_secure_boot_signing_key_v2.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MHcCAQEEILRUiyOQBmpmw50IeoRQwjgbBpHtBTSNiDt9N2R17Gv8oAoGCCqGSM49 3 | AwEHoUQDQgAEDixPrWrLYPuiolKmwJYRDDBDMHp+uOctcIOkiJCITukaV/ZBsyzj 4 | NtOob4eat2+WZtnH6icto557WqjESHcEkA== 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /test/secure_images/ecdsa256_secure_boot_signing_pubkey.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAENM762z/ushk+c0XOIYpi8wLSWuF5 3 | COnU0VAQnt3spTSX6l3bpwfuppsemDdwy+aKbdgeyMYDxFbROLOPTRbYJw== 4 | -----END PUBLIC KEY----- 5 | -------------------------------------------------------------------------------- /test/secure_images/ecdsa256_secure_boot_signing_pubkey2.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEG+Ah4OAejTBYKQNvJkEOP9Aifgul 3 | BMr4E9f+OqRU1Uno9Efi1kMcfzwZyx0A4mib0HfLUg9JNh8dNrUxLeVb4Q== 4 | -----END PUBLIC KEY----- 5 | -------------------------------------------------------------------------------- /test/secure_images/ecdsa256_secure_boot_signing_pubkey_raw.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/ecdsa256_secure_boot_signing_pubkey_raw.bin -------------------------------------------------------------------------------- /test/secure_images/ecdsa384_secure_boot_signing_key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MIGkAgEBBDBIxytBXMNRUK/28IbGjtIOfZTLrcKU8nk0zT966n0c1kFa0VdK84k0/lxnX1ukymWg 3 | BwYFK4EEACKhZANiAAQohLsM+b3/8g4A4q85TpbrVb7Z+CCkDOL90FzceloEFPY9Qt+IoIMmqxvx 4 | 0Uiz9t81CHE3+eVwoVLh7OepMJJ/lRX7leY6gLtnNYxPPpamrROAJ9BgakZ+VE9tYBlK3AY= 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /test/secure_images/ecdsa384_secure_boot_signing_key2.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MIGkAgEBBDAi/QEI621c5gFBaHyZ3JyrCXQYy5umeENn7dfHXxyM6CIKLFXWXrHOJ+xPEAvKEnqg 3 | BwYFK4EEACKhZANiAATQJep17Gl/ukPYPaoeau5WlspgrnT7pNqkq/TyJH5NYPZfuGFDzAxxaPl4 4 | PEbHAazkDNvziUUeI+CkF/M17chj7YyOFFdAJN+I+Qn38bS/yZiYVzOocGXeLWhZks3+wME= 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /test/secure_images/ecdsa384_secure_boot_signing_pubkey.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEKIS7DPm9//IOAOKvOU6W61W+2fggpAzi 3 | /dBc3HpaBBT2PULfiKCDJqsb8dFIs/bfNQhxN/nlcKFS4eznqTCSf5UV+5XmOoC7 4 | ZzWMTz6Wpq0TgCfQYGpGflRPbWAZStwG 5 | -----END PUBLIC KEY----- 6 | -------------------------------------------------------------------------------- /test/secure_images/ecdsa384_secure_boot_signing_pubkey2.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAE0CXqdexpf7pD2D2qHmruVpbKYK50+6Ta 3 | pKv08iR+TWD2X7hhQ8wMcWj5eDxGxwGs5Azb84lFHiPgpBfzNe3IY+2MjhRXQCTf 4 | iPkJ9/G0v8mYmFczqHBl3i1oWZLN/sDB 5 | -----END PUBLIC KEY----- 6 | -------------------------------------------------------------------------------- /test/secure_images/ef-flashencryption-key.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/ef-flashencryption-key.bin -------------------------------------------------------------------------------- /test/secure_images/hello-world-signed-encrypted-aes-xts-256.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/hello-world-signed-encrypted-aes-xts-256.bin -------------------------------------------------------------------------------- /test/secure_images/hello-world-signed-encrypted-aes-xts.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/hello-world-signed-encrypted-aes-xts.bin -------------------------------------------------------------------------------- /test/secure_images/hello-world-signed-encrypted.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/hello-world-signed-encrypted.bin -------------------------------------------------------------------------------- /test/secure_images/hello-world-signed.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/hello-world-signed.bin -------------------------------------------------------------------------------- /test/secure_images/pre_calculated_bootloader_signature.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/pre_calculated_bootloader_signature.bin -------------------------------------------------------------------------------- /test/secure_images/pre_calculated_bootloader_signature_ecdsa192.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/pre_calculated_bootloader_signature_ecdsa192.bin -------------------------------------------------------------------------------- /test/secure_images/pre_calculated_bootloader_signature_ecdsa256.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/pre_calculated_bootloader_signature_ecdsa256.bin -------------------------------------------------------------------------------- /test/secure_images/pre_calculated_bootloader_signature_ecdsa384.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/pre_calculated_bootloader_signature_ecdsa384.bin -------------------------------------------------------------------------------- /test/secure_images/pre_calculated_bootloader_signature_rsa.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/pre_calculated_bootloader_signature_rsa.bin -------------------------------------------------------------------------------- /test/secure_images/rsa_public_key_digest.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/espressif/esptool/89e8dd05b5100a497e4f6e7b71ad8e9f2e3e5cc6/test/secure_images/rsa_public_key_digest.bin -------------------------------------------------------------------------------- /test/secure_images/rsa_secure_boot_signing_key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIG4gIBAAKCAYEAtvnS7JPl5hGfA0Iks2lQm/L+eiw7pcAArH2IKGqryKdGCtiw 3 | uOLjZkUpNR/dZhSr/7JGvjUw+2elLY7D1XXXw3pufjVH7AePmo4EXUS4U1g6xDuc 4 | tj3hj3cOarpKo2+dEYrAwY13Bx28tOW0z2uKxQhNX3zHP9ssiTsLQ+6E+MjEvKjY 5 | cvAFtadXYtYTUZWhxuh8W2vnhOiR3zyJQL984iAl08G/T+HI/3JX3vGSFEnOP/yp 6 | qz7wQEMJwOEjVpsgaStf5N1JbSOSKp7r/aOMLQHnYHkfjWSNkX1v0QJfXl7iwtB8 7 | XVxRPftY4fdANrGTpQnUOogVo4q6mI80qJ5OuWfI+gdkxvMVnbmnNp1HtTslPGfB 8 | bF+XfQG23xEFvnYTUVvmmNX5QuHY2Vy6KpSStQmf4FGZXjQdGzxavFfQjdiBOhxi 9 | 5DEixcFpwlS1VcHRWb1G2yp15q3ukWrEkh9X4vV6h05fmdvxOk9QhHTr0XCIzC4G 10 | maUBM/UYvzGjlfwrAgMBAAECggGAVztK/1aTJ9gGwvrpnE79CxwRjhVAaojayWEf 11 | ZIVWWFbG4azks4AXgU4/kwAaAOyiA0juyQd6zqBe8xU47686qgrYWnr0SuZf5AMI 12 | uZ5lcfaCLcNttsRRoJ/V07P0mW5Ap3hK5PuYX2Ah8uwAA1L12XFX0cofA6Zt2Q65 13 | FC3GXwT4Jiko58LeNfgNhSUiGKcJdVao0rzip05pHNAzbxbbZsKExit8FY1C0eWl 14 | Vrg8OEfneEHwcZ+T0k8jezzaKBPT1S/3m3qHO5uw7l67VG7KHVNyKtwbrKwlayEU 15 | w4OJ6rwvpddXr2lrD1Nutg2fD9P0e8xKoyNsMFTr43/N2I8Zn5+ScYC4asPSIEMy 16 | 2V0NGCaL/cWfhQPUBi8M+dPitrX9QyGriM8kUp3KIqBW0LlSvMcZ4ZVtCxyTiR3S 17 | DShaWIP6ixZoudP8cxuq8ULx9KPoL5IzG/U+zzT17/T8/u7+tfIltlKP9bqn/ayQ 18 | gBiHyAR5JECooFZxxAOTuzk0oKlhAoHBAOOUHPqftoEC1iKGCu/zrLQe2tisGafC 19 | 2FkhrmAkM0eCexCtGSLGemGBD2LIZRNtcI1cy34nawrnhVEhCkyVccwv9/Txw3MB 20 | c7FjaA17MoYknEGT0VGnYVOOsWK0/2v3yfl9b7N1CS4qHaKWhpDOlgbrGTkFrMCg 21 | y9ev2cU0PwxNx+x1Jae4Zh+K2nQFLzD8lD6zyvRHzYhb+1q/YSjhHD3+xPLx9Hv+ 22 | U4uAVIvifU7pIHhMoQ3yu3QmMDYFDxwKdwKBwQDN07kzs/cYi7z3FxAGn4fMzyBX 23 | C/6U+cFaQmOi0Ds+w0fKM+0WdYDrw0qhuXMI5BK1FaE03y5AqYghBXktv+O4q8mr 24 | a77L1I3uIO4jVTkpBxjjnEbNtJCrA39VWdtupAKKpSczjmLwvzr/XYqbkyiUmxRM 25 | YukJ6fvXFmzAhGulBHSM7sEV0yzgOQBFcjSjKmf6icX8pQTzvXC7SHe7V8AtCRk1 26 | pBwg06Nyy1QYfFfCkVyF4RgwsJVvqgGu/O1pFO0CgcBF7ftBn9YKqn52OU4fEXde 27 | GaURs0Bm5l5odQsKC9WeAaAjLa1tnCN61peNuRol8BkHtx3oc+BWh3HVzhtGER3Y 28 | qly87ZUrP6T3Ox58FgEeax2AoRVOy+oCLPSg6hEachekDEFImYvqnZJhpXNQB8rd 29 | 8Vvcw7ujrUU1z5lRGY7ODxCBvjWF5gmrY5Vg1T79BH/hDIouqemkHu+LoQcP8qwk 30 | +KY4KNUBTNMLKLHSEhSDLOuHS7Spfo7PT/S8hK1x5l0CgcAyHjncgxfJ3EzZBb6b 31 | PkE897pyN7N35xDTv5KvVHD4qWhTri0u6NHJlrYXhyahpZeAjJHCZA3JJP7Gu6R0 32 | JWN31iy3FvdQfqNItrAF3nyapuXClo0PDcakPafFyqmJ2VndFLXk8ejZolblU4uq 33 | sjyRYumgZ/1Csrzl9MnqXtQvTFRs9L4DaHZm6rpMLrDugibrdJzHFg+MojZPBChT 34 | b9yVmr+OtjU7MQ19qFED3VMpR2f2GYdgY78ff5AFYgUVL0kCgcBiO0R3WqZbfW3j 35 | +TTGPEnEAnW/Te9fhvqPackVExjLyjjajXp1ce+79YjJaMUF5bPFsGY4GbJJe4k6 36 | R+j+nvs9TUl6RnX9v8tPsjGMBoj9OSXCDVJlWSw9LpBliJ5eGyJfcsFsAUZLUXlq 37 | dGYcxcsKj7M6+Rll5Nmi92+XGMsbF1Qg/9qQX38Vj9EuIn9jlpQ7Z0oyt6h4cU1C 38 | QEjvS1T2g9XpDBdXtn+JbVrQviRncDcU8GmMRsrjtzOmALi96XE= 39 | -----END RSA PRIVATE KEY----- 40 | -------------------------------------------------------------------------------- /test/secure_images/rsa_secure_boot_signing_key2.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | 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 39 | -----END RSA PRIVATE KEY----- 40 | -------------------------------------------------------------------------------- /test/secure_images/rsa_secure_boot_signing_key3.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | 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 39 | -----END RSA PRIVATE KEY----- 40 | -------------------------------------------------------------------------------- /test/secure_images/rsa_secure_boot_signing_key4.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | 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 39 | -----END RSA PRIVATE KEY----- 40 | -------------------------------------------------------------------------------- /test/secure_images/rsa_secure_boot_signing_pubkey.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAtvnS7JPl5hGfA0Iks2lQ 3 | m/L+eiw7pcAArH2IKGqryKdGCtiwuOLjZkUpNR/dZhSr/7JGvjUw+2elLY7D1XXX 4 | w3pufjVH7AePmo4EXUS4U1g6xDuctj3hj3cOarpKo2+dEYrAwY13Bx28tOW0z2uK 5 | xQhNX3zHP9ssiTsLQ+6E+MjEvKjYcvAFtadXYtYTUZWhxuh8W2vnhOiR3zyJQL98 6 | 4iAl08G/T+HI/3JX3vGSFEnOP/ypqz7wQEMJwOEjVpsgaStf5N1JbSOSKp7r/aOM 7 | LQHnYHkfjWSNkX1v0QJfXl7iwtB8XVxRPftY4fdANrGTpQnUOogVo4q6mI80qJ5O 8 | uWfI+gdkxvMVnbmnNp1HtTslPGfBbF+XfQG23xEFvnYTUVvmmNX5QuHY2Vy6KpSS 9 | tQmf4FGZXjQdGzxavFfQjdiBOhxi5DEixcFpwlS1VcHRWb1G2yp15q3ukWrEkh9X 10 | 4vV6h05fmdvxOk9QhHTr0XCIzC4GmaUBM/UYvzGjlfwrAgMBAAE= 11 | -----END PUBLIC KEY----- 12 | -------------------------------------------------------------------------------- /test/secure_images/rsa_secure_boot_signing_pubkey2.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAsM8ZHltWA8BfpCH1+xrm 3 | unmRCnzxZMjYsl069V7zkZlzKNHm7n76Q0+Jqb4g0uDzY3YD3hQAZTyCYxYjcgVm 4 | 4PQDSedkpWjkovKDJrvUIb3YzCGfoOOdj1vaJhGAH9COpJJJgvJG5fgvor7ERxFt 5 | q6/kTR2Dmipkc0CwrZi1CsBomcHKfUAEfuWY2hd2F4tmyN3Q/jObRUpk3XjPzFJP 6 | QDgnjgkxYHtUq9psalCqR8hjAx+pQHyGOMLNYSK0RwqslbvXy0dheLjlUPg84Z/g 7 | a4eYqboRy8wsiG+vRRgl4oYxIxg36WqurwaRu+8nUCO3zqQDff3yaN/lGlYfJojQ 8 | ihNto8opB5rTdRW/Obs0qE6nSf1WQMfG6ercRoMHx2alRgr1GRFe8QCm+nQsWnY7 9 | DOIy5U3usmQH9kjOBSYvHHvDbXvgyYRA3EHicWjh4akhtlbFosZeBZbK6NrsuKC8 10 | gc0UIpd8OcXmEudUEg34ezoLOs0gd4LI7hMt1c9UKofpAgMBAAE= 11 | -----END PUBLIC KEY----- 12 | -------------------------------------------------------------------------------- /test/secure_images/rsa_secure_boot_signing_pubkey4.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEApY+yGcE5s0hecfgMuIiv 3 | 5s4wr4Xkx+DPWs3r2fdZeUulpKtoh5QZ5QG2OFivx1ASBA4bN4NjuCzO+M83OLrC 4 | U8nCr4J1WLejOgJHabrvlAqYrRt6WF9ZQaw0feVasC13b96PgC80GgU6KhiLhJla 5 | hQLFC7F/Cyh14j5P31SCb3isSlIP6VN/PK73RETWwV+Ie3zxIrMeF2mpumLrW4U5 6 | YBt8PNQ1eAWmlUYD1iMGXZeZ9u/DRuhHGxTR4KCSov5/F14+Rb3L0eajYAQcyypU 7 | tDHLc7m62EAICqK2uHl3QX9+xnXnj2cfYUhDiQ1S6WJyVo9RTCx8qCYMVPt4c1DU 8 | rG+1dWKXFS5rQuQ9FaDNlE7sH1+QoBmyWRO9esIVOPFVXHa0E7VCVQQFpH833yCV 9 | JrqCiCCtlVaUDpvXbZWftJHgAXPWE9uecAMUjB+7qW5SXYfbiQsZPi9cnEZTyRs8 10 | jcQwA+1DDhY8SpzRe3+36ooJQ5WJDeCps/3y4STSgs1dAgMBAAE= 11 | -----END PUBLIC KEY----- 12 | -------------------------------------------------------------------------------- /test/sitecustomize.py: -------------------------------------------------------------------------------- 1 | try: 2 | import coverage 3 | 4 | coverage.process_startup() 5 | except ModuleNotFoundError: 6 | print("Coverage.py is not installed, skipping code coverage measurement") 7 | 8 | # This file exists to perform arbitrary site-specific customizations. 9 | # This script is executed before every Python process to start coverage measurement. 10 | -------------------------------------------------------------------------------- /test/test_esptool_sdm.py: -------------------------------------------------------------------------------- 1 | # Unit tests (really integration tests) for esptool.py using the pytest framework 2 | # Uses a device in the Secure Download Mode connected to the serial port. 3 | # 4 | # RUNNING THIS WILL MESS UP THE DEVICE'S SPI FLASH CONTENTS 5 | # 6 | # How to use: 7 | # 8 | # Run with a physical connection to a chip: 9 | # - `pytest test_esptool_sdm.py --chip esp32 --port /dev/ttyUSB0 --baud 115200` 10 | # 11 | # where - --port - a serial port for esptool.py operation 12 | # - --chip - ESP chip name 13 | # - --baud - baud rate 14 | # - --with-trace - trace all interactions (True or False) 15 | 16 | from test_esptool import EsptoolTestCase, arg_chip, esptool, pytest 17 | 18 | 19 | @pytest.mark.skipif( 20 | arg_chip == "esp8266", reason="ESP8266 does not support Secure Download Mode" 21 | ) 22 | class TestSecureDownloadMode(EsptoolTestCase): 23 | expected_chip_name = esptool.util.expand_chip_name(arg_chip) 24 | 25 | @pytest.mark.skipif( 26 | arg_chip in ("esp8266", "esp32"), 27 | reason="No get-security-info on ESP8266 and ESP32", 28 | ) 29 | def test_auto_detect(self): 30 | output = self.run_esptool("get-security-info", chip="auto") 31 | 32 | if arg_chip == "esp32s2": # no autodetection from security info, only magic no. 33 | assert "Secure Download Mode is enabled" in output 34 | assert "autodetection will not work" in output 35 | else: 36 | assert f"Detecting chip type... {self.expected_chip_name}" in output 37 | assert ( 38 | f"{'Chip type:':<20}{self.expected_chip_name} " 39 | "in Secure Download Mode" in output 40 | ) 41 | 42 | # Commands not supported in SDM 43 | def test_sdm_incompatible_commands(self): 44 | output = self.run_esptool_error("flash-id") # flash-id 45 | assert "The 'flash-id' command is not available" in output 46 | 47 | output = self.run_esptool_error("read-flash 0 10 out.bin") # read-flash 48 | assert "The 'read-flash' command is not available" in output 49 | 50 | # Commands supported in SDM 51 | def test_sdm_compatible_commands(self): 52 | output = self.run_esptool("write-flash 0x0 images/one_kb.bin") # write-flash 53 | assert "Security features enabled, so not changing any flash settings" in output 54 | assert "Wrote 1024 bytes" in output 55 | assert "Hash of data verified." not in output # Verification not supported 56 | 57 | output = self.run_esptool_error( 58 | "write-flash --flash-size detect 0x0 images/one_kb.bin" 59 | ) 60 | assert ( 61 | "Detecting flash size is not supported in secure download mode." in output 62 | ) 63 | 64 | output = self.run_esptool("erase-region 0 4096") # erase-region 65 | assert "Stub flasher is not supported in Secure Download Mode" in output 66 | assert "Flash memory region erased successfully" in output 67 | 68 | if arg_chip != "esp32": # esp32 does not support get-security-info 69 | output = self.run_esptool("get-security-info") 70 | assert "Security Information:" in output 71 | -------------------------------------------------------------------------------- /test/test_modules.py: -------------------------------------------------------------------------------- 1 | # Tests for regressions in python modules 2 | # used by esptool.py, espefuse.py, and espsecure.py 3 | 4 | import pytest 5 | 6 | import reedsolo 7 | 8 | 9 | @pytest.mark.host_test 10 | def test_reed_solomon_encoding(): 11 | # fmt: off 12 | pairs = [("a0a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbdbebf", "0404992ae0b12cb0ef0d4fd3"), 13 | ("11a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbd11bf", "e001803c2130884c190d57d5"), 14 | ("22a1a2a3a4a5a6a7a8a9aaabacadaeafb0b1b2b3b4b5b6b7b8b9babbbcbd22bf", "6c32056dd3fcc33fa6193773"), 15 | ("0a1a2a3a4a5a6a7a8a9aaabacadaeafa0b1b2b3b4b5b6b7b8b9babbbcbdbebfb", "08149eef461af628943c2661"), 16 | ("b3f455fb0b275123dec0e73c4becca19246bf2b103df401844a3bdcd3fd01a95", "500409183fa1b8e680568da7"), 17 | ("435777773fb1e36f7d6b5f1e99afaa7a57f16be0ed36bc057c7dae6a266d1504", "815d3007153d797bd6630d0e"), 18 | ("20a126c10f50ee871f43cfcfe4e62a492e3f729a6c48348a58863f3a482a69fe", "36150928f41dcacf396c0893"), 19 | ("a8d5fbda18d75605c422d2b10ac7f73283a5c9609d6b8c90ffaa96b84f133582", "a4f21330282242c9e20b6acf"), 20 | ("4296abb9a44432c8656d5605feffc25d71941fd0abf0ff0d61a01a19315a264c", "1bb4c3afd14b9023b33a2f15"), 21 | ("206e4f83f8173635d7d554d96b84586fbc3a4280b4403cba5834d3dc8e99a682", "1b7edac989c569cb08f9efd9"), 22 | ("57e8dc1b37c6b53a428fc6d7242114eaf3d80b0447bb642703120a257cf7ec52", "5ee82f785f3d5e19df92635b"), 23 | ("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", "13a36292597404257375e0aa"), 24 | ("f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0", "f66cb1ba3ee5d164a19668a0"), 25 | ("abad1deaabad1deaabad1deaabad1deaabad1deaabad1deaabad1deaabad1dea", "1171924a9b34c16878e182a5"), 26 | ("abad1deadeadbeefabadbabecafebabe11223344556677889900aabbccddeeff", "7601266085196663727c6522"), 27 | ("0000000000000000000000000000000000000000000000000000000000000000", "000000000000000000000000"), 28 | ("1000000000000000000000000000000000000000000000000000000000000000", "b6f06eae2266cc0bfca685ca"), 29 | ("0001000100010001000a000b000c000d000e000f000100010001000100010001", "6dc2afb4820bb002d9263544"), 30 | ("0000000000000000000000000000000000000000000000000000000000000001", "44774376dc1f07545c7fd561"), 31 | ] # Pregenerated pairs consisting of 32 bytes of data + 12 bytes of RS ECC (FPGA verified) 32 | # fmt: on 33 | 34 | rs = reedsolo.RSCodec(12) # 12 ECC symbols 35 | 36 | for pair in pairs: 37 | bin_base = bytearray.fromhex(pair[0]) 38 | # Encode the original 32 bytes of data 39 | encoded_data = rs.encode([x for x in bin_base]) 40 | assert encoded_data == bytearray.fromhex(pair[0] + pair[1]) 41 | -------------------------------------------------------------------------------- /test/test_uf2_ids.py: -------------------------------------------------------------------------------- 1 | import json 2 | 3 | from conftest import need_to_install_package_err 4 | 5 | import pytest 6 | 7 | import requests 8 | 9 | try: 10 | from esptool.targets import CHIP_DEFS 11 | except ImportError: 12 | need_to_install_package_err() 13 | 14 | 15 | FAMILIES_URL = ( 16 | "https://raw.githubusercontent.com/microsoft/uf2/master/utils/uf2families.json" 17 | ) 18 | 19 | 20 | @pytest.fixture(scope="class") 21 | def uf2_json(): 22 | """Download UF2 family IDs from Microsoft UF2 repo and filter out ESP chips""" 23 | res = requests.get(FAMILIES_URL) 24 | assert res.status_code == 200 25 | uf2_families_json = json.loads(res.content) 26 | # filter out just ESP chips 27 | chips = [ 28 | chip 29 | for chip in uf2_families_json 30 | if chip["short_name"].upper().startswith("ESP") 31 | ] 32 | return chips 33 | 34 | 35 | def test_check_uf2family_ids(uf2_json): 36 | """Compare UF2 family IDs from Microsoft UF2 repo and with stored values""" 37 | # check if all UF2 family ids match 38 | for chip in uf2_json: 39 | assert int(chip["id"], 0) == CHIP_DEFS[chip["short_name"].lower()].UF2_FAMILY_ID 40 | 41 | 42 | def test_check_uf2(uf2_json): 43 | """Check if all non-beta chip definition has UF2 family id in esptool 44 | and also in Microsoft repo 45 | """ 46 | # remove beta chip definitions 47 | esptool_chips = set( 48 | [chip.upper() for chip in CHIP_DEFS.keys() if "beta" not in chip] 49 | ) 50 | microsoft_repo_chips = set([chip["short_name"] for chip in uf2_json]) 51 | diff = esptool_chips.symmetric_difference(microsoft_repo_chips) 52 | if diff: 53 | out = [] 54 | # there was a difference between the chip support 55 | for chip in diff: 56 | if chip not in esptool_chips: 57 | out.append( 58 | f"Missing chip definition for '{chip}' in esptool " 59 | "which was defined in Microsoft UF2 Github repo." 60 | ) 61 | else: 62 | out.append( 63 | f"Please consider adding support for chip '{chip}' " 64 | f"to the UF2 repository: {FAMILIES_URL}" 65 | ) 66 | pytest.fail("\n".join(out)) 67 | --------------------------------------------------------------------------------