问题描述
环境有问题
解决过程
解决方法
原创并不容易。点赞或关注,鼓励作者分享更多高质量的原创内容!
开源万岁!
问题描述
- 配置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; //清除定时器中断触发标志
//...此处写定时器中断触发后要执行的任务
}
}