captainliuy 发表于 2019-5-8 13:43:50

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:16

非常感谢楼主分享,你的这个是那个系列。

captainliuy 发表于 2019-5-8 18:51:08

eric2013 发表于 2019-5-8 17:55
非常感谢楼主分享,你的这个是那个系列。

Cub: 5.2
HAL:STM32Cube_FW_F4_V1.24.1

eric2013 发表于 2019-5-9 01:02:53

captainliuy 发表于 2019-5-8 18:51
Cub: 5.2
HAL:STM32Cube_FW_F4_V1.24.1

感谢,正好要搞到这个,太及时了{:8:}

ccschen 发表于 2021-10-12 22:46:13

STM32L4 没用啊,一样的超时。。。

ccschen 发表于 2021-10-12 22:46:42

SDMMC_CmdWriteSingleBlock函数中,SDMMC_GetCmdResp1超时。

ccschen 发表于 2021-10-12 22:51:37

如果用1线式SDIO就没这个问题。。。

KAQ 发表于 2022-3-15 13:57:57

ccschen 发表于 2021-10-12 22:46
STM32L4 没用啊,一样的超时。。。

请问后面您的L4板问题解决了么

ccschen 发表于 2022-4-22 13:33:58

KAQ 发表于 2022-3-15 13:57
请问后面您的L4板问题解决了么

解决了的,就是官方生成的代码,有文字错误。FREERTOS+DMA+FATFS,读写完成的信号量有个笔误。

素履以往 发表于 2022-6-30 10:20:35

ccschen 发表于 2022-4-22 13:33
解决了的,就是官方生成的代码,有文字错误。FREERTOS+DMA+FATFS,读写完成的信号量有个笔误。

请问您是如何解决的可以分享一下吗

lvehe 发表于 2022-7-29 15:37:23

本帖最后由 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)) //笔误

l2830692300 发表于 2022-8-11 16:08:36

大神,解决了我的问题,请问是怎么定位是这个问题呢?

ccschen 发表于 2023-8-2 21:53:55

然而,但是,可是,同样L4系列的,具体到不同子系列和封装尾号的,同样的方法解决不了,感觉快成SD专业户了,能用SD或TF,就不要用贴片式的。

JustQin 发表于 2024-1-7 11:32:17

4bit有问题,1bit还算正常,跟这个有关吗?
然后就是单功能没问题,跑的东西多了就有问题了
页: [1]
查看完整版本: STM32CbueMX+FatFS+SD+FreeRTOS DMA 超时bug