10

我正在编写一个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  

为什么会发生在 main 上?

4

1 回答 1

17

FreeRTOS 任务堆栈深度

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

增加堆栈深度

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

堆栈深度增加多少?

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

缓冲区和金丝雀

金丝雀只是缓冲区末尾的一个标记 - 定期检查。如果它从其默认值更改,则意味着程序试图写入超出缓冲区的末尾 - 即存在缓冲区溢出

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

  • 'Check for stack overflow' -> 'using canary bytes'
  • 'Set a debug watchpoint as a stack overflow check' -> enabled

enter image description here

If you disable the second option, you will instead get a Guru Meditation error - a LoadProhibited exception - in the case of a stack overflow.

xTaskCreate() and stack depth

Bear in mind that the version of xTaskCreate() in the ESP IDF differs from that in the original FreeRTOS. In the original FreeRTOS, the stack depth is specified in words. In the ESP IDF, it's specified in bytes. A very important distinction!

于 2019-06-27T11:35:16.247 回答