在esp32 ISR中使用首选项



当中断被触发时,我试图使用首选项库在esp32中存储值。

Guru Meditation Error: Core  1 panic'ed (Interrupt wdt timeout on CPU1)
Core 1 register dump:
PC      : 0x4008867a  PS      : 0x00060034  A0      : 0x80087a9b  A1      : 0x3ffbe860  
A2      : 0x3ffb7e0c  A3      : 0x3ffb8074  A4      : 0x00000001  A5      : 0x00000001  
A6      : 0x00060023  A7      : 0x00000000  A8      : 0x3ffb8074  A9      : 0x3ffb8074  
A10     : 0x00000001  A11     : 0x00000001  A12     : 0x00000020  A13     : 0x0000ff00  
A14     : 0x00ff0000  A15     : 0xff000000  SAR     : 0x0000001e  EXCCAUSE: 0x00000006  
EXCVADDR: 0x00000000  LBEG    : 0x4000c2e0  LEND    : 0x4000c2f6  LCOUNT  : 0xffffffff  
Core 1 was running in ISR context:
EPC1    : 0x40085d07  EPC2    : 0x00000000  EPC3    : 0x00000000  EPC4    : 0x4008867a
ELF file SHA256: 0000000000000000
Backtrace: 0x4008867a:0x3ffbe860 0x40087a98:0x3ffbe880 0x400860cf:0x3ffbe8a0 0x400e2f42:0x3ffbe8e0 0x400e300a:0x3ffbe900 0x40083cad:0x3ffbe920 0x400840c4:0x3ffbe940 0x400e7b01:0x3ffbe990 0x400e5f66:0x3ffbe9b0 0x400e629e:0x3ffbe9d0 0x400e5a92:0x3ffbea50 0x400e4a77:0x3ffbeac0 0x400e4e55:0x3ffbeb10 0x400d1fa4:0x3ffbeb30 0x40080ecd:0x3ffbeb50 0x40080f19:0x3ffbeb70 0x40083969:0x3ffbeb90 0x40081b46:0x3ffb1e00 0x400826ef:0x3ffb1e20 0x40081183:0x3ffb1e40 0x400811a7:0x3ffb1e60 0x400d1cb7:0x3ffb1e80 0x400d1c85:0x3ffb1ea0 0x400d1c30:0x3ffb1ec0 0x400ebb35:0x3ffb1ee0 0x400ebbfe:0x3ffb1f00 0x400d1795:0x3ffb1f30 0x400d18da:0x3ffb1f70 0x400d1b47:0x3ffb1f90 0x400d33e9:0x3ffb1fb0 0x40086295:0x3ffb1fd0
Core 0 register dump:
PC      : 0x40086729  PS      : 0x00060034  A0      : 0x80086bd6  A1      : 0x3ffbc020  
A2      : 0x3ffbdf74  A3      : 0xb33fffff  A4      : 0x00060023  A5      : 0x003fffff  
A6      : 0x00060021  A7      : 0x00000000  A8      : 0x0000abab  A9      : 0x0000cdcd  
A10     : 0x0000abab  A11     : 0x00060023  A12     : 0x00060021  A13     : 0x3ffbc0d0  
A14     : 0x00000003  A15     : 0x00060b23  SAR     : 0x00000013  EXCCAUSE: 0x00000006  
EXCVADDR: 0x00000000  LBEG    : 0x00000000  LEND    : 0x00000000  LCOUNT  : 0x00000000  
ELF file SHA256: 0000000000000000
Backtrace: 0x40086729:0x3ffbc020 0x40086bd3:0x3ffbc050 0x40088524:0x3ffbc070 0x400884da:0x3ffbc090 0x400893fb:0x00000000
Rebooting...

但是当中断被触发时,我得到这个错误。请帮我解决这个

很难确定,因为您没有共享任何代码,但是…不应该从ISR 更新Preferences。事实上,除非你真的非常清楚自己在做什么,否则你应该尽可能少地在ISR中操作。

中断不可预测地发生…它们实际上会中断当前在CPU上执行的任何代码。这意味着代码当前正在更改的任何数据结构都可能处于不一致状态。从使用这些数据结构的中断处理程序调用函数将导致数据损坏并可能导致崩溃。

除非你写了你调用的代码,否则你不知道它调用的是什么。你可能会说"没关系,我没有使用isr之外的偏好设置"但是你不知道Preferences还调用了哪些函数。

你可能会很幸运,有时可能会奏效……它也可能只是随机崩溃。

再次强调,除非你真的知道自己在做什么,否则在ISR中很少有函数是可以安全调用的。这些通常是被明确指定为安全的FreeRTOS函数。

中断处理程序也会阻止CPU做它需要做的其他事情,所以(除非你真的真的知道你在做什么)你应该尽量减少你花在处理程序上的时间。

对于大多数没有编写中断处理程序经验的人(特别是使用Arduino核心编码的人),最好的方法是尽可能减少工作并设置loop()检查的标志,并在loop()中完成工作。

volatile关键字声明标志是很重要的,这样编译器就知道它的值可以被意外地改变。

IRAM_ATTR声明中断处理程序也很重要,它告诉系统将其代码加载到指令RAM中,以便在需要时可用。否则,如果中断处理程序的代码尚未从闪存中取出,程序将崩溃。

例如:

volatile boolean interrupt_happened = false;
IRAM_ATTR void interrupt_handler() {
interrupt_happened = true;
}
void loop() {
if(interrupt_happened) {
do_some_work();
interrupt_happened = false;
}
}

最新更新