Случайная система Cortex M7 зависает отключает отладчик

Я разрабатываю довольно сложное программное обеспечение для STM32F746NG. Я использую модифицированную плату Discovery. ST-Link удаляется и заменяется на Segger J-Link через JTAG. Дисплей Rocktech был заменен большим. И я использую gcc6.2

Система работает довольно хорошо. За исключением некоторых зависаний системы. Появляется случайно при обновлении дисплея.

Если происходит зависание, отладчик не может остановить процессор, и подключение отладчика к процессору невозможно. Светодиод срабатывает, когда аппаратный таймер останавливается. И отправка сообщений об ошибках через UART в Fault Handler не происходит. Кажется, что процессор просто останавливается и больше ничего не делает.

У кого-нибудь есть идеи, что может вызвать это?

Я не могу дать весь код, может быть, некоторые фрагменты.

редактировать: кажется, что оборудование в порядке. Новая плата с тем же дисплеем 800*480, но опять же с дрянной платой ST-Link снова вызывает проблему.

Еще немного информации:

  • Я использую FreeRTOS v9.0.0, там работает около 16 задач.

  • Tickrate имеет относительную высоту 10 кГц, но снижение до 1 кГц не решило проблему.

  • Кадровый буфер находится во внешнем sdram с платы обнаружения. 2 кадровых буфера для переднего плана и 1 кадровый буфер для фона последние 2 МБ используются для кучи.

    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 реализованы, удаляют весь код из них, но не решают проблему.

Замораживание системы всегда происходит при перерисовке Framebuffer (не имеет значения, какой именно) через функцию void refreshDisplay();

Я наблюдал три различных поведения для вероятности проблемы.

  1. Если я позвоню vTaskSuspendAll(); при входе refreshDisplay и xTaskResumeAll(); на выходе проблема очень маловероятна. Это не происходит в течение нескольких часов.

  2. Если я деактивирую все немаскируемые прерывания, т.е. все, кроме reset и nmi (но они никогда не должны вызываться). Я никогда не мог наблюдать проблему в этом случае.

  3. Если я деактивирую все прерывания с настраиваемым приоритетом, т.е. все, кроме сброса, nmi и HardFaultHandler. Тогда проблема очень вероятна. Это происходит через несколько минут.

Все остальные конфигурации ведут себя как в последнем случае.

0 ответов

Другие вопросы по тегам