当前位置: 首页 > news >正文

esp32(自定义分区)coredump

前言
这章主要讲述 自定义分区

1:环境
VSCODE+idf5.4
ESP32 C3

2:配置
在这里插入图片描述
Custom partition table CSV (CONFIG_PARTITION_TABLE_CUSTOM)
指定项目要使用的分区表 CSV 的路径。
有关更多信息,请参阅《ESP-IDF 编程指南》中的 “分区表” 部分。

生成分区二进制文件
分区文件是 CSV 格式,但是需要生成二进制文件才能被写入 FLASH,工具 gen_esp32part.py 被用于文件转化(CVS 和 二进制)。
转化 CVS 为二进制文件:
python gen_esp32part.py input_partitions.csv binary_partitions.bin
转化二进制为 CVS 文件:
python gen_esp32part.py binary_partitions.bin input_partitions.csv

3:字段说明

Bootloader 分区
位置:固定从0x0开始
大小:通常为 0x8000(32KB)
由 ESP-IDF 自动生成,无需在分区表中显式定义

参考 https://docs.espressif.com/projects/esp-idf/zh_CN/latest/esp32/api-guides/partition-tables.html
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

4:在工程目录下创建
没创建会提示
ninja: error: ‘D:/code/idf_code/testota2/testota2/partitions.csv’, needed by ‘partition_table/partition-table.bin’, missing and no known rule to make it

配置下coredump
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

