深入解析ESP32C3(1) - 使用ESP-IDF

乐鑫ESP32系列芯片是性价比非常高的嵌入式平台,不仅外设接口丰富,有较多的存储空间,还支持WIFI/BT等无线连接,同时也支持加密和权限管理等安全功能,这大大拓展了芯片的应用领域;当然,最重要的是该系列芯片的价格并不贵。个人是很看好ESP32系列芯片的前景,故此准备几篇文章来解析该芯片平台的功能,并为以后的开发做技术储备。

初次接触乐鑫ESP32,是从乐鑫的ESP-IDF开发环境开始的,这也是乐鑫主推的开发套件;另外也有Arduino开发套件,暂无涉及。IDF采用CMAKE编译系统,较晦涩复杂,本文不作解析,仅从使用IDF的角度出发。

IDF编译app固件按乐鑫官网的编程指南,安装好IDF开发环境,并复制examples\get-started\blink\作为测试用例,按下述命令编译测试:
>: idf.py set-target esp32c3    #配置目标芯片
>: idf.py menuconfig               #图像化配置功能宏,这里修改宏CONFIG_BLINK_GPIO为13
>: idf.py build                          #编译blink测试用例
    以下是整个编译过程的主要日志,可以看出涉及到哪些代码,以及编译结果。

Executing action: all (aliases: build)
Running ninja in directory G:\workspace\espressif\blink\build
Executing "ninja all"...
[0/1] Re-running CMake...
-- Building ESP-IDF components for target esp32c3
Processing 2 dependencies:            #项目依赖的组件来源

[1/2] espressif/led_strip (2.5.2)     #项目目录下的组件:\blink\managed_components\espressif__led_strip
[2/2] idf (5.1.2)                     #ESP-IDF目录components\下的组件

######编译器添加ESP32C3内部ROM的链接资源以及相关的组件代码路径,准备编译app(blink.bin)

-- Project sdkconfig file G:/workspace/espressif/blink/sdkconfig
-- App "blink" version: 1
-- Adding linker script G:/workspace/espressif/blink/build/esp-idf/esp_system/ld/memory.ld
-- Adding linker script G:/Program/Espressif/frameworks/esp-idf-v5.1.2/components/esp_system/ld/esp32c3/sections.ld.in
-- Adding linker script G:/Program/Espressif/frameworks/esp-idf-v5.1.2/components/esp_rom/esp32c3/ld/esp32c3.rom.ld
-- Adding linker script G:/Program/Espressif/frameworks/esp-idf-v5.1.2/components/esp_rom/esp32c3/ld/esp32c3.rom.api.ld
-- Adding linker script G:/Program/Espressif/frameworks/esp-idf-v5.1.2/components/esp_rom/esp32c3/ld/esp32c3.rom.libgcc.ld
-- Adding linker script G:/Program/Espressif/frameworks/esp-idf-v5.1.2/components/esp_rom/esp32c3/ld/esp32c3.rom.newlib.ld
-- Adding linker script G:/Program/Espressif/frameworks/esp-idf-v5.1.2/components/esp_rom/esp32c3/ld/esp32c3.rom.version.ld
-- Adding linker script G:/Program/Espressif/frameworks/esp-idf-v5.1.2/components/esp_rom/esp32c3/ld/esp32c3.rom.eco3.ld
-- Adding linker script G:/Program/Espressif/frameworks/esp-idf-v5.1.2/components/soc/esp32c3/ld/esp32c3.peripherals.ld
-- Components: app_trace app_update bootloader bootloader_support bt cmock console cxx driver efuse esp-tls esp_adc esp_app_format esp_coex esp_common esp_eth esp_event esp_gdbstub esp_hid esp_http_client esp_http_server esp_https_ota esp_https_server esp_hw_support esp_lcd esp_local_ctrl esp_mm esp_netif esp_netif_stack esp_partition esp_phy esp_pm esp_psram esp_ringbuf esp_rom esp_system esp_timer esp_wifi espcoredump espressif__led_strip esptool_py fatfs freertos hal heap http_parser idf_test ieee802154 json log lwip main mbedtls mqtt newlib nvs_flash openthread partition_table protobuf-c protocomm pthread riscv sdmmc soc spi_flash spiffs tcp_transport ulp unity usb vfs wear_levelling wifi_provisioning wpa_supplicant
-- Component paths:  #上面的组件列表不止来源于ESP-IDF组件目录,还包含了项目目录(..../blink/)下的组件
 ... ... ... (略)
