【踩坑日记】ESP32触发定时器中断后无限重启

本文探讨了ESP32开发板在配置定时器并尝试在中断回调中进行串口输出时遇到的问题,核心在于理解ESP32中断函数的特性,以及如何避免因阻塞导致的看门狗超时。作者通过实例揭示了问题所在,并提供了使用标志位代替阻塞操作的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

问题描述

出现问题环境 

解决过程

解决方法

原创不易,点个赞或者点个关注激励笔者分享更多优质原创内容吧!

开源万岁!


问题描述

  • 配置ESP32定时器成功后(在配置函数中写串口提示代码,串口正常输出配置成功的提示)
Serial.println("start timer");
表明定时器配置成功

  • 但是在定时器触发中断调用中断函数时,ESP32重启
  • 总体表现为定时器中断触发时,ESP32重启
  • 串口输出信息如下:
21:4:34.366 -> Guru Meditation Error: Core  1 panic'ed (Interrupt wdt timeout on CPU1). 

21:4:34.366 -> 

21:4:34.366 -> Core  1 register dump:

21:4:34.366 -> PC      : 0x4008e3d0  PS      : 0x00060c35  A0      : 0x8008d36a  A1      : 0x3ffbed3c  

21:4:34.366 -> A2      : 0x3ffcbef0  A3      : 0x3ffb8890  A4      : 0x00000004  A5      : 0x00060c23  

21:4:34.398 -> A6      : 0x00060c23  A7      : 0x00000001  A8      : 0x3ffb8890  A9      : 0x00000018  

21:4:34.398 -> A10     : 0x3ffb8890  A11     : 0x00000018  A12     : 0x00000004  A13     : 0x00060c23  

21:4:34.398 -> A14     : 0x007bf1d8  A15     : 0x003fffff  SAR     : 0x00000006  EXCCAUSE: 0x00000006  

21:4:34.398 -> EXCVADDR: 0x00000000  LBEG    : 0x40089314  LEND    : 0x4008932a  LCOUNT  : 0xffffffff  

21:4:34.430 -> Core  1 was running in ISR context:

21:4:34.430 -> EPC1    : 0x400e1697  EPC2    : 0x00000000  EPC3    : 0x00000000  EPC4    : 0x00000000

21:4:34.430 -> 

21:4:34.430 -> 

21:4:34.430 -> Backtrace:0x4008e3cd:0x3ffbed3c |<-CORRUPTED
 
21:4:15.290 -> Core  0 register dump:

21:4:15.290 -> PC      : 0x4008e549  PS      : 0x00060435  A0      : 0x8008e06b  A1      : 0x3ffb3240  

21:4:15.290 -> A2      : 0x3ffbf1d8  A3      : 0xb33fffff  A4      : 0x0000abab  A5      : 0x00060423  

21:4:15.290 -> A6      : 0x00060423  A7      : 0x0000cdcd  A8      : 0x0000cdcd  A9      : 0xffffffff  

21:4:15.322 -> A10     : 0x3ffcc200  A11     : 0x00000010  A12     : 0x3ffc72b0  A13     : 0x64af30a5  

21:4:15.322 -> A14     : 0x007bf1d8  A15     : 0x003fffff  SAR     : 0x00000009  EXCCAUSE: 0x00000006  

21:4:15.322 -> EXCVADDR: 0x00000000  LBEG    : 0x4008937d  LEND    : 0x4008939f  LCOUNT  : 0x00000000  

21:4:15.322 -> 

21:4:15.322 -> 

21:4:15.322 -> Backtrace:0x4008e546:0x3ffb32400x4008e068:0x3ffb3280 0x4008c720:0x3ffb32a0 0x400fab66:0x3ffb32e0 0x400fae95:0x3ffb3300 0x400ecf07:0x3ffb3320 0x400ecf65:0x3ffb3340 0x400f1d9d:0x3ffb3360 0x400f22c5:0x3ffb3390 0x400fcb84:0x3ffb33e0 0x400fd432:0x3ffb3400 0x400ebcbf:0x3ffb3420 

21:4:15.354 -> 

21:4:15.354 -> 

21:4:15.354 -> 

21:4:15.354 -> 

21:4:15.354 -> ELF file SHA256: 0000000000000000

21:4:15.354 -> 

21:4:15.354 -> Rebooting...

21:4:15.354 -> ets Jun  8 2016 00:22:57