上代码

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "esp_system.h"
#include "esp_partition.h"
#include "esp_log.h"
#include "esp_ota_ops.h"
#include "esp_vfs_fat.h"
#include "nvs.h"
#include "nvs_flash.h"
#include "esp_core_dump.h"
#include "sdkconfig.h"
#include "esp_timer.h"#include "esp_flash.h"
#include "spi_flash_mmap.h"// Log tag
static const char *TAG = "partition_test";// Test data definition
static const char *TEST_STR = "ESP32 Partition Test Data 2024";
#define  TEST_STR_LEN  strlen(TEST_STR) //
static char g_read_buf[256] = {0}; // General read buffer
/////////////////////////////////////////////////////////////////////////////
// Replace all instances of esp_partition_check_writable(part) with this helper function
static bool is_partition_writable(const esp_partition_t *part) {if (!part) return false;// Data partitions are generally writableif (part->type == ESP_PARTITION_TYPE_DATA) {return true;}// App partitions are writable only if they're not the currently running partitionif (part->type == ESP_PARTITION_TYPE_APP) {const esp_partition_t *running = esp_ota_get_running_partition();return (part->address != running->address);}return false;
}
//////////////////////////////////////////////////////////////////////////////////////////// Print partition detailed information
static void print_partition_info(const esp_partition_t *part) {if (!part) {ESP_LOGE(TAG, "Partition pointer is NULL");return;}ESP_LOGI(TAG, "Partition Information:");ESP_LOGI(TAG, "  Label: %s", part->label ? part->label : "None");ESP_LOGI(TAG, "  Type: %s (0x%x)", part->type == ESP_PARTITION_TYPE_APP ? "APP" : part->type == ESP_PARTITION_TYPE_DATA ? "DATA" : "Unknown",part->type);ESP_LOGI(TAG, "  SubType: 0x%x", (int)part->subtype);ESP_LOGI(TAG, "  Address: 0x%08x", (int)part->address);ESP_LOGI(TAG, "  Size: %d KB (0x%x)",(int)( part->size / 1024), (int)part->size);ESP_LOGI(TAG, "  Writable: %s", is_partition_writable(part) ? "Yes" : "No");
}// Get and print current running APP partition
static const esp_partition_t *get_running_app_partition() {const esp_partition_t *running = esp_ota_get_running_partition();ESP_LOGI(TAG, "\n===== Currently Running APP Partition =====");print_partition_info(running);return running;
}// Read partition data (starting from offset 0)
static esp_err_t read_partition_data(const esp_partition_t *part, size_t read_len) {if (!part || read_len == 0) return ESP_ERR_INVALID_ARG;memset(g_read_buf, 0, sizeof(g_read_buf));esp_err_t ret = esp_partition_read(part, 0, g_read_buf, read_len);if (ret == ESP_OK) {ESP_LOGI(TAG, "Read data: %s (Length: %d)", g_read_buf, strlen(g_read_buf));} else {ESP_LOGE(TAG, "Read failed: %s", esp_err_to_name(ret));}return ret;
}// Write partition data (requires erasure first, starting from offset 0)
static esp_err_t write_partition_data(const esp_partition_t *part, const char *data, size_t data_len) {if (!part || !data || data_len == 0) return ESP_ERR_INVALID_ARG;// Check if it's the currently running APP partition (write prohibited)const esp_partition_t *running = esp_ota_get_running_partition();if (part->type == ESP_PARTITION_TYPE_APP && part->address == running->address) {ESP_LOGW(TAG, "Writing to currently running APP partition is prohibited");return ESP_ERR_INVALID_STATE;}// Check if partition is writableif (!is_partition_writable(part)) {ESP_LOGW(TAG, "Partition is not writable, cannot perform write operation");return ESP_ERR_NOT_SUPPORTED;}// Erase partition (erase by sector, ESP32 default sector is 4KB)esp_err_t ret = esp_partition_erase_range(part, 0, part->size);if (ret != ESP_OK) {ESP_LOGE(TAG, "Partition erasure failed: %s", esp_err_to_name(ret));return ret;}// Write dataret = esp_partition_write(part, 0, data, data_len);if (ret == ESP_OK) {ESP_LOGI(TAG, "Write successful: %s (Length: %d)", data, data_len);} else {ESP_LOGE(TAG, "Write failed: %s", esp_err_to_name(ret));}return ret;
}// Test APP type partitions (factory/ota_0/ota_1)
static void test_app_partitions() {ESP_LOGI(TAG, "\n===== Starting APP Type Partition Tests =====");const esp_partition_t *running = esp_ota_get_running_partition();// Define APP partition labels to testconst char *app_labels[] = {"factory", "ota_0", "ota_1"};for (int i = 0; i < sizeof(app_labels)/sizeof(app_labels[0]); i++) {ESP_LOGI(TAG, "\n----- Testing APP Partition: %s -----", app_labels[i]);const esp_partition_t *part = esp_partition_find_first(ESP_PARTITION_TYPE_APP,ESP_PARTITION_SUBTYPE_ANY,app_labels[i]);if (!part) {ESP_LOGE(TAG, "Partition not found: %s", app_labels[i]);continue;}print_partition_info(part);// Read testESP_LOGI(TAG, "Read test:");read_partition_data(part, TEST_STR_LEN);// Write test (skip current running partition)ESP_LOGI(TAG, "Write test:");if (part->address == running->address) {ESP_LOGW(TAG, "Skipping write test for currently running partition");continue;}write_partition_data(part, TEST_STR, TEST_STR_LEN);// Verify writeESP_LOGI(TAG, "Verify write:");read_partition_data(part, TEST_STR_LEN);}
}// Test Data type partitions (nvs/otadata/phy_init/coredump)
static void test_data_partitions() {ESP_LOGI(TAG, "\n===== Starting Data Type Partition Tests =====");// Define Data partitions to test (label + whether to test write)struct {const char *label;bool test_write; // Whether to perform write test (system critical partitions may be read-only)} data_parts[] = {{"nvs", true},{"otadata", false},  // System critical partition, skip write test{"phy_init", false}, // System critical partition, skip write test{"coredump", true}};for (int i = 0; i < sizeof(data_parts)/sizeof(data_parts[0]); i++) {ESP_LOGI(TAG, "\n----- Testing Data Partition: %s -----", data_parts[i].label);const esp_partition_t *part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA,ESP_PARTITION_SUBTYPE_ANY,data_parts[i].label);if (!part) {ESP_LOGE(TAG, "Partition not found: %s", data_parts[i].label);continue;}print_partition_info(part);// Read testESP_LOGI(TAG, "Read test:");read_partition_data(part, TEST_STR_LEN);// Write test (execute based on configuration)if (data_parts[i].test_write) {ESP_LOGI(TAG, "Write test:");write_partition_data(part, TEST_STR, TEST_STR_LEN);// Verify writeESP_LOGI(TAG, "Verify write:");read_partition_data(part, TEST_STR_LEN);} else {ESP_LOGW(TAG, "Skipping write test (system critical partition)");}}
}// Test NVS partition (key-value storage)
static void test_nvs_partition() {ESP_LOGI(TAG, "\n===== Starting NVS Partition Test =====");// Initialize NVSesp_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());ret = nvs_flash_init();}ESP_ERROR_CHECK(ret);// Open NVS namespacenvs_handle_t nvs_handle;ret = nvs_open("test_namespace", NVS_READWRITE, &nvs_handle);if (ret != ESP_OK) {ESP_LOGE(TAG, "Failed to open NVS namespace: %s", esp_err_to_name(ret));return;}// Write test dataconst char *nvs_key = "test_str";ESP_LOGI(TAG, "Writing NVS key-value: %s = %s", nvs_key, TEST_STR);ret = nvs_set_str(nvs_handle, nvs_key, TEST_STR);if (ret != ESP_OK) {ESP_LOGE(TAG, "NVS write failed: %s", esp_err_to_name(ret));nvs_close(nvs_handle);return;}ESP_ERROR_CHECK(nvs_commit(nvs_handle));// Read test datasize_t required_size = 0;ret = nvs_get_str(nvs_handle, nvs_key, NULL, &required_size);if (ret != ESP_OK && ret != ESP_ERR_NVS_NOT_FOUND) {ESP_LOGE(TAG, "NVS read failed: %s", esp_err_to_name(ret));nvs_close(nvs_handle);return;}if (ret == ESP_ERR_NVS_NOT_FOUND) {ESP_LOGE(TAG, "NVS key not found: %s", nvs_key);nvs_close(nvs_handle);return;}char *nvs_val = malloc(required_size);ret = nvs_get_str(nvs_handle, nvs_key, nvs_val, &required_size);ESP_LOGI(TAG, "Reading NVS key-value: %s = %s", nvs_key, nvs_val);free(nvs_val);nvs_close(nvs_handle);
}// Test Data partition (FAT file system + log storage)
static void test_data_fat_partition() {ESP_LOGI(TAG, "\n===== Starting Data(FAT) Partition Test =====");// Find data partitionconst esp_partition_t *data_part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA,ESP_PARTITION_SUBTYPE_DATA_FAT,"data");if (!data_part) {ESP_LOGE(TAG, "Data partition not found");return;}print_partition_info(data_part);// Mount FAT file systemstatic wl_handle_t wl_handle;const char *base_path = "/data";ESP_LOGI(TAG, "Mounting FAT file system to: %s", base_path);esp_vfs_fat_mount_config_t mount_config = {.max_files = 5,.format_if_mount_failed = true, // Auto-format on first use.allocation_unit_size = CONFIG_WL_SECTOR_SIZE};esp_err_t ret = esp_vfs_fat_spiflash_mount(base_path, data_part->label, &mount_config, &wl_handle);if (ret != ESP_OK) {ESP_LOGE(TAG, "Mount failed: %s", esp_err_to_name(ret));return;}// Write log fileconst char *log_file = "/data/test_log.txt";ESP_LOGI(TAG, "Writing log file: %s", log_file);FILE *f = fopen(log_file, "a");if (!f) {ESP_LOGE(TAG, "Failed to open log file");esp_vfs_fat_spiflash_unmount(base_path, wl_handle);return;}fprintf(f, "Test log: %s (Time: %lld ms)\n", TEST_STR, esp_timer_get_time() / 1000);fclose(f);// Read log fileESP_LOGI(TAG, "Reading log file: %s", log_file);f = fopen(log_file, "r");if (!f) {ESP_LOGE(TAG, "Failed to read log file");esp_vfs_fat_spiflash_unmount(base_path, wl_handle);return;}char log_buf[256] = {0};while (fgets(log_buf, sizeof(log_buf), f)) {ESP_LOGI(TAG, "Log content: %s", log_buf);}fclose(f);// Unmount file systemesp_vfs_fat_spiflash_unmount(base_path, wl_handle);ESP_LOGI(TAG, "FAT file system unmounted");
}// Test Core Dump partition (simulate crash and store)
static void test_coredump_partition() {ESP_LOGI(TAG, "\n===== Starting Core Dump Partition Test =====");// Find coredump partition (works if partition is defined in partitions.csv)const esp_partition_t *coredump_part = esp_partition_find_first(ESP_PARTITION_TYPE_DATA,ESP_PARTITION_SUBTYPE_DATA_COREDUMP,"coredump");if (!coredump_part) {ESP_LOGE(TAG, "Coredump partition not found - check partitions.csv");return;}print_partition_info(coredump_part);// Check core dump configuration (IDF 5.4 compatible)#if CONFIG_ESP_COREDUMP_ENABLE_TO_FLASHESP_LOGI(TAG, "Core dump enabled: Flash (configured in menuconfig)");#elif CONFIG_ESP_COREDUMP_ENABLE_TO_UARTESP_LOGI(TAG, "Core dump enabled: UART (configured in menuconfig)");#elseESP_LOGW(TAG, "Core dump is disabled - enable in menuconfig");#endif// Test trigger (uncomment to test)ESP_LOGW(TAG, "To test core dump, uncomment the line below (will crash device)");ESP_LOGI(TAG, "Triggering core dump...");// abort(); // Generates core dump when enabledint* pp =NULL;*pp =1;ESP_LOGI(TAG, "Triggering core dump end");
}void app_main(void) {vTaskDelay(pdMS_TO_TICKS(3000));ESP_LOGI(TAG, "===== ESP32 Partition Comprehensive Test (IDF 5.4) =====");//  ESP_LOGI(TAG, "Total Flash capacity: %d MB", spi_flash_get_chip_size() / (1024 * 1024));{uint32_t size_flash_chip;esp_flash_get_size(NULL, &size_flash_chip);ESP_LOGI(TAG, "flash size = %ld bytes\n", size_flash_chip);}vTaskDelay(pdMS_TO_TICKS(3000));// 1. Display current running partitionget_running_app_partition();// 2. Test APP type partitions (factory/ota_0/ota_1)test_app_partitions();// 3. Test Data type partitions (nvs/otadata/phy_init/coredump)test_data_partitions();// 4. Special test for NVS partitiontest_nvs_partition();// 5. Special test for Data(FAT) partition (log storage)test_data_fat_partition();// 6. Special test for Core Dump partition//  test_coredump_partition();ESP_LOGI(TAG, "\n===== All Tests Completed =====");//int  count =0;while (1) {vTaskDelay(pdMS_TO_TICKS(1000));if(++count == 120){test_coredump_partition();}}
}

