SOC-ESP32S3部分:22-分区表

article/2025/6/25 13:07:13

飞书文档https://x509p6c8to.feishu.cn/wiki/F9PdwnOKhiTRDWk4cr1cIZsvneh

无论是前面我们说到的NVS,还是后面用到的文件系统,他们都必须有存储的载体,例如NVS,我们说过它是存储在Flash中的,那具体是Flash的哪个位置呢?这就是由分区表决定的了。

1-1、什么是分区表?

ESP32-S3的分区表是用来确定在ESP32-S3的Flash中数据和应用程序的布局。每个ESP32-S3的Flash可以包含多个应用程序(例如双分区OTA中,就有两个应用),以及多种不同类型的数据(例如校准数据、文件系统数据、参数存储数据等)。因此,我们在Flash的默认偏移地址0x8000处烧写一张分区表。

2-1IDF中默认的分区表?

IDF中有一些参考的分区表设置,我们可以打开idf.py menuconfig查看

(Top) → Partition Table → Partition TableEspressif IoT Development Framework Configuration
(X) Single factory app, no OTA
( ) Single factory app (large), no OTA
( ) Factory app, two OTA definitions
( ) Two large size OTA partitions
( ) Custom partition table CSV

这些分区表文件放在esp-idf/components/partition_table文件夹中,我们可以打开partitions_singleapp.csv查看

# Name,   Type, SubType, Offset,  Size, Flags
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
nvs,      data, nvs,     ,        0x6000,
phy_init, data, phy,     ,        0x1000,
factory,  app,  factory, ,        1M,上方创建了三个分区,nvs,phy_init和factory分区
其中nvs和phy_init为数据区,大小分别为0x6000和0x1000,分别用于存储NVS库专用分区和PHY初始化数据。
factory为应用区,大小为1M,系统启动时,会默认加载这个分区内的应用。

分区名称

类型

子类型

偏移量

大小

描述

nvs 

data

nvs

留空,自动偏移

 0x6000

非易失性存储区,用于保存设备重启后仍需保留的配置数据,如Wi-Fi凭据等

phy_init

data

 phy

留空,自动偏移

0x1000

物理层初始化数据区,通常存放与硬件初始化相关的固件或配置信息

factory

app  

factory

留空,自动偏移

1M

出厂固件或用户可升级的应用程序固件存储区,用于存储设备的主要应用程序代码

在这里可以看到,只用了1M多的空间,而我们板卡Flash一般是16M的,所以,我们可以根据实际应用需求修改大小,如果我们需要修改不同分区的大小,应该如何修改呢?那就需要我们自定义分区表了。

3-1、如何自定义分区表?

我们可以参考上述分区表的格式,在工程文件下创建partitions.csv文件,然后添加user_nvs

# Name,   Type, SubType, Offset,  Size, Flags
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
nvs,      data, nvs,     ,        0x6000,
phy_init, data, phy,     ,        0x1000,
factory,  app,  factory, ,        1M,
user_nvs, data, nvs,     ,        0x6000,

然后通过idf.py menuconfig配置自定义分区表

然后重新编译

idf.py build编译完成后,可以执行以下指令查看分区表
idf.py partition-table
*******************************************************************************
# ESP-IDF Partition Table
# Name, Type, SubType, Offset, Size, Flags
nvs,data,nvs,0x9000,24K,
phy_init,data,phy,0xf000,4K,
factory,app,factory,0x10000,1M,
user_nvs,data,nvs,0x110000,24K,
*******************************************************************************

接着,我们就可以修改原来nvs的代码,让它使用我们创建的分区进行存储

#include <stdio.h>
#include <inttypes.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "nvs.h"
#include "esp_log.h"static const char *TAG = "NVS"; // 定义日志标签void app_main(void)
{char* partition_name="user_nvs";            //我们添加的分区名// 初始化 NVSesp_err_t err = nvs_flash_init_partition(partition_name);if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {// NVS 分区被截断,需要擦除// 重新初始化 nvs_flashESP_ERROR_CHECK(nvs_flash_erase_partition(partition_name));err = nvs_flash_init_partition(partition_name);}ESP_ERROR_CHECK(err);// 打开命名空间ESP_LOGI(TAG, "打开非易失性存储 (NVS) 句柄...");nvs_handle_t my_handle;err = nvs_open_from_partition(partition_name,"storage", NVS_READWRITE, &my_handle);if (err != ESP_OK) {ESP_LOGI(TAG, "打开 NVS 句柄时出错 (%s)!\n", esp_err_to_name(err));} else {// 读取重启计数器ESP_LOGI(TAG, "从 NVS 读取重启计数器 ... ");int32_t restart_counter = 0; // 如果 NVS 中未设置值,则默认为 0err = nvs_get_i32(my_handle, "restart_counter", &restart_counter);ESP_LOGI(TAG, "重启计数器 = %" PRIu32 "\n", restart_counter);// 更新重启计数器ESP_LOGI(TAG, "更新 NVS 中的重启计数器 ... ");restart_counter++;err = nvs_set_i32(my_handle, "restart_counter", restart_counter);// 提交写入的值。设置任何值后,必须调用 nvs_commit() 以确保更改写入闪存存储。ESP_LOGI(TAG, "提交 NVS 中的更改 ... ");err = nvs_commit(my_handle);// 关闭命名空间nvs_close(my_handle);}ESP_LOGI(TAG, "\n");// 重启模块for (int i = 10; i >= 0; i--) {ESP_LOGI(TAG, "将在 %d 秒后重启...\n", i);vTaskDelay(1000 / portTICK_PERIOD_MS);}ESP_LOGI(TAG, "现在重启。\n");fflush(stdout);esp_restart();
}