出现问题环境 

  • Arduino IDE
  • ESP32-WROOM-32

解决过程

  • 注意到串口输出的错误信息里有:
21:4:34.366 -> Guru Meditation Error: Core  1 panic'ed (Interrupt wdt timeout on CPU1). 
  • wdt表示看门狗,可知此时程序跑飞
  • 在另外一个测试程序中,于中断函数中串口输出一内容:
void IRAM_ATTR onTimer(){
  Serial.println(interruptCounter++);
    if (interruptCounter > 5)
    {
        interruptCounter = 1;
    }
}
  • 此时开发板有时可以打印出一些内容后才自动重启,有时候可以一直打印成功而不重启,可推断此时触发中断后有时程序跑飞而有时候正常
  • 了解到 println() 和 printf() 都是阻塞性函数,推测是由于中断阻塞而导致没有及时喂狗而导致重启

解决方法

  • 注意esp32-timer-hal.c中定时器和中断函数是不可被阻塞的,笔者由于习惯使用STM32的HAL库中的中断回调函数,误将其认为是回调函数从而在中断函数中阻塞了程序线程,导致程序跑飞
  • 在ESP32中断函数中使用标志位标志定时器触发,在 loop() 函数中检测标志位触发对应的定时器任务即可解决问题
  • 代码如下:
/*
 *ESP32 芯片包含两个定时器组,每组有两个通用定时器。
 *它们都是基于 16 位预分频器和 64 位自动重载功能的向上/向下计数器的 64 位通用定时器。
 */
 
/* 创建硬件定时器 */
hw_timer_t * timer = NULL;

/* 创建定时器中断触发标志 */
int FLAG_timIT = 0;

// 中断服务函数,为使编译器将代码分配到IRAM内,中断处理程序应该具有 IRAM_ATTR 属性
void IRAM_ATTR Callback_TimerIT()
{
  FLAG_timIT = 1;    //定时器中断触发标志置1,中断函数中不能阻塞
}

void Timer_Init()
{
  /*  1/(80MHZ/80) = 1us  */
  timer = timerBegin(1, 80, true);  //定时器0,80分频,向上计数
 
  /* 将Callback_TimerIT函数附加到我们的计时器 */
  timerAttachInterrupt(timer, &Callback_TimerIT, true); //第三个参数(edge):如果为true,则报警将产生边缘类型中断
 
  /* *设置闹钟每5秒调用Callback_TimerIT函数1 tick为1us   => 1秒为1000000us * / 
  / *重复闹钟(第三个参数)*/
  timerAlarmWrite(timer, 5000000, true);
 
  timerAlarmEnable(timer);  //中断使能
  Serial.println("start timer");  
}

void loop() {

  if(tim){    //检测定时器中断触发标志
    FLAG_timIT = 0;    //清除定时器中断触发标志
    //...此处写定时器中断触发后要执行的任务
  }
}

原创不易,点个赞或者点个关注激励笔者分享更多优质原创内容吧!

开源万岁!

Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1).这个错误的原因是中断看门狗在CPU1上超时。中断看门狗是一种用于监视程序运行情况的机制,当程序在规定的时间内没有完成任务时,中断看门狗会触发重启系统。在这种情况下,可能是由于中断函数中的阻塞操作导致了中断看门狗的超时。根据错误信息显示,在中断函数`onTimer()`中使用了阻塞性函数`Serial.println()`,推测是由于中断阻塞导致没有及时喂狗而触发重启。此外,错误信息中还提到了调试异常的原因是堆栈金丝雀(watchpoint)触发了,这可能是由于任务(task_name)的堆栈溢出导致的。为了解决这个问题,我们可以考虑以下解决方案: 1. 在中断函数中尽量避免使用阻塞性函数,特别是在低优先级的中断服务程序中 2. 确保中断服务程序尽快完成任务,以避免中断看门狗的超时 3. 检查任务的堆栈使用情况,确保没有堆栈溢出的问题 4. 调整中断看门狗的超时时间,使其能够适应程序的运行情况 5. 可以考虑使用RTOS的任务管理机制,以提高系统的稳定性和可靠性 通过以上的解决方案,我们可以尝试修复Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1)这个错误。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [[esp32] Guru Meditation 错误解析及解决方案](https://blog.csdn.net/weixin_42942530/article/details/103975237)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [【日记ESP32触发定时器断后无限重启](https://blog.csdn.net/Beihai_Van/article/details/125793806)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

__Witheart__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值