查看分区表
idf.py partition_table
在这里插入图片描述
在这里插入图片描述
5:查看coredump
1>获取 Flash 中的 Core Dump
python + esptool.py + 串口号 + read_flash + coredume存储的falsh地址 + 大小 + core.bin(最终要生成的文件用于解析,使用方便查找的路径)
//读取 coredump 分区(地址 0x110000,大小 64K=0x10000)
python D:\soft_install\Espressif\frameworks\esp-idf-v5.4.1\components\esptool_py\esptool/esptool.py --port COM6 read_flash 0x110000 0x10000 D:\code\idf_code\coredump_raw2.bin

2>分析 Core Dump info_corefile
解析 Core Dump 需要编译生成的 ELF 文件(包含符号表信息,用于映射二进制地址到代码中的函数名)。ELF
文件位于项目的 build 目录下,名称为 <项目名>.elf(如 partition_test.elf)。
coredump解析core.bin文件说明
指令:
python + espcoredump.py + info_corefile + --core + core.bin + --core-format raw + elf文件

python D:\code\idf_code\testesp32\components\components\espcoredump\espcoredump.py info_corefile --core D:\code\idf_code\coredump_raw2.bin --core-format raw D:\code\idf_code\testota2\testota2\build\testota2.elf

6:测试结果 如果对你又帮助,麻烦点个赞,加个关注
在这里插入图片描述
在这里插入图片描述

