STM32CbueMX+FatFS+SD+FreeRTOS DMA 超时bug
RTOS负载比较重的时候,SD卡操作容易卡在static uint32_t SDMMC_GetCmdResp1(SDIO_TypeDef *SDIOx, uint8_t SD_CMD, uint32_t Timeout)
{
uint32_t response_r1;
/* 8 is the number of required instructions cycles for the below loop statement.
The Timeout is expressed in ms */
register uint32_t count = Timeout * (SystemCoreClock / 8U /1000U);
do
{
if (count-- == 0U)
{
<font color="#ff0000">return SDMMC_ERROR_TIMEOUT;</font>
}
}while(!__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT));
-----
}因为SDIO_FLAG_CMDREND 标志在SD_DMAReceiveCplt中错误的清掉了,修改HAL驱动
/**
* @briefDMA SD receive process complete callback
* @paramhdma DMA handle
* @retval None
*/
static void SD_DMAReceiveCplt(DMA_HandleTypeDef *hdma)
{
SD_HandleTypeDef* hsd = (SD_HandleTypeDef* )(hdma->Parent);
uint32_t errorstate = HAL_SD_ERROR_NONE;
/* Send stop command in multiblock write */
if(hsd->Context == (SD_CONTEXT_READ_MULTIPLE_BLOCK | SD_CONTEXT_DMA))
{
errorstate = SDMMC_CmdStopTransfer(hsd->Instance);
if(errorstate != HAL_SD_ERROR_NONE)
{
hsd->ErrorCode |= errorstate;
#if (USE_HAL_SD_REGISTER_CALLBACKS == 1)
hsd->ErrorCallback(hsd);
#else
HAL_SD_ErrorCallback(hsd);
#endif
}
}
/* Disable the DMA transfer for transmit request by setting the DMAEN bit
in the SD DCTRL register */
hsd->Instance->DCTRL &= (uint32_t)~((uint32_t)SDIO_DCTRL_DMAEN);
/* Check current state of Command Register and don't clear those flags */
if (hsd->Context == (SD_CONTEXT_READ_SINGLE_BLOCK | SD_CONTEXT_DMA))
{
if (__HAL_SD_GET_FLAG(hsd, SDIO_FLAG_CMDREND))
{
/* Clear only selected flags */
__HAL_SD_CLEAR_FLAG(hsd, ((uint32_t)(SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT |
SDIO_FLAG_TXUNDERR | SDIO_FLAG_RXOVERR |
SDIO_FLAG_CMDSENT | SDIO_FLAG_DATAEND | SDIO_FLAG_DBCKEND)));
}
else
{
/* Clear all the static flags */
__HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
}
}
else
{
/* Clear all the static flags */
__HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
}
hsd->State = HAL_SD_STATE_READY;
#if (USE_HAL_SD_REGISTER_CALLBACKS == 1)
hsd->RxCpltCallback(hsd);
#else
HAL_SD_RxCpltCallback(hsd);
#endif
}
非常感谢楼主分享,你的这个是那个系列。 eric2013 发表于 2019-5-8 17:55
非常感谢楼主分享,你的这个是那个系列。
Cub: 5.2
HAL:STM32Cube_FW_F4_V1.24.1 captainliuy 发表于 2019-5-8 18:51
Cub: 5.2
HAL:STM32Cube_FW_F4_V1.24.1
感谢,正好要搞到这个,太及时了{:8:} STM32L4 没用啊,一样的超时。。。 SDMMC_CmdWriteSingleBlock函数中,SDMMC_GetCmdResp1超时。 如果用1线式SDIO就没这个问题。。。 ccschen 发表于 2021-10-12 22:46
STM32L4 没用啊,一样的超时。。。
请问后面您的L4板问题解决了么 KAQ 发表于 2022-3-15 13:57
请问后面您的L4板问题解决了么
解决了的,就是官方生成的代码,有文字错误。FREERTOS+DMA+FATFS,读写完成的信号量有个笔误。 ccschen 发表于 2022-4-22 13:33
解决了的,就是官方生成的代码,有文字错误。FREERTOS+DMA+FATFS,读写完成的信号量有个笔误。
请问您是如何解决的可以分享一下吗 本帖最后由 lvehe 于 2022-7-30 20:27 编辑
素履以往 发表于 2022-6-30 10:20
请问您是如何解决的可以分享一下吗
具体位于 sd_diskio.c 文件中的 SD_write() 函数中
if (event.value.v == WRITE_CPLT_MSG) //READ_CPLT_MSG) //笔误
if ((status == osOK) && (event == WRITE_CPLT_MSG)) //READ_CPLT_MSG)) //笔误 大神,解决了我的问题,请问是怎么定位是这个问题呢? 然而,但是,可是,同样L4系列的,具体到不同子系列和封装尾号的,同样的方法解决不了,感觉快成SD专业户了,能用SD或TF,就不要用贴片式的。 4bit有问题,1bit还算正常,跟这个有关吗?
然后就是单功能没问题,跑的东西多了就有问题了
页:
[1]