编译烧录后,我们会发现,效果和原来的是一样的,只不过现在存储到,user_nvs分区中。

4-1、自定义自己的分区

另外,我们还可以自定义分区:

我们可以参考上述分区表的格式,添加user分区

# Name,   Type, SubType, Offset,  Size, Flags
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
nvs,      data, nvs,     ,        0x6000,
phy_init, data, phy,     ,        0x1000,
factory,  app,  factory, ,        1M,
user,     0x40, 0x01,    ,        0x1000,

Name 字段

Name 字段可以是任何有意义的名称,但不能超过 16 个字节,其中包括一个空字节(之后的内容将被截断)。该字段对 ESP32-S3 并不是特别重要。

Type 字段

Type 字段可以指定为 app (0x00) 或者 data (0x01),也可以直接使用数字 0-254(或者十六进制 0x00-0xFE)。注意,0x00-0x3F 不得使用(预留给 esp-idf 的核心功能)。

SubType 字段

SubType 字段长度为 8 bit,内容与具体分区 Type 有关。目前,esp-idf 仅仅规定了 “app” 和 “data” 两种分区类型的子类型含义。

​
当 Type 定义为 app 时,SubType 字段可以指定为 factory (0x00)、 ota_0 (0x10) … ota_15 (0x1F) 或者 test (0x20)。当 Type 定义为 data 时,SubType 字段可以指定为 ota (0x00)、phy (0x01)、nvs (0x02)、nvs_keys (0x04) 或者其他组件特定的子类型.ESP-IDF 还支持其他用于数据存储的预定义子类型,包括:
coredump (0x03) 用于在使用自定义分区表 CSV 文件时存储核心转储。
efuse (0x05) 使用 虚拟 eFuse 模拟 eFuse 位。
undefined (0x06) 隐式用于未指定子类型(即子类型为空)的数据分区,但也可显式将其标记为未定义。
fat (0x81) 用于 FAT 文件系统。
spiffs (0x82) 用于 SPIFFS 文件系统。
littlefs (0x83) 用于 LittleFS 文件系统,详情可参阅 storage/littlefs 示例。如果分区类型是由应用程序定义的任意值 (0x40-0xFE),那么 subtype 字段可以是由应用程序选择的任何值 (0x00-0xFE)。​

然后通过idf.py menuconfig配置自定义分区表

(Top) → Partition Table
Espressif IoT Development Framework ConfigurationPartition Table (Custom partition table CSV)  --->
(partitions.csv) Custom partition CSV file   //名称需要和我们文件名称一致
(0x8000) Offset of partition table
[*] Generate an MD5 checksum for the partition table

然后重新编译

idf.py build编译完成后,可以执行以下指令查看分区表
idf.py partition-table
*******************************************************************************
# ESP-IDF Partition Table
# Name, Type, SubType, Offset, Size, Flags
nvs,data,nvs,0x9000,24K,
phy_init,data,phy,0xf000,4K,
factory,app,factory,0x10000,1M,
user,64,1,0x110000,4K,
*******************************************************************************

接着我们可以编写个demo验证下,能否读写分区表

#include <stdio.h>
#include <esp_log.h>
#include <esp_partition.h>
#include "string.h"static const char*TAG = "partition";/*定义分区类型*/
#define USER_PARTITION_TYPE 0x40
/*定义分许子类型*/
#define USER_PARTITION_SUBTYPE 0x01
/*定义目标分区指针*/
static const esp_partition_t* partition_ptr = NULL;void app_main(void)
{/*获取目标分区指针*/partition_ptr = esp_partition_find_first(USER_PARTITION_TYPE, USER_PARTITION_SUBTYPE, NULL);if(partition_ptr == NULL){ESP_LOGE(TAG,"CAN'T FIND partition");return;}/*1-擦除操作*/esp_partition_erase_range(partition_ptr,0,0x1000);/*2-准备目标字符串*/const char *test_str = "this is flash write test!";/*3-写入目标地址*/esp_partition_write(partition_ptr,0,test_str,strlen(test_str));/*4-读出目标地址*/char read_buf[64];memset(read_buf,0,sizeof(read_buf));esp_partition_read(partition_ptr,0,read_buf,strlen(test_str));ESP_LOGI(TAG, "read partition data:%s" ,read_buf);return;
}

