Добрый день!
Процессор stm32f407vg. На нём запущена FREERTOS. stm общается с SDcard по SDIO с прерываниями от DMA. Без ОС - инициализация, запись, чтение работают.
Вопрос по поводу приоритетов прерываний.
Обработчики прерываний имеют вид:
CODE
void SDIO_IRQHandler(void)
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
SD_ProcessIRQSrc();
xSemaphoreGiveFromISR( c_xSemaphore_SDIO_IRQHandler, &xHigherPriorityTaskWoken );
if( xHigherPriorityTaskWoken != pdFALSE ){
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
}
void SD_SDIO_DMA_IRQHANDLER(void)
{
portBASE_TYPE xHigherPriorityTaskWoken = pdFALSE;
SD_ProcessDMAIRQ();
xSemaphoreGiveFromISR( c_xSemaphore_SD_SDIO_DMA_IRQHANDLER, &xHigherPriorityTaskWoken );
if( xHigherPriorityTaskWoken != pdFALSE )
{
portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
}
}
В функции SD_ReadMultiBlocksFIXED
Код
....
xSemaphoreGive( c_xSemaphore_SDIO_IRQHandler);
xSemaphoreGive( c_xSemaphore_SD_SDIO_DMA_IRQHANDLER);
SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | SDIO_IT_RXOVERR | SDIO_IT_STBITERR, ENABLE);
SDIO_DMACmd(ENABLE);
SD_LowLevel_DMA_RxConfig((uint32_t *)readbuff, (NumberOfBlocks * BlockSize));
while (xSemaphoreTake( c_xSemaphore_SDIO_IRQHandler, cardBLOCK_TIME_WAITING)==pdFALSE);
while (xSemaphoreTake( c_xSemaphore_SD_SDIO_DMA_IRQHANDLER, cardBLOCK_TIME_WAITING)==pdFALSE);
....
и в функции SD_WriteMultiBlocksFIXED
Код
...
SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | SDIO_IT_RXOVERR | SDIO_IT_STBITERR, ENABLE);
SDIO_DMACmd(ENABLE);
SD_LowLevel_DMA_TxConfig((uint32_t *)writebuff, (NumberOfBlocks * BlockSize));
while (xSemaphoreTake( c_xSemaphore_SD_SDIO_DMA_IRQHANDLER, cardBLOCK_TIME_WAITING)==pdFALSE);
...
Настройка прерываний:
CODE
void Init_NVIC(void)
{
NVIC_InitTypeDef NVIC_InitStructure;
NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);
NVIC_InitStructure.NVIC_IRQChannel = SDIO_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 12;
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = SD_SDIO_DMA_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 13;
NVIC_Init(&NVIC_InitStructure);
NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 14;
NVIC_Init(&NVIC_InitStructure);
}
Если NVIC_IRQChannelPreemptionPriority для SDIO и SDIO_DMA поставить 12 и 13, то программа зацикливается в ожидании
Код
while ((DMAEndOfTransfer == 0x00) && (TransferEnd == 0) && (TransferError == SD_OK) && (timeout > 0))
{
timeout--;
}
в функции SD_WaitReadOperation().
Задача, для записи данных на карту
CODE
void vTaskSendSD(void *pvParameters) {
volatile UINT BytesWritten;
portBASE_TYPE xStatus;
uint8_t ps;
for (;;) {
xQueueReceive(xQueue, &ps, portMAX_DELAY);
if(cSDclose < 500){//250
res = f_lseek(&fil, fil.fsize);
if(ps)
res = f_write(&fil, buf_2, 4096, &BytesWritten);
else
res = f_write(&fil, buf_1, 4096, &BytesWritten);
f_sync(&fil);
cSDclose++;
}else{
f_close(&fil);
f_mount(0, NULL);
}
}
}
Каждый из массивов buf заполняется в течении 2.7 сек.
Если поставить приоритеты NVIC_IRQChannelPreemptionPriority для SDIO и SDIO_DMA поставить 4 и 5 и убрать семафоры из обработчиков прерываний - проект работает, но нестабильно. Данные на SDcard могут записываться без сбоев длительное время, а может записаться 4 кБайта и
всё.
В чём может быть проблема, кто сталкивался?
Спасибо.
Сообщение отредактировал IgorKossak - Aug 18 2016, 13:12
Причина редактирования: [codebox] для длинного кода, [code] - для короткого!