[1/875] Generating project_elf_src_esp32c3.c

[2/875] Generating ../../partition_table/partition-table.bin  #生成分区表镜像文件partition-table.bin 
Partition table binary generated. Contents:
*******************************************************************************
# ESP-IDF Partition Table
# Name,   Type, SubType, Offset,  Size, Flags
  nvs,     data, nvs,     0x9000,  24K,       #非易失性存储,储存工厂校准数据和配置数据
  phy_init,data, phy,     0xf000,  4K,        #以太网PHY初始化数据
  factory, app,  factory, 0x10000, 1M,        #系统分区,例如工厂的生产固件,默认运行分区
*******************************************************************************
[3/875] Generating memory.ld linker script...
 ... ... ... (略)  #编译组件的代码
 
######编译器添加ESP32C3内部ROM的链接资源以及相关的组件代码路径,准备编译bootloader.bin

-- Adding linker script G:/Program/Espressif/frameworks/esp-idf-v5.1.2/components/soc/esp32c3/ld/esp32c3.peripherals.ld
-- App "bootloader" version: 1
-- Adding linker script G:/Program/Espressif/frameworks/esp-idf-v5.1.2/components/esp_rom/esp32c3/ld/esp32c3.rom.ld
-- Adding linker script G:/Program/Espressif/frameworks/esp-idf-v5.1.2/components/esp_rom/esp32c3/ld/esp32c3.rom.api.ld
-- Adding linker script G:/Program/Espressif/frameworks/esp-idf-v5.1.2/components/esp_rom/esp32c3/ld/esp32c3.rom.libgcc.ld
-- Adding linker script G:/Program/Espressif/frameworks/esp-idf-v5.1.2/components/esp_rom/esp32c3/ld/esp32c3.rom.newlib.ld
-- Adding linker script G:/Program/Espressif/frameworks/esp-idf-v5.1.2/components/bootloader/subproject/main/ld/esp32c3/bootloader.ld
-- Adding linker script G:/Program/Espressif/frameworks/esp-idf-v5.1.2/components/bootloader/subproject/main/ld/esp32c3/bootloader.rom.ld
-- Components: bootloader bootloader_support efuse esp_app_format esp_common esp_hw_support esp_rom esp_system esptool_py freertos hal log main micro-ecc newlib partition_table riscv soc spi_flash
-- Component paths: ... ... ...
[668/875] Performing build step for 'bootloader'
 ... ... ... (略) #编译bootloader组件的代码
Successfully created esp32c3 image.

Generated G:/workspace/espressif/blink/build/bootloader/bootloader.bin  #生成引导镜像文件bootloader.bin
[96/96] cmd.exe /C "cd /D G:\workspace\espressif\blink\build\bootloader\esp-idf\esptool_py && G:\Program\Espressif\python_env\idf5.1_py3.11_env\Scripts\python.exe G:/Program/Espressif/frameworks/esp-idf-v5.1.2/components/partition_table/check_sizes.py --offset 0x8000 bootloader 0x0 G:/workspace/espressif/blink/build/bootloader/bootloader.bin"

Bootloader binary size 0x5070 bytes. 0x2f90 bytes (37%) free.
[669/875] No install step for 'bootloader'
[670/875] Completed 'bootloader'

[671/875] Generating x509_crt_bundle                     
[672/875] Generating ../../x509_crt_bundle.S
 ... ... ... (略)#继续编译app的关联代码
[873/875] Linking CXX executable blink.elf
[874/875] Generating binary image from built executable

esptool.py v4.7.0
Creating esp32c3 image...
Merged 1 ELF section
Successfully created esp32c3 image.

Generated G:/workspace/espressif/blink/build/blink.bin  #生成APP镜像文件blink.bin
[875/875] cmd.exe /C "cd /D G:\workspace\espressif\blink\build\esp-idf\esptool_py && G:\Program\Espressif\python_env\idf5.1_py3.11_env\Scripts\python.exe G:/Program/Espressif/frameworks/esp-idf-v5.1.2/components/partition_table/check_sizes.py --offset 0x8000 partition --type app G:/workspace/espressif/blink/build/partition_table/partition-table.bin G:/workspace/espressif/blink/build/blink.bin"

blink.bin binary size 0x2ec20 bytes. Smallest app partition is 0x100000 bytes. 0xd13e0 bytes (82%) free. 
######编译完成

