Случайная система 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();
Я наблюдал три различных поведения для вероятности проблемы.
Если я позвоню vTaskSuspendAll(); при входе refreshDisplay и xTaskResumeAll(); на выходе проблема очень маловероятна. Это не происходит в течение нескольких часов.
Если я деактивирую все немаскируемые прерывания, т.е. все, кроме reset и nmi (но они никогда не должны вызываться). Я никогда не мог наблюдать проблему в этом случае.
Если я деактивирую все прерывания с настраиваемым приоритетом, т.е. все, кроме сброса, nmi и HardFaultHandler. Тогда проблема очень вероятна. Это происходит через несколько минут.
Все остальные конфигурации ведут себя как в последнем случае.