This article focuses on the ESP32 -S3, explaining how to set up its SPI Flash partition table and connect it to the Flash. It also covers partition table configuration and initializing and mounting each partition ,Learn how to configure and manage the ESP32 partition table. This guide covers Flash connection, partition table setup, initialization, and mounting for applications, NVS, SPIFFS, and FATFS.
01 Introduction
1. ESP32-S3 Partition Table
It is a configuration mechanism for dividing the SPI Flash storage space. It works similarly to the partitioning of a computer hard drive, dividing the Flash into multiple areas, each area is used to store different types of data or programs, such as:
Applications (e.g., factory, ota_0, ota_1);
System data (such as NVS and PHY initialization data);
File system (such as SPIFFS, FATFS).
2. Connecting ESP32-S3 to SPI Flash
ESP32-S3 communicates with external SPI Flash through the SPI/QSPI/OPI interface . The typical connection scheme is as follows:
SPI Flash Signals
ESP32-S3 Pin Names
Pin number (QFN56)
Remark
SCK/CLK
SPICLK
33
Clock Line
MOSI/SI
SPID
35
Data Input
MISO/SO
SPIQ
34
Data Output
CS#
SPICS0
32
Chip Select
WP#
SPIWP
31
Write protection
HOLD# / IO3
SPIHD
30
Pause/IO3
The SPI Flash is an external, independent chip that must be connected to the ESP32-S3 via a printed circuit board (PCB). The ESP32-S3 chip itself does not have integrated Flash, so all programs and data are stored in the external SPI Flash. Some modules (such as the ESP32 ESP32-S3-WROOM-1-S3) integrate Flash with the SoC on the same PCB, but these are still external components.
3. Communication protocols and modes
Basic SPI mode : uses 4 lines (CLK, CS, MOSI, MISO) and supports standard SPI protocol;
QSPI mode : transmits address and data simultaneously through 4 lines, increasing bandwidth by 4 times. It requires Flash chip support (such as qioor qoutmode).
OPI mode (Octal SPI): 8-wire parallel transmission, suitable for high-performance requirements, but requires a dedicated Flash model.
4. ESP32-S3 is compatible with SPI Flash from major manufacturers . Typical models are as follows:
1. Winbond
W25Q64JV: 8MB, supports QSPI, voltage 3.3V, package SOIC-8;
W25Q128JV: 16MB, maximum clock frequency 133MHz, suitable for large-capacity storage needs.
2. GigaDevice
GD25Q32C: 4MB, low-power design (<1mW), supports XIP (execution in place);
GD25Q128C: 16MB, operating voltage 1.7V~3.6V, compatible with wide voltage systems.
3. Micron
MT25QL128: 16MB, uses Octal SPI interface, suitable for high-speed data throughput scenarios.
02 How to set up the partition table
The partition table is a binary data structure stored in a fixed location in Flash (default 0x8000). It records information such as the starting address, size, type, and subtype of each partition. When the ESP32-S3 boots, the bootloader first reads the partition table and then uses the information in the table to load programs (such as the app partition) or access data (such as the NVS partition) from the corresponding partition.
Partition name
Who is responsible for initialization?
Typical trigger codes /locations
Remark
nvs
nvs_flash_init()
User code `app_main()
Must be called manually
phy_init
Inside the Wi-Fi/BT protocol stack
esp_wifi_init() or esp_bt_controller_init()
The protocol stack automatically reads calibration data
factory
ROM bootloader + CMake link
Power on ROM is directly mapped to address 0x10000
No application layer initialization required
vfs(FAT)
esp_vfs_fat_spiflash_mount()` or esp_vfs_fat_register()
User Code
Example: fatfs_spiflash/main.c
storage (SPIFFS)
esp_spiffs_mount()` or esp_vfs_spiffs_register()`
User Code
Example: spiffsgen/main.c
Specific process (taking ESP-IDF framework as an example).
Subtype: Under the app type, there are factory (default program), ota_0~ota_15 (OTA partition); under the data type, there are nvs, phy (radio data), fat (file system), etc.
Offset: can be omitted (automatically assigned in sequence), but must ensure no overlap;
Size: supports KB (such as 64KB), MB (such as 2MB), or hexadecimal (such as 0x10000).
2. Manually create a partition table
Creation steps:
1) Create a partition table file : Create a new file named partitions.csv in the project root directory and fill in the partition information according to the above format.
2) Specify the partition table path:
Add the following to your project’s CMakeLists.txt:
set (PARTITION_TABLE_CSV partitions.csv) # Point to the custom partition table file
Or via the ESP-IDF configuration tool (menuconfig):
3) Go to Partition Table → Partition Table (Custom partition table CSV) → enter the custom CSV file path (e.g. partitions.csv).
3. Automatically create a partition table for the ESP-IDF project in VSCode
In most cases, use the partition table automatically created by VSCode ESP-IDF. VSCode ESP-IDF projects use the framework’s default partition table (default_partitions.csv), which is suitable for most basic scenarios (including necessary partitions such as the factory app, nvs, and phy_init).
If you use the default partition table: No additional operations are required, just compile (Build) and flash (Flash) normally, VS Code will automatically handle the generation and flashing of the partition table.
4. Scenarios where partition table modification is required
1) Need to support OTA upgrade
The default partition table does not contain an OTA partition. To implement wireless upgrade functionality, you must add at least two OTA partitions (such as ota_0 and ota_1). For example:
If the NVS partition (default 5KB) cannot store device configurations (such as multiple WiFi passwords, sensor calibration data), its capacity needs to be increased (for example, 0x40000, which is 256KB);
If you use the FAT file system to store a large number of logs or files, you need to add or expand a fat-type partition (such as 2M).
3) Custom data partitioning requirements
When you need to store specific data (such as firmware backups and encryption keys) independently, you can add a custom data partition. For example:
csvfirmware_backup, data, 0x80, , 512KB, # Subtype 0x80 is custom
4) The Flash capacity exceeds the default partition table support range
The default partition table is suitable for Flash memory of 4MB or less. If you use 8MB/16MB Flash memory and need to make full use of the space, you need to re-plan the partition size (for example, expand the app partition to 4MB).
5) Multi-application switching
When you need to run multiple independent applications (such as the main program + debugger) on a device, you need to allocate a separate app partition for each application.
03 Initialize/Mount each partition
1. nvs
As long as you plan to use NVS (non-volatile storage) to save/read key-value data, you must call nvs_flash_init() during the initialization phase. Without it, any nvs_open, nvs_set_*, nvs_get_* will directly return ESP_ERR_NVS_NOT_INITIALIZED.
esp_err_t ret = nvs_flash_init ();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES ||
ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {ESP_ERROR_CHECK ( nvs_flash_erase ());
ESP_ERROR_CHECK (nvs_flash_init ());
}
2.phy_init (inside the Wi-Fi/BT protocol stack, developers only need to start the protocol stack)
/* Wi-Fi example: The protocol stack will automatically read the calibration data at 0xF000*/
esp_netif_init ();
esp_event_loop_create_default ();
esp_netif_create_default_wifi_sta ();
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT ();
ESP_ERROR_CHECK (esp_wifi_init (&cfg)); // phy_init will be loaded internally
3. Factory (ROM bootloader runs directly, no code is required for the application layer)
4. vfs (FAT) – Mount the 10 MB partition starting at 0x200000 as /vfs
void app_main (void) {
/* 1. NVS initialization*/
esp_err_t ret = nvs_flash_init ();
if (ret == ESP_ERR_NVS_NO_FREE_PAGES ||
ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {ESP_ERROR_CHECK ( nvs_flash_erase ());
ESP_ERROR_CHECK (nvs_flash_init ());
}
/* 2. Wi-Fi/BT → Automatically use the phy_init partition*/
esp_netif_init ();
esp_event_loop_create_default ();
esp_netif_create_default_wifi_sta ();
wifi_init_config_t wifi_cfg = WIFI_INIT_CONFIG_DEFAULT ();
ESP_ERROR_CHECK (esp_wifi_init (&wifi_cfg));
/* 3. Mount FAT file system*/
mount_fat ();
/* 4. Mount the SPIFFS file system*/
mount_spiffs ();
/* 5. Main loop or other business logic*/
for (;;) {vTaskDelay ( pdMS_TO_TICKS ( 1000));
}}
FAQ
1.What is the partition table in ESP32?
The partition table in ESP32 defines how SPI Flash is divided into different regions, such as application storage, system data (NVS, PHY), and file systems like SPIFFS or FATFS.
2.Where is the ESP32 partition table stored?
By default, the ESP32 partition table is stored at offset 0x8000 in Flash. The bootloader reads it during startup to determine how to load applications and access data.
3.How do I customize the ESP32 partition table?
You can create a custom CSV file (e.g., partitions.csv) and specify it in the project’s CMakeLists.txt or via ESP-IDF menuconfig. This allows defining partitions for OTA, larger NVS, or custom data storage.
4.How do I mount SPIFFS or FATFS on ESP32?
For SPIFFS, use esp_vfs_spiffs_register(). For FATFS, use esp_vfs_fat_spiflash_mount(). Both require defining the correct partition label and initialization code in your ESP-IDF project.
5.Why do I need multiple app partitions in ESP32?
Multiple app partitions are required for OTA (Over-The-Air) updates. With at least two partitions (ota_0 and ota_1), the ESP32 can safely switch between firmware versions during updates.
END
0
Copyright Notice: Our original article was published byPa2sw0rd on 2025-09-05, total 9534 words.
Reproduction Note: Unless otherwise specified, all articles are published by cc-4.0 protocol. Please indicate the source of reprint.
Microsoft said Saturday that clients of its Azure cloud platform might experience increased latency after multiple undersea cables were cut in the Red Sea, as reported in Bloomberg. In a status update, the company said traffic going through the Middle East or ending in Asia or Europe had been affected. It did not say who had...
A complete guide to STM32 GPIO modes. Learn about Push-Pull, Open-Drain, Alternate Functions, Floating, Pull-Up, Pull-Down, and Analog inputs, with circuit diagrams, register explanations, and practical applications. Preface: STM32 has eight modes, as follows: The STM32 standard IO structure diagram is as follows: The following circuit is a protection circuit. When the voltage is greater...
This article provides a detailed solution to the “com.mongodb.MongoSocketOpenException: Connection refused” error that occurs when starting a Spring Boot project—even without any MongoDB configuration. It explains why the mongodb-driver-sync dependency triggers auto-configuration and offers two methods to disable MongoAutoConfiguration, helping developers quickly troubleshoot similar issues. 1. Background & Environment Overview To meet business requirements, a...
The European Commission announced this week that it’s fining Google €2.95 billion (just under $3.5 billion). The commission found that Google had violated European Union antitrust rules by favoring its own advertising services. Specifically, the commission said Google“abused”its“dominant positions”by favoring its ad exchange AdX in both its publisher ad server and in its ad-buying tools. The commission...