ESP-IDF学习笔记-错误处理
同STM32HAL库的各种错误状态码一样,ESP-IDF中也有不同的错误码以及相应的错误处理方法,这给出基本的使用。
首先放上官方文档
一,错误的分类
ESP32中主要有两类错误:
- 可恢复错误
可用错误状态码表示,使用 throw
关键字抛出的 C++ 异常。
- 不可恢复(严重)错误
断言失败:(使用 assert
宏或者其它类似方法,可参考 Assertions)或者直接调用 abort()
函数造成的错误
CPU 异常:访问受保护的内存区域、非法指令等
系统级检查:看门狗超时、缓存访问错误、堆栈溢出、堆栈粉碎、堆栈损坏等
二,错误码与错误消息
在ESP-IDF中,错误码的类型是esp_err_t
,本质是带符号整型。其中表示没有错误的定义是:ESP_OK
具体定义为0。
对于一个具体的错误,错误码常常以ESP_ERR_XXX
形式呈现,常见的错误码在esp_err.h
中已经定义好了,各个组件也可以自定义。
得到整型的错误码可以使用esp_err_to_name()
或者esp_err_to_name_r()
函数(esp_err.h
)将其转换为字符串(返回值是const char *
),这两个函数的区别主要在于当没有匹配的错误时,是否用 标准 POSIX 错误代码 进行解释。
三,常用宏
- ESP_ERROR_CHECK
该宏定义在esp_err.h
中。功能与assert
相似,但是会检测错误值并打印错误信息,最后调用abort()
。
通常错误信息如下:
1 | ESP_ERROR_CHECK failed: esp_err_t 0x107 (ESP_ERR_TIMEOUT) at 0x400d1fdf |
- ESP_ERROR_CHECK_WITHOUT_ABORT
该宏定义在esp_err.h
中。功能与ESP_ERROR_CHECK一样,但不会调用abort()
。
以下宏定义在esp_check.h
- ESP_RETURN_ON_ERROR
宏 ESP_RETURN_ON_ERROR 用于错误码检查, 如果错误码不等于 ESP_OK, 该宏会打印错误信息,并使原函数立刻返回。
- ESP_GOTO_ON_ERROR
宏 ESP_GOTO_ON_ERROR 用于错误码检查, 如果错误码不等于 ESP_OK, 该宏会打印错误信息,将局部变量 ret 赋值为该错误码, 并使原函数跳转至给定的 goto_tag.
- ESP_RETURN_ON_FALSE
宏 ESP_RETURN_ON_FALSE 用于条件检查, 如果给定条件不等于 true, 该宏会打印错误信息,并使原函数立刻返回,返回值为给定的 err_code.
- ESP_GOTO_ON_FALSE
宏 ESP_GOTO_ON_FALSE 用于条件检查, 如果给定条件不等于 true, 该宏会打印错误信息,将局部变量 ret 赋值为给定的 err_code, 并使原函数跳转至给定的 goto_tag.
ESP_RETURN_xx 和 ESP_GOTO_xx 宏不可以在中断服务程序里被调用。
使用例:
1 | static const char* TAG = "Test"; |
如果 Kconfig 中的 CONFIG_COMPILER_OPTIMIZATION_CHECKS_SILENT 选项被打开, CHECK 宏将不会打印错误信息,其他功能不变。
四,错误处理
根据错误码恢复
用变量储存错误码,在代码中判断错误码类型,根据类型不同尝试恢复。或者使用上面用到的CHECK宏。
转化为不可恢复错误
使用ESP_ERROR_CHECK
处理返回值。
1 | ESP_ERROR_CHECK(spi_bus_initialize(host, bus_config, dma_chan)); |
五,严重错误
以下情况为不可恢复的严重错误,程序会中断重启。
CPU 异常:非法指令,加载/存储时的内存对齐错误,加载/存储时的访问权限错误,双重异常。
系统级检查错误:
中断看门狗 超时
任务看门狗 超时(只有开启 CONFIG_ESP_TASK_WDT_PANIC 后才会触发严重错误)
高速缓存访问错误
内存保护故障
掉电检测事件
堆栈溢出
堆栈粉碎保护检查
堆完整性检查
未定义行为清理器 (UBSAN) 检查
使用 assert、configASSERT 等类似的宏断言失败。
官方文档给出了参考解决,这里先待补,等以后接触后继续。