Есть проект сервисного устройства, которое ведет логи и считывает настройки через SD карточку.
Для доступа к логам и настройкам поднят FTP сервер. В общем-то все работает. Но есть один баг, который, хотя и не мешает, но не дает спать спокойно. Проблема возникает при попытке закачать на устройство файл размерами выше нескольких килобайт. Всякие файлы настроек меньше и проходят, а скачать с устройства можно файл любого размера. Но, все равно, мне не нравится, что в ОС осталась такая проблема. Проблема возникает если первые блоки данных FTP сервер еще пишет на SD, а пришло несколько новых пакетов. Тогда портится связанный список и зависание идет в функции vListInsert
Причем над этим местом есть даже комментарии для таких как я:
Код
/* *** NOTE ***********************************************************
If you find your application is crashing here then likely causes are
listed below. In addition see http://www.freertos.org/FAQHelp.html for
more tips, and ensure configASSERT() is defined!
http://www.freertos.org/a00110.html#configASSERT
1) Stack overflow -
see http://www.freertos.org/Stacks-and-stack-overflow-checking.html
2) Incorrect interrupt priority assignment, especially on Cortex-M
parts where numerically high priority values denote low actual
interrupt priorities, which can seem counter intuitive. See
http://www.freertos.org/RTOS-Cortex-M3-M4.html and the definition
of configMAX_SYSCALL_INTERRUPT_PRIORITY on
http://www.freertos.org/a00110.html
3) Calling an API function from within a critical section or when
the scheduler is suspended, or calling an API function that does
not end in "FromISR" from an interrupt.
4) Using a queue or semaphore before it has been initialised or
before the scheduler has been started (are interrupts firing
before vTaskStartScheduler() has been called?).
**********************************************************************/
1. Переполнения стека нет. Стоит и его контроль и давал значительно больше, его хватает с запасом.
2. Раздача приоритетов прерываниям кажется наиболее вероятной причиной. Однако сверялся с разными похожими проектами, примерами от ST и демо проектами FreeRTOS. К тому же попробовал разные варианты приоритетов Eternet и SDIO - больше, меньше, одинаковые - результат одинаковый.
3. Для контроля, ввел дополнительные assert в код, вроде все вызовы делаются в соответствии с правилами. Например такой configASSERT( (uxCriticalNesting || uxSchedulerSuspended || __get_BASEPRI() ) ); для контроля, что в функцию попал внутри критической секции или при остановленном шедулере или при закрытом приоритете прерывания.
4. Гарантированно не причина.
Менял исходный код LwIP версий от 1.1.0 до 1.4.0 и RfeeRTOS версий 6.1, 7.1, 7.2 и 8.1 - результат одинаковый. Код ftp сервера по выполнению закачки прост:
Код
for(;;)
{
err = netconn_recv(sess->dconn, &nbuff);
len = ( nbuff != NULL && nbuff->p != NULL ) ? netbuf_len( nbuff ) : 0;
if ( !len ) break;
if ( err == ERR_TIMEOUT )
{
debug("[storeFile] timeout");
break;
}
if ( err != ERR_OK )
{
debug("[storeFile] data error [%d]", err);
if ( ERR_IS_FATAL(err) ) break; // connection closed
vTaskDelay(500);
continue;
}
buff = mem_malloc( len );
if ( buff == NULL )
{
debug("[storeFile] error linear buff allocation");
break;
}
netbuf_copy( nbuff, (void *)buff, len );
netbuf_delete( nbuff );
if ( f_write(fp, buff, len, &wlen) || len != (uint16_t)wlen )
{
debug("[storeFile] write error");
mem_free( buff );
break;
}
mem_free( buff );
}
f_close(fp);
mem_free( fp );
Пните мою мысль что и где еще проверить.