更多参考

https://docs.espressif.com/projects/esp-idf/zh_CN/v5.4/esp32s3/api-guides/partition-tables.html


http://www.hkcw.cn/article/axRthtEvlY.shtml

相关文章

华为OD机试真题——找出两个整数数组中同时出现的整数(2025A卷:100分)Java/python/JavaScript/C++/C语言/GO六种最佳实现

2025 A卷 100分 题型 本文涵盖详细的问题分析、解题思路、代码实现、代码详解、测试用例以及综合分析; 并提供Java、python、JavaScript、C++、C语言、GO六种语言的最佳实现方式! 2025华为OD真题目录+全流程解析/备考攻略/经验分享 华为OD机试真题《找出两个整数数组中同时出…

KWIC—Implicit Invocation

KWIC—Implicit Invocation ✏️ KWIC—Implicit Invocation 文章目录 KWIC—Implicit Invocation&#x1f4dd;KWIC—Implicit Invocation&#x1f9e9;KWIC&#x1f9e9;核心组件&#x1f9e9;ImplementationScheme⚖️ 隐式调用 vs 显式调用对比 &#x1f31f; 总结 &#x…

JWT 入门

一、JWT 概述 1. 扩展(Cookie、Session、Token) 灵魂拷问&#xff1a;为什么你的淘宝账号关闭后&#xff0c;购物车还在&#xff1f;其实这是Cookie 在搞事情。它就像是一种入场券&#xff0c;有该入场券就可以随意进出关卡。但这有个致命的弱点&#xff0c;Cookie是存在客户…

传统液晶瓶颈待破?铁电液晶如何实现显示技术逆袭

一、传统液晶显示&#xff1a;繁华背后的技术枷锁 在消费电子与专业显示领域&#xff0c;液晶技术&#xff08;LCD&#xff09;凭借成熟的产业链和性价比优势&#xff0c;长期占据主流地位。然而&#xff0c;随着 VR/AR、车载显示、高端投影等新兴场景的崛起&#xff0c;传统液…

Mybatis:灵活掌控SQL艺术

在前面的文章中&#xff0c;小编分享了spring中相关的知识&#xff0c;但是没有分享到&#xff0c;如何去更高效操作数据库。 操作数据库传统的方法就是通过JDBC来进行操作。 这个传统方法使用上可谓是够麻烦的 1.首先创建一个数据源对象 2.设置该数据源的属性&#xff08;…

STM32CubeMX定时器配置

STM32CubeMX定时器配置 一&#xff0c;Mode界面1&#xff0c;Slave Mode (从模式)2&#xff0c;Trigger Source (触发源) 三&#xff0c;Channelx&#xff08;通道模式&#xff09;1&#xff0c;Input Capture2&#xff0c;Output Compare3&#xff0c;PWM Generation4&#xf…

可灵2.1 vs Veo 3:AI视频生成谁更胜一筹?

在Google发布Veo 3几天后,可灵显然感受到了压力,发布了即将推出的视频模型系列可灵 2.1的早期体验版。 据我了解,有三种不同的模式: 可灵 2.1 标准模式: 720p分辨率 仅支持图像转视频(生成更快,一致性更好) 5秒视频仍需20积分 可灵 2.1 专业模式: 1080p分辨率 仅在图…

推荐几个不错的AI入门学习视频

引言&#xff1a;昨天推荐了几本AI入门书&#xff08;AI入门书&#xff09;&#xff0c;反响还不错。今天&#xff0c;我再推荐几个不错的AI学习视频&#xff0c;希望对大家有帮助。 网上关于AI的学习视频特别多。有收费的&#xff0c;也有免费的。我今天只推荐免费的。 我们按…

【机器学习】支持向量机

文章目录 一、支持向量机简述1.概念2.基本概念3.算法介绍4.线性可分5.算法流程 二、实验1.代码介绍2.模型流程3.实验结果4.实验小结 一、支持向量机简述 1.概念 支持向量机&#xff08;SVM&#xff09;是一类按监督学习方式对数据进行二元分类的广义线性分类器&#xff0c;其…

scale up 不能优化 TCP 聚合性能

