ESP32 S3 入门工程:打印系统信息
文章目录前言一、工程要达成什么二、工程结构三、板级默认配置N16R8四、编译、烧录、监视五、代码走读main/sysinfo.c5.1 头文件与职责5.2 app_main 流程5.3 芯片信息5.4 内存信息重点5.5 FreeRTOS 两行六、运行输出七、和「官方 hello_world」的关系八、建议你改的几处小练习九、踩坑速查十、本篇命令小结全部代码参考链接目录 | 上篇 | 下篇前言环境装好、命令会用、板卡规格也清楚之后该动手写第一个固件了。本篇以仓库中的sysinfo工程为例用 ESP-IDF 在ESP32-S3上跑起来经串口打印芯片、CPU、Flash、堆与 PSRAM 等信息并每秒刷新剩余堆。目标不是堆功能而是把这条链路跑通建工程 → set-target → 配 N16R8 → 写 app_main → build → flash → monitor工程路径相对本仓库根sysinfo/。一、工程要达成什么启动后串口大致看到三类信息块内容Chip目标芯片、IDF 版本、核数、硅片修订、Wi-Fi/BLE、CPU 频率、Flash 容量Memory总堆空闲、历史最小空闲、片内 / DMA / PSRAM 空闲与最大连续块FreeRTOSTick 频率、当前任务数随后每秒一行 uptime 与堆快照确认程序在跑、堆没有异常掉光。实测本系列默认板可对上这些量级项期望量级Flash16 MBPSRAM约 8 MB可用日志里常有Found 8MB PSRAMCPU默认常见160 MHz可在 menuconfig 改到 240片内空闲约数百 KB总堆空闲片内 PSRAM约8 MB二、工程结构sysinfo/ CMakeLists.txt # 工程入口project(sysinfo) sdkconfig.defaults # N16R8 默认16MB Flash Octal PSRAM sdkconfig # set-target / menuconfig 后生成本地生效 main/ CMakeLists.txt # 注册源文件 sysinfo.c # app_main 与打印逻辑 README.md # 工程内速查 build/ # 编译产物勿手改要点工程根的CMakeLists.txt必须include($ENV{IDF_PATH}/tools/cmake/project.cmake)再project(...)。main组件用idf_component_register声明源文件入门阶段一个.c足够。sdkconfig.defaults存「换机器也希望一致」的板级默认首次配置会合并进sdkconfig。创建方式# 官方脚手架idf.py create-project sysinfocdsysinfo三、板级默认配置N16R8sdkconfig.defaults内容# ESP32-S3-N16R8 defaults (see esp32/e003.md) CONFIG_ESPTOOLPY_FLASHSIZE_16MBy CONFIG_SPIRAMy CONFIG_SPIRAM_MODE_OCTy CONFIG_SPIRAM_SPEED_80My若你的板不是 Octal PSRAM / 不是 16 MB Flash先改 defaults 或menuconfig再fullclean后重新set-target/build。四、编译、烧录、监视串口名以本机为准macOS 上 S3 原生 USB 常见为/dev/cu.usbmodem*ls/dev/cu.usbmodem*完整流程get_idfcdsysinfo idf.py set-target esp32s3# 首次或换目标时需要idf.py build idf.py-p/dev/cu.usbmodemXXXXXXXX flash monitor操作说明退出监视器Ctrl]只烧不监idf.py -p PORT flash复位后再看日志监视器里按CtrlT再CtrlR见 e002成功烧录时 esptool 会打印芯片特性例如双核、Embedded PSRAM 8MB 等可与后面应用打印交叉核对。五、代码走读main/sysinfo.cESP-IDF 应用入口是app_main由系统在启动任务里调用不是桌面程序的main。5.1 头文件与职责头文件用途esp_chip_info.hesp_chip_info()核数、特性、修订号esp_flash.hesp_flash_get_size()Flash 容量esp_system.hIDF 版本、总堆空闲 / 历史最小空闲esp_heap_caps.h按能力查堆INTERNAL/DMA/SPIRAMfreertos/FreeRTOS.htask.hvTaskDelay、任务数、Ticksdkconfig.hCONFIG_*宏目标名、CPU 频率、是否开 SPIRAM5.2app_main流程voidapp_main(void){// 1. 一次性打印 Chip / Memory / FreeRTOSprint_chip_info();print_memory_info();print_rtos_info();// 2. 死循环每秒打一行堆快照固件常驻不要 return 后空等while(1){// printf uptime heap ...vTaskDelay(pdMS_TO_TICKS(1000));}}入门习惯需要周期干活时用vTaskDelay避免空转占满 CPU。5.3 芯片信息esp_chip_info_tchip_info;esp_chip_info(chip_info);// chip_info.cores / .revision / .featuresCONFIG_IDF_TARGET、CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ来自配置编译期写入用来打印「当前固件按什么目标、默认主频」构建。Flash 用运行时 APIuint32_tflash_size;esp_flash_get_size(NULL,flash_size);// 字节再换成 MB5.4 内存信息重点API含义esp_get_free_heap_size()当前总空闲堆含已并入分配器的 PSRAMesp_get_minimum_free_heap_size()启动以来空闲堆的最小值看有没有短暂吃紧heap_caps_get_free_size(MALLOC_CAP_INTERNAL)片内 SRAM 空闲heap_caps_get_largest_free_block(...)最大连续空闲块比「总空闲」更能说明能否一次malloc大块heap_caps_get_free_size(MALLOC_CAP_DMA)可给 DMA 用的空闲heap_caps_get_free_size(MALLOC_CAP_SPIRAM)PSRAM 空闲需CONFIG_SPIRAM代码里用#if CONFIG_SPIRAM包住 PSRAM 打印没开外挂 RAM 时仍能编译通过并提示 disabled。5.5 FreeRTOS 两行configTICK_RATE_HZ// 常见 100 HzuxTaskGetNumberOfTasks()// 当前任务数含系统任务本例不自建任务数字会偏小够用来确认 RTOS 已起来。六、运行输出执行命令写入并监测idf.py-p/dev/cu.usbmodemXXXXXXXX flash monitor输出结果*** ESP32-S3 sysinfo *** Chip Target esp32s3 IDF version v6.0.1 CPU cores 2 Silicon revision v0.2 Features Wi-Fi BLE CPU frequency 160 MHz Flash size 16 MB (external) Memory Heap free 8745164 bytes (8540.2 KB) Heap min free 8745164 bytes (8540.2 KB) Internal free 391039 bytes ( 381.9 KB) Internal largest 294912 bytes ( 288.0 KB) DMA-capable free 383251 bytes ( 374.3 KB) PSRAM free 8386156 bytes (8189.6 KB) PSRAM largest 8257536 bytes (8064.0 KB) FreeRTOS Tick rate 100 Hz Tasks 5 [uptime 0s] free heap8745164 internal391039 psram8386156 [uptime 1s] free heap8745164 internal391039 psram8386156 [uptime 2s] free heap8745164 internal391039 psram8386156 [uptime 3s] free heap8745164 internal391039 psram8386156 [uptime 4s] free heap8745164 internal391039 psram8386156启动日志里还可留意SPI Flash Size : 16MBFound 8MB PSRAM device/SPI SRAM memory test OKcpu freq: 160000000 Hz七、和「官方 hello_world」的关系官方examples/get-started/hello_world也会打印芯片与最小空闲堆然后倒计时esp_restart()。sysinfo在同样入门路径上多做了三件事更贴本系列板卡拆开片内 / DMA / PSRAM方便对照上篇用sdkconfig.defaults固化 N16R8常驻循环打堆而不是自动重启便于盯监视器会改sysinfo之后再去读官方示例会轻松很多。八、建议你改的几处小练习按兴趣任选巩固 API不必一次做完把 CPU 默认频率改为240 MHzmenuconfig→ ESP System Settings重编烧录看打印是否变化。增加一行打印esp_get_free_internal_heap_size()若当前 IDF 提供或当前任务名pcTaskGetName(NULL)。用heap_caps_malloc(1 * 1024 * 1024, MALLOC_CAP_SPIRAM)申请 1 MB打印前后 PSRAM free 差值再free。把 1 秒周期改成CONFIG可配或拆成独立 FreeRTOS 任务。九、踩坑速查现象排查idf.py: command not foundget_idf或source ~/esp/esp-idf/export.sh找不到串口换数据线ls /dev/cu.usbmodem*驱动 / 线材问题见 e001Flash 不是 16 MB / 校验失败CONFIG_ESPTOOLPY_FLASHSIZE_16MB模组是否真是 N16PSRAM free 为 0 或启动报 PSRAM 错Octal 模式与频率是否匹配板卡见 e003监视器乱码波特率是否 115200默认确认连的是正在跑本固件的口改 defaults 不生效删掉或调整已有sdkconfig或idf.py fullclean后重新配置再编十、本篇命令小结get_idfcdsysinfo idf.py set-target esp32s3 idf.py build idf.py-p/dev/cu.usbmodemXXXXXXXX flash monitor# 退出监视Ctrl]全部代码sysinfo.c/* * ESP32-S3 入门打印芯片 / CPU / 内存等信息 */#includeinttypes.h#includestdio.h#includeesp_chip_info.h#includeesp_flash.h#includeesp_heap_caps.h#includeesp_system.h#includefreertos/FreeRTOS.h// IWYU pragma: keep#includefreertos/task.h#includesdkconfig.hstaticvoidprint_bytes(constchar*label,size_tbytes){printf( %-22s %8zu bytes (%6.1f KB)\n,label,bytes,bytes/1024.0);}staticvoidprint_chip_info(void){esp_chip_info_tchip_info;uint32_tflash_size0;esp_chip_info(chip_info);printf(\n Chip \n);printf( Target %s\n,CONFIG_IDF_TARGET);printf( IDF version %s\n,esp_get_idf_version());printf( CPU cores %d\n,chip_info.cores);printf( Silicon revision v%d.%d\n,chip_info.revision/100,chip_info.revision%100);printf( Features %s%s%s%s\n,(chip_info.featuresCHIP_FEATURE_WIFI_BGN)?Wi-Fi :,(chip_info.featuresCHIP_FEATURE_BT)?BT :,(chip_info.featuresCHIP_FEATURE_BLE)?BLE :,(chip_info.featuresCHIP_FEATURE_EMB_PSRAM)?embedded-PSRAM :);#ifdefined(CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ)printf( CPU frequency %d MHz\n,CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ);#endifif(esp_flash_get_size(NULL,flash_size)ESP_OK){printf( Flash size %PRIu32 MB (%s)\n,flash_size/(1024*1024),(chip_info.featuresCHIP_FEATURE_EMB_FLASH)?embedded:external);}else{printf( Flash size (read failed)\n);}}staticvoidprint_memory_info(void){printf(\n Memory \n);print_bytes(Heap free,esp_get_free_heap_size());print_bytes(Heap min free,esp_get_minimum_free_heap_size());print_bytes(Internal free,heap_caps_get_free_size(MALLOC_CAP_INTERNAL));print_bytes(Internal largest,heap_caps_get_largest_free_block(MALLOC_CAP_INTERNAL));print_bytes(DMA-capable free,heap_caps_get_free_size(MALLOC_CAP_DMA));#ifCONFIG_SPIRAMprint_bytes(PSRAM free,heap_caps_get_free_size(MALLOC_CAP_SPIRAM));print_bytes(PSRAM largest,heap_caps_get_largest_free_block(MALLOC_CAP_SPIRAM));#elseprintf( PSRAM disabled in sdkconfig\n);#endif}staticvoidprint_rtos_info(void){printf(\n FreeRTOS \n);printf( Tick rate %u Hz\n,(unsigned)configTICK_RATE_HZ);printf( Tasks %u\n,(unsigned)uxTaskGetNumberOfTasks());}voidapp_main(void){printf(\n*** ESP32-S3 sysinfo ***\n);print_chip_info();print_memory_info();print_rtos_info();printf(\n);intsec0;while(1){printf([uptime %ds] free heap%PRIu32 internal%zu#ifCONFIG_SPIRAM psram%zu#endif\n,sec,esp_get_free_heap_size(),heap_caps_get_free_size(MALLOC_CAP_INTERNAL)#ifCONFIG_SPIRAM,heap_caps_get_free_size(MALLOC_CAP_SPIRAM)#endif);fflush(stdout);vTaskDelay(pdMS_TO_TICKS(1000));sec;}}参考链接本仓库工程../sysinfo/ESP-IDF · 入门 Hello Worldhttps://docs.espressif.com/projects/esp-idf/zh_CN/stable/esp32s3/get-started/index.html堆分配 / heap_capshttps://docs.espressif.com/projects/esp-idf/zh_CN/stable/esp32s3/api-reference/system/mem_alloc.html芯片信息https://docs.espressif.com/projects/esp-idf/zh_CN/stable/esp32s3/api-reference/system/misc_system_api.html