Я разрабатываю довольно сложное программное обеспечение для 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 кГц не решило проблему.
Framebuffer находится во внешнем sdram от платы обнаружения 2 Framebuffers для переднего плана и 1 Framebuffer для фона
последние 2 МБ используются для кучи.
caddr_t _sbrk (int incr)
{
extern char _end; / * Определяется компоновщиком * /
статический символ * 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 ();
Замораживание системы всегда происходит при перерисовке Framebuffer (не имеет значения, какой именно) через функцию void refreshDisplay ();
Я наблюдал три различных поведения для вероятности проблемы.
Если я позвоню vTaskSuspendAll (); при входе refreshDisplay и xTaskResumeAll (); на выходе проблема очень маловероятна. Это не происходит в течение нескольких часов.
Если я деактивирую все немаскируемые прерывания, то есть все, кроме reset и nmi (но они никогда не должны вызываться). Я никогда не мог наблюдать проблему в этом случае.
Если я деактивирую все прерывания с настраиваемым приоритетом, то есть все, кроме сброса, nmi и HardFaultHandler. Тогда проблема очень вероятна. Это происходит через несколько минут.
Все остальные конфигурации ведут себя как в последнем случае.
Задача ещё не решена.
Других решений пока нет …