为什么我会得到 Debug 异常原因:Stack canary watchpoint triggered (main)?

use*_*539 7 esp32 esp-idf

我正在编写一个esp32-wroom-32使用esp-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  
Run Code Online (Sandbox Code Playgroud)

为什么会发生在 main 上?

Dav*_*ins 13

FreeRTOS 任务堆栈深度

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

增加堆栈深度

我要做的第一件事是增加FreeRTOS 任务的堆栈深度。例如,如果您创建的任务的堆栈大小为configMINIMAL_STACK_SIZE,这可能低至 768 字节 - 这不足以满足许多常见要求。

堆栈深度增加多少?

回答这个问题并不容易,但是 - 在这种情况下 - 简单地增加它可能就足够了,直到你不再有堆栈溢出。如果您担心不会无谓地浪费内存,FreeRTOS包含一种机制,可让您知道任务接近溢出堆栈的程度。

缓冲区和金丝雀

金丝雀只是在一个缓冲区的末尾的标记-其被周期性地检查。如果它从它的默认值改变,这意味着程序试图写超出缓冲区的末尾——即出现了缓冲区溢出

通过更改配置中的两个选项(在Component Config->FreeRTOS部分下),可以在 ESP IDF 中启用使用 Canary 检测堆栈溢出:

  • “检查堆栈溢出”->“使用金丝雀字节”
  • “将调试观察点设置为堆栈溢出检查”-> 启用

在此处输入图片说明

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

xTaskCreate() 和堆栈深度

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