http://www.lryc.cn/news/623716.html

相关文章:

  • C语言私人学习笔记分享
  • 关于第一次接触Linux TCP/IP网络相关项目
  • 使用Ansys Fluent进行倒装芯片封装Theta-JA热阻表征
  • 计算机网络 OSI 七层模型和 TCP 五层模型
  • IP 分片和组装的具体过程
  • 数字货币的法律属性与监管完善路径探析
  • Trae 辅助下的 uni-app 跨端小程序工程化开发实践分享
  • 【Java后端】Spring Boot 集成 MyBatis-Plus 全攻略
  • 【昇腾】单张48G Atlas 300I Duo推理卡MindIE+WebUI方式跑14B大语言模型_20250817
  • 前端vue3+后端spring boot导出数据
  • Java 大视界 -- Java 大数据分布式计算在基因测序数据分析与精准医疗中的应用(400)
  • Linux | i.MX6ULL网络通信-套字节 UDP(第十八章)
  • 计算机网络 TCP 延迟确认机制
  • 矿物分类案列 (一)六种方法对数据的填充
  • 安卓开发者自学鸿蒙开发2页面高级技巧
  • 安卓14系统应用收不到开机广播
  • Android原生(Kotlin)与Flutter混合开发 - 设备控制与状态同步解决方案
  • Javascript面试题及详细答案150道之(106-120)
  • Python实现区域生长和RANSAC聚类
  • 职场新人如何在快速适应工作的同时保持自我成长节奏?
  • JUC常用线程辅助类详解
  • JavaScript 性能优化实战大纲
  • [GLM-4.5] LLM推理服务器(SGLang/vLLM) | 工具与推理解析器
  • c_str()函数的详细解析
  • 【PHP】Hyperf:接入 Nacos
  • Python | 解决 matplotlib 中文乱码
  • 基于MATLAB多智能体强化学习的出租车资源配置优化系统设计与实现
  • [论文阅读] 人工智能 + 职业教育 | 从技能操作者到技术反思者:生成式AI驱动职业教育学习范式转型
  • 豆包 Java的23种设计模式
  • 微调 AnomalyCLIP——基于对象无关提示学习与全局 - 局部优化的零样本异常检测框架性能验证