ESP32-IDF 分区表


一、基本介绍

使用时要添加头文件 #include "esp_partition.h"

1、配置结构体

1.1 esp_partition_t

typedef struct {
   
   
    esp_flash_t* flash_chip;            /*!< SPI flash chip on which the partition resides */
    esp_partition_type_t type;          /*!< partition type (app/data) */
    esp_partition_subtype_t subtype;    /*!< partition subtype */
    uint32_t address;                   /*!< starting address of the partition in flash */
    uint32_t size;                      /*!< size of the partition, in bytes */
    uint32_t erase_size;                /*!< size the erase operation should be aligned to */
    char label[17];                     /*!< partition label, zero-terminated ASCII string */
    bool encrypted;                     /*!< flag is set to true if partition is encrypted */
    bool readonly;                      /*!< flag is set to true if partition is read-only */
} esp_partition_t;

该结构体存储的是分区信息,使用的是 API 的格式,而不是 Flash 中的格式,该格式是 esp_partition_info_t

  • flash_chip:分区所在的 SPI 闪存芯片
  • type:分区类型 (app/data)
  • subtype:partition subtype partition 子类型
  • address:Flash 中分区的起始地址
  • size:分区的大小(以字节为单位)
  • erase_size:擦除操作所应对齐的大小
  • label:分区标签,以零结尾的 ASCII 字符串
  • encrypted:如果分区已加密,则 flag 设置为 true
  • readonly:如果 partition 是只读的,则 flag 设置为 true

1.2 esp_partition_iterator_t

用于遍历分区表的迭代器:

typedef struct esp_partition_iterator_opaque_* esp_partition_iterator_t;

...

typedef struct esp_partition_iterator_opaque_ {
   
   
    esp_partition_type_t type;                      // requested type
    esp_partition_subtype_t subtype;                // requested subtype
    const char *label;                              // requested label (can be NULL)
    partition_list_item_t *next_item;               // next item to iterate to
    esp_partition_t *info;                          // pointer to info (it is redundant, but makes code more readable)
} esp_partition_iterator_opaque_t;

2、常用 API

2.1 esp_partition_find

esp_partition_iterator_t esp_partition_find(esp_partition_type_t type, esp_partition_subtype_t subtype, const char *label)
  • 参数
    • type:分区类型,参考 esp_partition_type_t
    • subtype:分区子类型,参考 esp_partition_subtype_t
    • label:可选)分区标签。如果查找具有特定名称的分区,请设置此值。否则传递 NULL。
  • 作用
    • 根据一个或多个参数查找分区。
  • 返回值
    • esp_partition_iterator_t :可用于枚举找到的所有分区的迭代器;如果未找到分区,则为 NULL。通过此函数获取的 Iterator 在不再使用时必须使用 esp_partition_iterator_release 释放。

2.2 esp_partition_find_first

const esp_partition_t *esp_partition_find_first(esp_partition_type_t type, esp_partition_subtype_t subtype, const char *label)
  • 参数
    • type:分区类型,参考 esp_partition_type_t
    • subtype:分区子类型,参考 esp_partition_subtype_t
    • label:可选)分区标签。如果查找具有特定名称的分区,请设置此值。否则传递 NULL。
  • 作用
    • 根据一个或多个参数查找第一个分区。
  • 返回值
    • esp_partition_iterator_t :指向 esp_partition_t 结构的指针,如果未找到分区,则为 NULL。此指针在应用程序的生存期内有效。

2.3 esp_partition_get

const esp_partition_t *esp_partition_get(esp_partition_iterator_t iterator)
  • 参数
    • iterator:通过 esp_partition_find 获取的迭代器。必须为非 NULL。
  • 作用
    • 获取给定分区 esp_partition_t 结构。
  • 返回值
    • esp_partition_t :指向 esp_partition_t 结构的指针。此指针在应用程序的生存期内有效。

2.4 esp_partition_next

esp_partition_iterator_t esp_partition_next(esp_partition_iterator_t iterator)
  • 参数
    • iterator:通过 esp_partition_find 获取的迭代器。必须为非 NULL。
  • 作用
    • 将 partition iterator 移动到找到的下一个分区。
  • 返回值
    • esp_partition_t :如果未找到分区,则为 NULL,否则为有效的 esp_partition_iterator_t

2.5 esp_partition_iterator_release

void esp_partition_iterator_release(esp_partition_iterator_t iterator)
  • 参数
    • iterator:使用 esp_partition_find 获取的迭代器。迭代器允许为 NULL,因此在调用此函数之前无需检查其值。
  • 作用
    • 释放 partition 迭代器。

2.6 esp_partition_verify

const esp_partition_t *esp_partition_verify(const esp_partition_t *partition)
  • 参数
    • partition:指向要验证的分区数据的指针。必须为非 NULL。此结构的所有字段必须与 flash 中的分区表条目匹配,此函数才能返回成功匹配。
  • 作用
    • 验证分区数据。
  • 返回值
    • 如果未找到分区,则返回 NULL。
    • 如果找到,则返回指向 flash 中 esp_partition_t 结构的指针。此指针在应用程序的生存期内始终有效。

