我正在为STM32F746NG开发一个非常复杂的软件。我正在使用一个改装的发现板。移除ST-Link并通过JTAG替换为Segger J-Link。 Rocktech Display被更大的一个取代。我正在使用gcc6.2
系统运行良好。除了有一些系统冻结。刷新显示器时会随机出现。
如果冻结发生,调试器无法暂停cpu并将调试器连接到cpu是不可能的。由硬件定时器触发的LED触发停止。并且在故障处理程序中通过UART发送错误消息。看起来CPU就停止了,不再做任何事了。
有谁知道可能导致这种情况的原因?
我无法提供整个代码,也许是一些代码段。
编辑: 看起来硬件没问题。新的主板具有相同的800 * 480显示屏,但再次使用蹩脚的板载ST-Link会再次导致问题。
更多信息:
我使用的是FreeRTOS v9.0.0,大约有16个任务在运行。
Tickrate的相对较高值为10 kHz,但将其降至1 kHz并未解决问题。
Framebuffer位于发现板2的外部sdram中,前景为Framebuffers,背景为1 Framebuffer 最后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()进行线程保存;
系统冻结总是在通过函数void refreshDisplay()重绘Framebuffer(无关紧要)时发生;
我发现了问题可能性的三种不同行为。
如果我调用vTaskSuspendAll();在refreshDisplay和xTaskResumeAll()的条目上;退出问题的可能性很小。它不会发生几个小时。
如果我停用所有不可屏蔽的中断,即除了复位和nmi之外的所有中断(但不应该调用它们)。在这种情况下,我无法观察到这个问题。
如果我使用可配置的优先级停用所有中断,即除了reset,nmi和HardFaultHandler之外的所有中断。那么这个问题很有可能发生。它发生在一些会议纪要之后。
所有其他配置的行为与最后一种情况相同。