我正在为 STM32F746NG 开发一个非常复杂的软件。我正在使用经过改装的探索板。ST-Link 被移除并被一个通过 JTAG 的 Segger J-Link 取代。Rocktech 显示器被更大的显示器取代。我正在使用 gcc6.2
该系统运行良好。除了有一些系统冻结。它在刷新显示时随机出现。
如果发生冻结,调试器将无法停止 cpu,并且无法将调试器连接到 cpu。由硬件定时器触发的 LED 切换停止。并且在故障处理程序中通过 UART 发送错误消息不会发生。似乎CPU只是停止并且不再做任何事情。
有谁知道可能导致这种情况的原因?
我不能给出整个代码,也许是一些片段。
编辑:看起来硬件还可以。具有相同 800*480 显示器的新板,但再次带有糟糕的板载 ST-Link 再次导致问题。
更多信息:
我使用的是 FreeRTOS v9.0.0,大约有 16 个任务正在运行。
Tickrate 相对高 10 kHz,但将其降低到 1 kHz 并不能解决问题。
帧缓冲区位于发现板的外部 sdram 中 2 个用于前景的帧缓冲区和 1 个用于背景的帧缓冲区,最后 2 MB 用于堆。
caddr_t _sbrk(int incr) { extern char _end; /* 由链接器定义 */ static char *heap_end=0;
char *prev_heap_end; if (heap_end == 0) { heap_end = &_end; } prev_heap_end = heap_end; if((uint32_t)heap_end <= _heap1_end) { if ((uint32_t)heap_end + incr > _heap1_end) { heap_end = &_endFrameBuffer; #ifdef DEBUGMODE sendErrToUart("Heap1 is Full: continue at"); char buff[12]; sprintf(buff,"%.8x",&_endFrameBuffer); sendErrToUart(buff); #endif } } else { if ((uint32_t)heap_end + incr > _RAM2_end) { #ifdef DEBUGMODE sendErrToUart("Heap is Full: exit"); #endif abort (); } } heap_end += incr; return (caddr_t) prev_heap_end;
}
malloc 是通过 vTaskSuspendAll() 进行线程保存;
- 已实施 HardFault、NMI、BusFault、MemFault 和 UsageFault 处理程序从其中删除所有代码并不能解决问题
通过函数 void refreshDisplay(); 重绘帧缓冲区(不管是哪一个)时,系统总是会冻结。
我观察了三种不同的行为来判断问题的可能性。
如果我调用 vTaskSuspendAll(); 在 refreshDisplay 和 xTaskResumeAll() 输入时;在退出时,这个问题不太可能发生。它不会发生几个小时。
如果我停用所有不可屏蔽的中断,即除了重置和 nmi 之外的所有中断(但它们永远不应该被调用)。在这种情况下,我无法观察到这个问题。
如果我停用所有具有可配置优先级的中断,即除复位之外的所有中断,nmi 和 HardFaultHandler。那么这个问题很有可能。它发生在几分钟后。
所有其他配置的行为都与最后一种情况类似。