为什么得到Debug异常原因:触发了堆栈金丝雀监视点(主)?

时间:2019-06-26 19:00:28

标签: esp32 esp-idf

我正在使用esp32-wroom-32esp-idf-v3.0编写程序。
我正在尝试添加日志,这些日志将保存在fatfs中。
经过一些日志后,我得到:

21:54:21.306 -> Debug exception reason: Stack canary watchpoint triggered (main) 
21:54:21.306 -> Register dump:
21:54:21.306 -> PC      : 0x40089827  PS      : 0x00060b36  A0      : 0x40082179  A1      : 0x3ffd3860  
21:54:21.340 -> A2      : 0x3ff40000  A3      : 0x00000033  A4      : 0x00000033  A5      : 0x00000000  
21:54:21.340 -> A6      : 0x00000024  A7      : 0xff000000  A8      : 0xe37fc000  A9      : 0x0000007e  
21:54:21.340 -> A10     : 0x00000000  A11     : 0xffffffff  A12     : 0x00000004  A13     : 0x00000001  
21:54:21.340 -> A14     : 0x00000005  A15     : 0x00000000  SAR     : 0x00000004  EXCCAUSE: 0x00000001  
21:54:21.340 -> EXCVADDR: 0x00000000  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xfffffff6  

为什么会发生这种情况?

1 个答案:

答案 0 :(得分:1)

FreeRTOS任务堆栈深度

这很可能是由于FreeRTOS任务中的堆栈溢出引起的。

增加堆栈深度

我要做的第一件事是增加FreeRTOS任务的堆栈深度。例如,如果您创建的任务堆栈大小为var socket = io.connect("localhost:3000"); socket.emit('privatechatroom'); socket.on('res', function(data){ console.log("response getting"); }); ,则该字节可能低至768个字节-不足以满足许多常见要求。

将堆栈深度增加多少?

回答这个问题并不容易,但是-在这种情况下-简单地增加它可能就足够了,直到不再有堆栈溢出为止。如果您担心不必要的浪费内存,请使用FreeRTOS includes a mechanism告诉您任务溢出堆栈有多接近。

缓冲区和金丝雀

canary只是缓冲区末尾的标记-会定期检查。如果将其值更改为默认值,则表示程序已尝试在缓冲区末尾之外进行写操作-即存在缓冲区溢出

通过更改配置中的两个选项(在configMINIMAL_STACK_SIZE-> Component Config下),在ESP IDF中启用了使用金丝雀检测堆栈溢出的功能:

  • “检查堆栈是否溢出”->“使用金丝雀字节”
  • “将调试监视点设置为堆栈溢出检查”->已启用

enter image description here

如果禁用第二个选项,则在堆栈溢出的情况下,您将得到Guru Meditation错误-FreeRTOS异常。

LoadProhibited和堆栈深度

请记住,ESP IDF中xTaskCreate()的版本与原始FreeRTOS的版本不同。在原始的FreeRTOS中,堆栈深度为specified in words。在ESP IDF中,它是specified in bytes非常重要区别!