Так что я использую CMSIS-RTOS
механика очереди почты с Keil uVision 5.0.5
в STM32F427
микроконтроллер работает на 180MHz
, Время от времени освобождение ранее выделенного элемента почтового ящика с помощью osMailFree () приводило к возвращению некоторого адреса вместо osStatus-введите значение как osOK или же osErrorValue или что там сказано в документах.
Этот адрес указывает на os_mailQ_p _ ## blahlbah элемент структуры обслуживания, выделенный с osMailQDef. Это также означает, что он указывает прямо за конец фактического буфера данных, выделенного с тем же osMailQDef макро.
Все мои структуры расположены статически; размеры стеков для потоков (OS_STKSIZE 600) также выглядят достаточно симпатично — во всяком случае, удвоение и утроение их не дало никакого эффекта.
Меня не будет беспокоить, если это не тот факт, что рано или поздно моя программа попадает в ситуацию, когда один поток не может выделить почтовый элемент (osMailAlloc () возвращает 0) в то время как другой, ожидающий поток, постоянно принимает osEventTimeout. Похоже, что все блоки памяти используются — но я честно освобождаю их после каждого использования (в оболочке деструктора объекта, чтобы быть уверенным, что он действительно освобожден).
Что бы это могло значить и куда копать?
Ну, я не понял, что было настоящей глубокой причиной описанного поведения. Но:
1) Сначала был найден обходной путь для этого: достаточно позвонить osMailFree () еще раз сразу после неудачного звонка. Затем он ожидаемо возвращается osOK и (как показали мои долгосрочные тесты) ресурс времени высвобождается по-настоящему.
2) Эффект полностью исчез после того, как я изменил процедуру установки приоритета IRQ внутри fatfs_sd_sdio.c файл, который является частью FatFS
Библиотека, которую я использую. В частности это были следующие строки кода:
NVIC_PriorityGroupConfig (NVIC_PriorityGroup_1);
NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init (&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = SD_SDIO_DMA_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
NVIC_Init (&NVIC_InitStructure);
заменены на следующие:
NVIC_EnableIRQ(SDIO_IRQn);
NVIC_SetPriority (SDIO_IRQn, 0x0e);
NVIC_EnableIRQ(SD_SDIO_DMA_IRQn);
NVIC_SetPriority (SD_SDIO_DMA_IRQn, 0x0e);
где 0x0E это RTX
Уровень приоритета SysTick минус 1. Примечательно, что лечение не было завершено, пока я не избавился от NVIC_PriorityGroupConfig()
звонок, который поначалу казался не значимым для меня.
Других решений пока нет …