2.7 esp_partition_read

esp_err_t esp_partition_read(const esp_partition_t *partition, size_t src_offset, void *dst, size_t size)
  • 参数
    • partition:指向使用 esp_partition_find_firstesp_partition_get 获取的分区结构的指针。必须为非 NULL。
    • src_offset:要读取的数据的地址,相对于分区的开头。
    • dst:向应存储数据的缓冲区的指针。指针必须为非 NULL,并且缓冲区必须至少为 ‘size’ 字节长。
    • size:要读取的数据的大小,以字节为单位。
  • 作用
    • 从分区中读取数据。
  • 返回值
    • ESP_OK,如果数据读取成功
    • ESP_ERR_INVALID_ARG:参数错误,比如 src_offset 超过分区大小
    • ESP_ERR_INVALID_SIZE:如果读取将超出分区的边界

2.8 esp_partition_write

esp_err_t esp_partition_write(const esp_partition_t *partition, size_t dst_offset, const void *src, size_t size)
  • 参数
    • partition:指向使用 esp_partition_find_firstesp_partition_get 获取的分区结构的指针。必须为非 NULL。
    • dst_offset:相对于分区开头应写入数据的地址。
    • src:指向源缓冲区的指针。指针必须为非 NULL,并且缓冲区必须至少为 ‘size’ 字节长。
    • size:要写入的数据的大小,以字节为单位。
  • 作用
    • 从将数据写入分区。
  • 返回值
    • ESP_OK,如果数据读取成功
    • ESP_ERR_INVALID_ARG:参数错误,比如 dst_offset 超过分区大小
    • ESP_ERR_INVALID_SIZE:如果 write 会超出分区的边界
    • ESP_ERR_NOT_ALLOWED:如果分区是只读的

在将数据写入 flash 之前,需要擦除 flash 的相应区域。这可以使用 esp_partition_erase_range 函数来完成。

2.9 esp_partition_erase_range

esp_err_t esp_partition_erase_range(const esp_partition_t *partition, size_t offset, size_t size)
  • 参数
    • partition:指向使用 esp_partition_find_firstesp_partition_get 获取的分区结构的指针。必须为非 NULL。
    • offset:从擦除操作应开始的分区开头开始
