【嵌入式】ESP32几个反复重启的bug记录

最近在使用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 -error
  • ESP_LOGW -wornning
  • ESP_LOGI -information
  • ESP_LOGD -debug
  • ESP_LOGV -verbose

4. 指针导致的内存错误

在程序中需要用到结构体指针、函数指针等稍微复杂一些的指针操作时,注意指向对象前先给对象分配内存空间,不然找不到地址就会报错重启。

5. 参数异常

某些API参数设置没有保护或异常判断,输入参数溢出可能会导致错误。例如在设置定时器alarm周期时需要根据命令内容来设置,这时需要手动检测这个周期>=0,否则会导致重启。

  • 3
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值