最近在使用ESP32开发一些无线应用,在经历重重困难能够顺利编译-下载工程后,尝试把STM32中的程序移植到ESP32中,但由于对FreeRTOS系统了解不够深入,所以遇到了很多导致板子一直Rebooting的bug,在此记录一下。
1. 消息队列溢出
在创建一个消息队列时需要给出队列长度,同时也需要相应的读取队列信息。如果入队过多没读完就满了,队列溢出则会导致系统重启。
所以在使用消息队列时注意消息写入与读取的对应关系。
2. 中断程序卡死 看门狗异常
在程序中使用到了一个timer中断,刚写完发现一直重启,报错的原因是看门狗溢出,也就是高优先级线程卡死太久了。后来debug发现是卡死在timer中断内了。卡死的具体原因见我之前写的一个小总结:STM32-中断卡死 - CHER-YOUNG BLOG
在ESP32-FreeRTOS系统中封装了太多层,直接去改中断标志位寄存器的值没有开放API,不过可以随意调用一个更改中断位的函数完成。
这点后来查阅官方文档,也有相应的说明:
定时器启动后,可动态产生特定事件(如“警报事件”)。如需在事件发生时调用某些函数,请通过 gptimer_register_event_callbacks() 将函数挂载到中断服务例程 (ISR)。gptimer_event_callbacks_t 中列出了所有支持的事件回调函数:
gptimer_event_callbacks_t::on_alarm 设置警报事件的回调函数。由于此函数在 ISR 上下文中调用,必须确保该函数不会试图阻塞(例如,确保仅从函数内调用具有
ISR
后缀的 FreeRTOS API)。函数原型在 gptimer_alarm_cb_t 中有所声明。
例如 xQueueSendFromISR、timer_group_get_counter_value_in_isr
3. printf重入
由于之前写裸机程序习惯了,没想到有一天会因为printf卡死。
具体的场景是:中断A和B同时调用了printf,然后系统就很重启。printf不能在未返回的时候再次被调用。所以在中断中尽量不要用printf发送调试信息,应该改用ESP_LOG,日志输出。
详情见:Logging library
大致就是以下几个API:
ESP_LOGE
-errorESP_LOGW
-wornningESP_LOGI
-informationESP_LOGD
-debugESP_LOGV
-verbose
4. 指针导致的内存错误
在程序中需要用到结构体指针、函数指针等稍微复杂一些的指针操作时,注意指向对象前先给对象分配内存空间,不然找不到地址就会报错重启。文章来源:https://www.toymoban.com/news/detail-402555.html
5. 参数异常
某些API参数设置没有保护或异常判断,输入参数溢出可能会导致错误。例如在设置定时器alarm周期时需要根据命令内容来设置,这时需要手动检测这个周期>=0,否则会导致重启。文章来源地址https://www.toymoban.com/news/detail-402555.html
到了这里,关于【嵌入式】ESP32几个反复重启的bug记录的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!