<think>我们正在讨论如何在ESP32-S3上使用ESP-IDF框架配置和使用分区表分区表是ESP-IDF中用于定义闪存布局的重要机制,它允许开发者将闪存划分为多个区域,例如应用程序、OTA数据、文件系统等。 参考步骤: 1. 理解分区表概念 2. 创建自定义分区表 3. 配置项目以使用分区表 4. 在代码中使用分区信息 注意:ESP32-S3的分区表配置与其他ESP32系列类似,但可能有特定的分区类型(如用于USB、PSRAM等)。 详细步骤: 1. **理解分区表概念** - 分区表是一个CSV文件,通常位于项目根目录下的`partitions.csv`。 - 每个分区包括:名称、类型、子类型、偏移量、大小和标志。 - 常用分区类型:`app`(应用程序)、`data`(数据)、`ota`(OTA更新)等。 2. **创建自定义分区表** - 在项目根目录创建`partitions.csv`文件。 - 示例内容: ``` # Name, Type, SubType, Offset, Size, Flags nvs, data, nvs, 0x9000, 0x6000, phy_init, data, phy, 0xf000, 0x1000, factory, app, factory, 0x10000, 1M, storage, data, spiffs, , 0x100000, ``` - 注意:如果偏移量(Offset)留空,则分区会紧接上一个分区之后开始。大小(Size)可以使用十六进制或带单位(如K、M)的十进制表示。 3. **配置项目以使用分区表** - 运行`idf.py menuconfig`打开配置菜单。 - 进入`Partition Table`设置: - 选择`Partition Table`(分区表)→ `Custom partition table CSV`(自定义分区表CSV),并填写`partitions.csv`的路径(如果不在项目根目录)。 - 可以设置`Partition Table offset`(分区表偏移量),默认为`0x8000`。 - 保存配置。 4. **在代码中使用分区信息** - 使用`esp_partition`相关API访问分区。 - 示例:查找并操作分区 ```c #include "esp_partition.h" // 查找类型为数据,子类型为spiffs的分区 const esp_partition_t *partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_SPIFFS, "storage"); if (partition == NULL) { ESP_LOGE(TAG, "Failed to find partition"); return; } // 读取分区数据 uint8_t buffer[128]; esp_err_t err = esp_partition_read(partition, 0, buffer, sizeof(buffer)); if (err != ESP_OK) { ESP_LOGE(TAG, "Read failed: %s", esp_err_to_name(err)); } ``` 5. **构建和烧录** - 分区表会在构建过程中自动编译并烧录到闪存的默认位置(`0x8000`)。 - 使用`idf.py flash`烧录整个项目(包括分区表)。 6. **验证分区表** - 烧录后,可以通过串口监视器查看启动日志,其中会打印分区表信息。 - 或者使用`esptool.py`读取闪存中的分区表: ``` esptool.py -p COMx read_flash 0x8000 0xC00 partition_table.bin ``` 然后使用`gen_esp32part.py`解析: ``` python components/partition_table/gen_esp32part.py partition_table.bin ``` 注意:对于ESP32-S3,如果需要使用特定的功能(如USB OTG),可能需要配置特定的分区类型和子类型。请参考官方文档。 引用:ESP-IDF分区表文档[^1] 相关问题: 1. 如何在分区表中为ESP32-S3的USB功能预留空间? 2. 如何配置分区表以支持OTA更新? 3. 如何扩展分区表以包含自定义数据类型?</think>### ESP32-S3 ESP-IDF 分区表配置指南 在 ESP-IDF 框架中配置分区表是管理 ESP32-S3 闪存空间的关键步骤,它定义了应用程序、文件系统、OTA 更新等组件的存储布局。以下是详细配置指南: --- #### 1. **分区表基础概念** - **分区表作用**:定义闪存空间的逻辑划分,每个分区包含名称、类型、子类型、偏移量和大小 - **核心分区类型**: - `app`:应用程序固件(可包含多个 OTA 分区) - `data`:数据存储(NVS、SPIFFS、FATFS 等) - `ota`:OTA 更新数据 - **ESP32-S3 特有**:支持 PSRAM 缓存分区和 USB OTG 专用分区 --- #### 2. **创建自定义分区表** 在项目根目录创建 `partitions.csv` 文件: ```csv # ESP32-S3 典型分区表示例 # Name, Type, SubType, Offset, Size, Flags nvs, data, nvs, 0x9000, 0x6000, otadata, data, ota, 0xf000, 0x2000, phy_init, data, phy, 0x11000, 0x1000, factory, app, factory, 0x20000, 2M, ota_0, app, ota_0, , 2M, ota_1, app, ota_1, , 2M, spiffs, data, spiffs, , 1M, usb, data, fat, , 512K, encrypted ``` **参数说明**: - `Offset`:留空表示自动接续前一分区 - `Size`:支持单位(K/KB, M/MB)或十六进制(0x100000) - `Flags`:可选 `encrypted`(加密分区) --- #### 3. **配置项目使用分区表** 1. 运行配置工具: ```bash idf.py menuconfig ``` 2. 导航至: ``` > Partition Table [*] Custom partition table CSV (partitions.csv) Partition table CSV file (0x8000) Partition table offset address ``` 3. 启用 SPIFFS/FATFS(如使用文件系统分区): ``` > Component config > SPIFFS Configuration [*] Enable SPIFFS support ``` --- #### 4. **在代码中使用分区** ```c #include "esp_partition.h" // 查找 SPIFFS 分区 const esp_partition_t *spiffs_partition = esp_partition_find_first( ESP_PARTITION_TYPE_DATA, // 类型: data ESP_PARTITION_SUBTYPE_DATA_SPIFFS, // 子类型: spiffs "spiffs" // 分区标签 ); // 挂载 SPIFFS 文件系统 esp_vfs_spiffs_conf_t conf = { .base_path = "/spiffs", .partition_label = "spiffs", .max_files = 5, .format_if_mount_failed = true }; esp_vfs_spiffs_register(&conf); // 访问 USB 分区 (加密) const esp_partition_t *usb_partition = esp_partition_find_first( ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_FAT, "usb" ); esp_partition_read(usb_partition, 0, buffer, size); // 自动解密 ``` --- #### 5. **构建与烧录** 1. 编译包含分区表的固件: ```bash idf.py build ``` 2. 烧录所有内容(含分区表): ```bash idf.py flash ``` 3. 查看分区信息(烧录后): ```bash idf.py partition-table partition-table-flash monitor ``` --- #### 6. **高级配置技巧** 1. **OTA 滚动更新**: ```csv ota_0, app, ota_0, , 2M, ota_1, app, ota_1, , 2M, ``` 使用 `esp_ota_set_boot_partition()` 切换启动分区 2. **加密分区**: - 添加 `encrypted` 标志 - 在代码中使用 `esp_partition_get_encryption_key()` 获取密钥 3. **PSRAM 缓存优化**: ```csv psram_cache, data, spiram, , 256K, ``` --- #### 7. **分区表验证** 1. 生成二进制分区表: ```bash python $IDF_PATH/components/partition_table/gen_esp32part.py partitions.csv partitions.bin ``` 2. 解析现有分区表: ```bash esptool.py read_flash 0x8000 0xC00 partition-table.bin gen_esp32part.py partition-table.bin ``` --- ### 注意事项 1. **偏移量对齐**:确保分区起始地址按 4KB 对齐(0x1000 倍数) 2. **空间预留**:在分区表后预留至少 0x1000 空间 3. **默认分区**:未指定分区表时使用 `$IDF_PATH/components/partition_table/default.csv` 4. **大小计算**:总分区大小不应超过 ESP32-S3 闪存容量(通常 4MB/8MB/16MB) > 参考:ESP-IDF 分区表官方文档[^1]
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值