scale up 作为一种系统扩展优化的方法&#xff0c;旨在提高系统组件的执行效率&#xff0c;比如替换更高性能的硬件或算法。是否可以此为依据优化 TCP 呢&#xff0c;例如通过多条路径聚合带宽实现吞吐优化(对&#xff0c;还是那个 MPTCP)&#xff0c;答案是否定的。 因为 TCP…

深度学习|pytorch基本运算-广播失效

【1】引言 前序文章中&#xff0c;已经学习了pytorch基本运算中的生成随机张量、生成多维张量&#xff0c;以及张量的变形、加减和广播运算。 今天的文章在之前学习的基础上&#xff0c;进一步探索。 前序文章链接为&#xff1a; 深度学习|pytorch基本运算-CSDN博客 【2】…

Asp.Net Core SignalR的分布式部署

文章目录 前言一、核心二、解决方案架构三、实现方案1.使用 Azure SignalR Service2.Redis Backplane(Redis 背板方案&#xff09;3.负载均衡配置粘性会话要求无粘性会话方案&#xff08;仅WebSockets&#xff09;完整部署示例&#xff08;Redis Docker&#xff09;性能优化技…

Linux环境搭建MCU开发环境

操作系统版本&#xff1a; ubuntu 22.04 文本编辑器&#xff1a; vscode 开发板&#xff1a; stm32f103c8t6 调试器&#xff1a; st-link 前言 步骤一&#xff1a; 安装交叉编译工具链 步骤二&#xff1a; 创建工程目录结构 步骤三&#xff1a; 调试…

VR/AR 视网膜级显示破局:10000PPI 如何终结颗粒感时代?

一、传统液晶 “纱窗效应”&#xff1a;VR 沉浸体验的最大绊脚石 当用户首次戴上 VR 头显时&#xff0c;眼前密密麻麻的像素网格往往打破沉浸感 —— 这正是传统液晶显示在近眼场景下的致命缺陷。受限于 500-600PPI 的像素密度&#xff0c;即使达到 4K 分辨率&#xff0c;等效到…

【教学类-36-10】20250531蝴蝶图案描边,最适合大小(一页1图1图、2图图案不同、2图图案相同对称)

背景说明: 之前做了动物头像扇子(描边20),并制作成一页一套图案对称两张 【教学类-36-09】20250526动物头像扇子的描边(通义万相)对称图40张,根据图片长宽,自动旋转图片,最大化图片-CSDN博客文章浏览阅读1k次,点赞37次,收藏6次。【教学类-36-09】20250526动物头像…

灌水论坛系统总体设计文档

一、实验题目 灌水论坛系统 二、实验目的 旨在通过一个相对完整且功能丰富的Web应用实例&#xff0c;全面地实践和巩固Web开发所需的各项核心技术和工程方法&#xff0c;从而提升其综合应用能力和解决实际开发问题的能力。它不仅仅是完成一个软件&#xff0c;更是一个学习、…

TK海外抢单源码/指定卡单

​ 抢单源码&#xff0c;有指定派单&#xff0c;打针&#xff0c;这套二改过充值跳转客服 前端vue 后端php 两端分离 可二开 可以指定卡第几单&#xff0c;金额多少&#xff0c; 前后端开源 PHP7.2 MySQL5.6 前端要www.域名&#xff0c;后端要admin.域名 前端直接静态 伪静…

印军高官为何指责83架光辉订单0交付 国产战机交付延迟

印度空军参谋长辛格在印度工业联合会举办的年度商业峰会上严厉批评本国的航空制造业,指出印度大型国防项目的落实没有如期进行,包括国产“光辉”战机在内的战斗机向空军交付均出现延迟。根据2021年与印度斯坦航空有限公司签订的价值4800亿卢比(约合404亿元人民币)的合同,印…

年轻人开始主动挂艾草了 老习俗焕发新活力

今年端午节当天,“年轻人开始主动挂艾草了”登上小红书APP热点榜首,截至晚上9点30分浏览量达到918万次。菜市场几块钱一把的野生艾草,在年轻人手中经过巧手改造,搭配菖蒲叶、玉簪叶、香樟果和铃铛,变成了身价百元的“祈福门挂”。如今,挂艾草不再只是简单的节庆习俗,而是…

Roguelike地牢:混沌系统与涌现式玩法设计

目录 Roguelike地牢:混沌系统与涌现式玩法设计引言第一章 地牢生成算法1.1 多级生成策略1.2 柏林噪声应用第二章 道具生态系统2.1 属性耦合模型2.2 道具稀有度系统第三章 敌人行为树3.1 自适应难度3.2 状态机设计第四章 永久死亡机制4.1 元进度系统4.2 遗产继承设计第五章 光照…