十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

ESP-IDF 杂项系统 API 实战指南:软件复位、复位原因、堆内存、MAC 地址与版本信息

ESP-IDF 杂项系统 API 实战指南:软件复位、复位原因、堆内存、MAC 地址与版本信息 ESP-IDF 杂项系统 API 实战指南软件复位、复位原因、堆内存、MAC 地址与版本信息【免费下载链接】esp-idfEspressif IoT Development Framework. Official development framework for Espressif SoCs.项目地址: https://gitcode.com/GitHub_Trending/es/esp-idf本指南以 ESP-IDF 官方文档 Miscellaneous System APIs 为骨架系统讲解 ESP-IDF 提供的一组小而关键的系统级接口软件复位与关机回调、复位原因查询、堆内存状态获取、MAC 地址的读取/自定义/派生规则、芯片与 SDK 版本信息、调试辅助工具以及应用版本管理。读完本文你将掌握这些 API 的调用方式、底层原理与典型使用场景并能直接应用于自己的 ESP-IDF 工程。软件复位Software ResetESP-IDF 提供了esp_restart()函数用于执行芯片的软件复位。调用该函数后程序停止执行CPU 被复位在 ESP32 上为双核同时复位见 esp_system.h 中对 Restart PRO and APP CPUs 的说明随后由 bootloader 重新加载应用并再次启动执行。函数原型位于 components/esp_system/include/esp_system.hvoid esp_restart(void) __attribute__((__noreturn__));该函数声明为noreturn调用后不会返回。需要注意可从 PRO 与 APP CPU 任意一侧调用复位成功后CPU 复位原因将被记录为SW_CPU_RESET对应枚举ESP_RST_SW除 Wi-Fi、BT、UART0、SPI1 和传统定时器外外设不会复位。关机回调Shutdown Handler与atexit类似的机制由esp_register_shutdown_handler()提供注册的回调会在esp_restart()触发的重启之前被自动调用适合用于保存关键状态、关闭外设或输出日志。对应接口定义同样位于 esp_system.htypedef void (*shutdown_handler_t)(void); esp_err_t esp_register_shutdown_handler(shutdown_handler_t handle); esp_err_t esp_unregister_shutdown_handler(shutdown_handler_t handle);返回值含义ESP_OK成功ESP_ERR_INVALID_ARG传入 NULLESP_ERR_INVALID_STATE处理器重复注册/注销ESP_ERR_NO_MEM内存分配失败。注册数量仅受可用堆内存限制。从源码结构还可以看到一种静态链接期注册方式ESP_SHUTDOWN_HANDLER_REGISTER(fn, prio)esp_system.h它通过链接器段esysev_shdn按优先级排序分发低优先级值先执行且总是先于动态注册的处理器执行。若业务上对回调执行顺序有确定性要求应优先使用该宏。复位原因Reset Reason应用可能因多种原因启动或重启调用esp_reset_reason()可获取最近一次的复位原因返回类型为esp_reset_reason_t。完整枚举定义见 esp_system.h枚举值含义ESP_RST_UNKNOWN无法确定复位原因ESP_RST_POWERON上电事件复位ESP_RST_EXT外部引脚复位ESP32 不适用ESP_RST_SW通过esp_restart的软件复位ESP_RST_PANIC异常/恐慌导致的软件复位ESP_RST_INT_WDT中断看门狗导致的复位软件或硬件ESP_RST_TASK_WDT任务看门狗复位ESP_RST_WDT其他看门狗复位ESP_RST_DEEPSLEEP退出深度睡眠后的复位ESP_RST_BROWNOUT掉电欠压复位软件或硬件ESP_RST_SDIO通过 SDIO 复位ESP_RST_USBUSB 外设复位ESP_RST_JTAGJTAG 复位ESP_RST_EFUSEeFuse 错误导致的复位ESP_RST_PWR_GLITCH检测到电源毛刺ESP_RST_CPU_LOCKUPCPU 锁死双重异常导致的复位典型用途在app_main()启动时判断设备是被看门狗踢复位还是异常崩溃后复位从而决定是否进入恢复流程或输出诊断信息。堆内存状态Heap MemoryESP-IDF 提供两个与堆内存相关的函数esp_system.hesp_get_free_heap_size()返回当前可用堆内存大小字节。注意返回值可能大于能够分配的最大连续内存块esp_get_minimum_free_heap_size()返回应用生命周期内曾经出现过的最小可用堆内存大小可用于评估内存峰值压力。此外esp_get_free_internal_heap_size()返回内部片上堆的可用大小。需要说明的是ESP-IDF 支持多堆与多种能力capability属性上述函数返回的是可通过malloc家族分配的内存大小。更细粒度的堆能力分配如heap_caps_malloc请参考 Heap Memory Allocation中文版见 docs/zh_CN/api-reference/system/mem_alloc.rst。MAC 地址MAC AddressMAC 地址相关 API 允许查询和自定义不同网络接口Wi-Fi、Bluetooth、Ethernet 等的 MAC 地址。在 ESP-IDF 中各网络接口的 MAC 地址都由**一个基准 MAC 地址base MAC**计算派生而来。默认使用乐鑫Espressif出厂时预烧录在芯片 eFuse 中的基准 MAC 地址。类型枚举esp_mac_type_t定义在 esp_mac.h包括ESP_MAC_WIFI_STAWi-Fi Station6 字节ESP_MAC_WIFI_SOFTAPWi-Fi SoftAP6 字节ESP_MAC_BT蓝牙6 字节ESP_MAC_ETH以太网6 字节ESP_MAC_IEEE802154IEEE 802.15.48 字节需CONFIG_SOC_IEEE802154_SUPPORTEDyESP_MAC_BASE用于派生其他 MAC 的基准 MAC6 字节ESP_MAC_EFUSE_FACTORY乐鑫出厂烧录的 MAC_FACTORY eFuse6 字节ESP_MAC_EFUSE_CUSTOM客户可烧录的 MAC_CUSTOM eFuse6 字节ESP_MAC_EFUSE_EXTIEEE 802.15.4 扩展字段2 字节需支持 802.15.4获取指定接口 MAC 使用esp_read_mac()其内部先取得 base MAC再按派生算法计算对应接口的 MACesp_mac.h。接口 MAC 派生规则表不同芯片的派生规则不同下表汇总了常见配置base_mac, N表示末字节加 N支持 4 个全局管理 MAC 的芯片默认 4 个含 ESP32/ESP32-C3/S3 等Wi-Fi BT 全功能接口4 个全局管理 MAC默认2 个全局管理 MACWi-Fi Stationbase_macbase_macWi-Fi SoftAPbase_mac, 1本地管理 MAC由 Station MAC 派生Bluetoothbase_mac, 2base_mac, 1Ethernetbase_mac, 3本地管理 MAC由蓝牙 MAC 派生ESP32-S2默认 2 个无蓝牙接口2 个全局管理 MAC默认1 个全局管理 MACWi-Fi Stationbase_macbase_macWi-Fi SoftAPbase_mac, 1本地管理 MAC由 Station MAC 派生Ethernet本地管理 MAC由 SoftAP MAC 派生本地管理 MAC由 base1 派生不推荐ESP32-S3默认 2 个eFuse 仅提供 2 个全局管理 MAC接口2 个全局管理 MAC默认4 个全局管理 MACWi-Fi Stationbase_macbase_macWi-Fi SoftAP本地管理 MAC由 Station MAC 派生base_mac, 1Bluetoothbase_mac, 1base_mac, 2Ethernet本地管理 MAC由蓝牙 MAC 派生base_mac, 3警告ESP32-S3 的 eFuse 只提供 2 个全局管理 MAC 地址。只有在使用客户提供的自定义 base MAC 范围见下文时才应选择 4 个 选项若使用默认乐鑫 eFuse base MAC 却选择 4 个SoftAP 与 Ethernet 将占用该芯片未分配的全局 MAC 槽位base1/3可能与蓝牙 MAC 冲突。ESP32-H2/H21/H4默认 1 个无 Wi-Fi支持 802.15.4接口MAC 地址1 个全局管理默认IEEE 802.15.4由 base_mac 与 MAC_EXT 派生的 EUI-64base_mac[0:2] ‖ MAC_EXT ‖ base_mac[3:5]MAC_EXT 默认为ff:feBluetoothbase_mac说明H2/H21/H4 的 eFuse 中提供 1 个全局管理 MACMAC_FACTORY加 MAC_EXT 字段。蓝牙直接复用 base MAC不加偏移——因为这些芯片没有 Wi-Fi无需第二个全局 MAC 槽位。ESP32-P4默认 1 个接口MAC 地址1 个全局管理默认Ethernetbase_mac说明ESP32-P4 上CONFIG_ESP32P4_UNIVERSAL_MAC_ADDRESSES固定为 1 个全局管理 MAC。上述表项由CONFIG_{TARGET}_UNIVERSAL_MAC_ADDRESSES配置决定对应源码中的CONFIG_ESP_MAC_UNIVERSAL_MAC_ADDRESSES见 esp_mac.h 中UNIVERSAL_MAC_ADDR_NUM的定义。另外即使芯片没有集成以太网 MAC如 ESP32-C 系列仍可计算以太网 MAC 地址但只能用于 SPI 以太网等外部以太网设备参考 esp_eth。自定义接口 MACCustom Interface MAC如果不想使用由 base MAC 派生的地址可以调用esp_iface_mac_addr_set(mac, type)覆盖指定接口的 MAC。被覆盖的接口在 base MAC 改变后不受影响。底层实现见 esp_mac.h。自定义 Base MACCustom Base MAC默认 base MAC 预烧录在 eFuse BLK1ESP32 为 BLK0。如需改用自定义 base MAC在初始化任何网络接口或调用esp_read_mac之前调用esp_iface_mac_addr_set(mac, ESP_MAC_BASE)或旧 APIesp_base_mac_addr_set()自定义 MAC 可存储在任何受支持的存储介质中如 flash、NVS分配自定义 base MAC 时要保证派生出的各接口 MAC 互不重叠并依据上文表格通过CONFIG_{TARGET}_UNIVERSAL_MAC_ADDRESSES配置可派生的全局 MAC 数量。esp_base_mac_addr_set()的两个注意点esp_mac.hbase MAC 必须是单播 MAC首字节最低位必须为 0如果不使用有效 OUI应设置 本地管理 位首字节 bit 值 0x02以避免冲突。官方还提示也可在网络初始化后调用esp_netif_set_mac()设置具体接口使用的 MAC但推荐使用上述 base MAC 方案以避免原始 MAC 地址在被替换前短暂出现在网络中。eFuse 中的自定义 MACCustom MAC Address in eFuse从 eFuse 读取自定义 MAC 时可调用辅助函数esp_efuse_mac_get_custom()esp_mac.h或用esp_read_mac(mac, ESP_MAC_EFUSE_CUSTOM)。该 MAC 存储在 eFuse BLK3且假定采用以下存储格式ESP32BLK3 含版本与 CRC 校验字段位数位范围说明Version8191:1840 无效其他有效Reserved128183:56—MAC address4855:8—MAC address CRC87:0CRC-8-CCITT多项式 0x07注意ESP32 若启用了 3/4 编码方案3/4 coding scheme该块所有 eFuse 字段必须同时烧录。esp_efuse_mac_get_custom()在 ESP32 上会校验版本与 CRC异常时返回ESP_ERR_INVALID_VERSION/ESP_ERR_INVALID_CRC。其他芯片BLK3无版本/CRC 字段字段位数位范围MAC address48200:248注意非 ESP32 芯片的 BLK3 烧录使用 RS 编码RS-coding所有 eFuse 字段必须同时烧录。拿到自定义 eFuse MAC 后将其设置为 base MAC 有两种方式旧 API调用esp_base_mac_addr_set()新 API调用esp_iface_mac_addr_set(mac, ESP_MAC_BASE)。本地管理与全局管理 MACLocal vs Universal芯片出厂时预烧录了足够覆盖所有内部接口的全局管理universally administeredMAC 地址。但使用自定义 MAC 方案时可能无法为所有接口分配全局管理 MAC此时会分配本地管理locally administeredMAC 地址——这类地址仅适用于单个本地网络。esp_derive_local_mac()esp_mac.h在内部完成从全局到本地 MAC 的派生规则如下在全局 MAC 首字节设置 U/L 位bit 值 0x2得到本地 MAC若该位在传入的 全局 MAC 中已置位即传入的其实已是本地 MAC则将首字节与 0x4 做异或保证得到不同的本地 MAC。实战示例base_mac_address官方示例 examples/system/base_mac_address 演示了完整的读取、设置与派生流程核心代码在 base_mac_address_example_main.c通过esp_read_mac(base_mac_addr, ESP_MAC_EFUSE_CUSTOM)从 eFuse BLK3 读取自定义 base MAC读取失败时可按配置回退到ESP_MAC_EFUSE_FACTORY出厂 MAC或直接abort()也支持CONFIG_BASE_MAC_STORED_OTHER_EXTERNAL_STORAGE选项从外部存储flash/EEPROM模拟读取 base MAC用esp_iface_mac_addr_set(base_mac_addr, ESP_MAC_BASE)设置 base MAC依次用esp_read_mac(..., ESP_MAC_WIFI_STA / ESP_MAC_WIFI_SOFTAP / ESP_MAC_BT / ESP_MAC_ETH)读取各接口派生 MAC 并打印演示了用esp_iface_mac_addr_set(base_mac_addr, ESP_MAC_ETH)覆盖 Ethernet MAC末字节 6在支持 802.15.4 的芯片上还读取了ESP_MAC_EFUSE_EXT2 字节与ESP_MAC_IEEE8021548 字节 EUI-64。芯片版本Chip Versionesp_chip_info()函数填充esp_chip_info_t结构体提供芯片修订版本revision、CPU 核心数以及芯片已启用功能的位掩码等信息。接口头文件为 esp_chip_info.h可用于在运行时适配不同芯片特性如根据核心数决定任务分配策略、根据 feature 掩码判断是否支持特定外设。SDK 版本SDK Versionesp_get_idf_version()返回用于编译当前应用的 ESP-IDF 版本字符串与构建系统中的IDF_VER变量一致格式一般为git describe的输出如v6.2.0-xxx-gxxxxxxxxx能区分开发版、预发布版与正式版。该函数声明于 esp_idf_version.h。当前仓库的版本宏为ESP_IDF_VERSION_MAJOR6、ESP_IDF_VERSION_MINOR2、ESP_IDF_VERSION_PATCH0esp_idf_version.h。编译期版本判断宏ESP_IDF_VERSION_MAJOR/ESP_IDF_VERSION_MINOR/ESP_IDF_VERSION_PATCH分别表示主/次/修订版本号整数ESP_IDF_VERSION_VAL(major, minor, patch)将版本号编码为整数用于比较实现为(major 16) | (minor 8) | (patch)ESP_IDF_VERSION当前版本编码后的整数值。典型用法与文档示例一致#include esp_idf_version.h #if ESP_IDF_VERSION ESP_IDF_VERSION_VAL(4, 0, 0) // 启用 ESP-IDF v4.0 起才有的功能 #endif调试辅助工具Debug Helpersesp_debug_helpers.h位于 components/esp_system/include/esp_debug_helpers.h提供运行时调试与栈回溯输出的工具esp_backtrace_print()打印当前栈回溯esp_backtrace_print_all_tasks()打印所有任务的栈回溯esp_backtrace_get_start()与esp_backtrace_get_next_frame()手动迭代回溯帧。这些 API 在诊断崩溃、看门狗超时或异常控制流时非常有用。例如在看门狗复位前注册一个 shutdown handler调用esp_backtrace_print_all_tasks()输出各任务栈即可定位卡死位置。应用版本App Version应用版本存储在esp_app_desc_t结构体中定义见 esp_app_desc.h。该结构位于 DROM 段从二进制文件起始处有一个固定偏移紧随esp_image_header_t与esp_image_segment_header_t之后。其中version字段为字符串类型最大长度 32 字符。如何设置应用版本手动设置在工程的CMakeLists.txt中在include project.cmake之前设置set(PROJECT_VER 0.1.0.1)从配置项读取若启用CONFIG_APP_PROJECT_VER_FROM_CONFIG则使用CONFIG_APP_PROJECT_VER的值自动推断未设置PROJECT_VER时依次尝试$(PROJECT_PATH)/version.txt文件、git describe命令若都不可用PROJECT_VER将回退为1。应用可通过esp_app_get_description()或esp_ota_get_partition_description()获取该版本信息后者用于读取 OTA 分区中的应用描述常用于 OTA 升级时的版本比对、启动时打印固件版本号等场景。小结本文覆盖了 ESP-IDF 杂项系统 API 的六大方面软件复位esp_restart()与关机回调esp_register_shutdown_handler()/ESP_SHUTDOWN_HANDLER_REGISTER复位原因esp_reset_reason()与 15 种esp_reset_reason_t枚举堆内存esp_get_free_heap_size()、esp_get_minimum_free_heap_size()MAC 地址esp_read_mac()、esp_base_mac_addr_set()、esp_iface_mac_addr_set()、esp_derive_local_mac()、esp_efuse_mac_get_custom()以及各芯片的派生规则表与本地/全局管理 MAC 机制版本信息esp_chip_info()、esp_get_idf_version()与编译期版本宏调试与应用版本栈回溯工具与PROJECT_VER的优先级链。对应 API 的完整参考可继续查阅 esp_system、esp_mac、esp_idf_version、esp_chip_info、esp_debug_helpers 与 esp_app_desc 头文件并通过 base_mac_address 示例 快速上手实践。【免费下载链接】esp-idfEspressif IoT Development Framework. Official development framework for Espressif SoCs.项目地址: https://gitcode.com/GitHub_Trending/es/esp-idf创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表