Project build complete. To flash, run this command:     #下载命令行:烧录所有镜像到ESP32C3开发板
G:\Program\Espressif\python_env\idf5.1_py3.11_env\Scripts\python.exe ..\..\..\Program\Espressif\frameworks\esp-idf-v5.1.2\components\esptool_py\esptool\esptool.py -p (PORT) -b 460800 --before default_reset --after hard_reset --chip esp32c3  write_flash --flash_mode dio --flash_size 2MB --flash_freq 80m 0x0 build\bootloader\bootloader.bin 0x8000 build\partition_table\partition-table.bin 0x10000 build\blink.bin
or run 'idf.py -p (PORT) flash'

 从代码的组成部分来看,一个测试用例,会涉及4个方面:

  • 测试用例本身,一般包含子目录main/等。
  • 测试用例的本地依赖组件,存放在子目录managed_components/下,比如blink\managed_components\espressif__led_strip。(可选项,可以没有)
  • IDF的平台组件,见IDF安装子目录 frameworks/esp-idf-v5.1.2/components
  • 芯片IROM的固件。不参与实际编译,作用于编译链接阶段,类似于一个动态链接库。固件的相关资源定义,见目录 frameworks/esp-idf-v5.1.2/components/esp_rom/esp32c3/ld/

从编译结果来看,测试固件分3个部分:

  • partition-table.bin  分区表镜像,定义各个分区的位置和大小
  • bootloader.bin  引导镜像,用于引导并加载应用镜像
  • blink.bin     APP应用镜像,含实际测试用例

最后的下载命令行用于烧录固件到ESP32C3开发板:

>: idf.py -p COM5  flash  #板子串口COM5
上述命令会烧录全部的固件,烧录地址和镜像文件的关系,如下
        0x00000 build\bootloader\bootloader.bin
        0x08000 build\partition_table\partition-table.bin
        0x10000 build\blink.bin
注意,烧录位置,并不在ESP32C3内部,而是SPI接口的外部flash存储芯片,下一小节讲述芯片的存储结构。
烧录地址并不是固定的,与分区表相关;分区表允许修改或重新指定配置文件,具体见IDF组件目录:components\partition_table\,默认分区表为partitions_singleapp.csv,分区信息见上面的编译日志。
当前的Flash分区存储结构如下:
 Bootloader     - 起始必须是0x00000,大小等于CONFIG_PARTITION_TABLE_OFFSET 
 PartitionTable - 起始为CONFIG_PARTITION_TABLE_OFFSET (0x8000),固定大小4KB
 nvs数据分区   - 紧挨上个分区结尾并4KB对齐:0x9000,大小24KB
 phy数据分区   - 紧挨上个分区结尾并4KB对齐:0xF000,大小4KB
 factory            - 紧挨上个分区结尾并4KB对齐:0x10000,大小1024KB

另,其他编译和烧录命令:

idf.py app   #单独编译APP,比如blink.bin
idf.py size  #查看APP占用RAM+ROM的情况
idf.py app-flash  #单独烧录app分区,比如将blink.bin烧录到默认app分区:factory
idf.py encrypted-app-flash #加密并烧录APP
idf.py bootloader #单独编译引导镜像
idf.py bootloader-flash #单独烧录引导镜像
idf.py partition-table #单独生成分区表镜像
idf.py partition-table-flash #单独烧录分区表镜像
idf.py erase-flash #擦除整块FLASH芯片,慎重!请先备份工厂的数据分区
idf.py erase-otadata #擦除OTA数据分区
idf.py read-otadata #读取OTA数据分区

分区工具parttool.py的用法举例:
# 擦除名为'storage' 的分区
parttool.py --port "/dev/ttyUSB1" erase_partition --partition-name=storage
# 读取类型为'data'、子类型为'spiffs' 的分区, 保存到'spiffs.bin' 文件
parttool.py --port "/dev/ttyUSB1" read_partition --partition-type=data --partition-subtype=spiffs --output "spiffs.bin"
# 将'factory.bin' 文件中的内容写入到'factory' 分区
parttool.py --port "/dev/ttyUSB1" write_partition --partition-name=factory --input "factory.bin"
# 打印默认启动分区的大小
parttool.py --port "/dev/ttyUSB1" get_partition_info --partition-boot-default --info size
# 显示子命令的描述
parttool.py [subcommand] --help

  • 12
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值