0

我正在为 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(); 重绘帧缓冲区(不管是哪一个)时,系统总是会冻结。

我观察了三种不同的行为来判断问题的可能性。

  1. 如果我调用 vTaskSuspendAll(); 在 refreshDisplay 和 xTaskResumeAll() 输入时;在退出时,这个问题不太可能发生。它不会发生几个小时。

  2. 如果我停用所有不可屏蔽的中断,即除了重置和 nmi 之外的所有中断(但它们永远不应该被调用)。在这种情况下,我无法观察到这个问题。

  3. 如果我停用所有具有可配置优先级的中断,即除复位之外的所有中断,nmi 和 HardFaultHandler。那么这个问题很有可能。它发生在几分钟后。

所有其他配置的行为都与最后一种情况类似。

4

0 回答 0