跳到主要内容

ESP32应用笔记

阅读量: 101阅读人次: 102

开发 ESP32 需要持续关注官方帮助手册

esp32s3 在中断不能执行耗时操作,例如写flash。那么 esp32s3 是如何实现当程序crash时,将coredump写入flash的呢?

在终端使用 idf 工具:

$env:IDF_TOOLS_PATH = "D:\Espressif\.espressif"
D:\Espressif\esp\v5.4.1\esp-idf\export.ps1

生成反汇编代码:

xtensa-esp32s3-elf-objdump -S build/geminai.elf > build/disassembly.lst

将 ESP32-S3 的内存地址转换为对应的源代码位置,用于软件触发Panic时打印的函数调用栈信息,在使用 IDF 提供的串口 Monitor 工具时,会自动帮我做如下命令解析:

xtensa-esp32s3-elf-addr2line -pfiaC -e build\geminai.elf \
0x4005625d:0x3fcb5d90 0x40385b49:0x3fcb5dc0

避免过多创建任务

SRAM比较有限,在官方手册也提到了 PSRAM 最好不要作为任务栈的限制。其实很多任务都形如:

void task_handler(void *args) {
while(1) {
wait_something();
do_something();
sleep();
}
}

这时可以考虑使用 ESP 定时器事件循环库 进行减少任务创建数量以及程序框架优化。

FreeRTOS 队列元素不能过大。

FreeRTOS 的 pvPortMalloc() 函数申请内存来自 SRAM,所以 xQueueCreate() 等申请的内存都来自 SRAM。例如如下创建 log_queue 队列就消耗了 10KB 的SRAM:

typedef struct {
char message[1024];
} log_entry_t;

QueueHandle_t log_queue = xQueueCreate(10, sizeof(log_entry_t)); // 这里消耗了10k的SRAM

可以使用 xQueueCreateStatic() 自行设置 PSRAM 为队列的存储空间,减少SRAM开销。或者队列保存的元素大小应该尽可能的小。

stdlib 的内存申请函数 malloc() 都是调用 heap_caps_malloc_default() ,存在一个 malloc_alwaysinternal_limit 变量控制是从sram 还是 psram 分配。

可以在 Kconfig 中做如下配置以使堆内存都从 PSRAM 中申请:

CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=0