硬汉嵌入式论坛

 找回密码
 立即注册
查看: 6516|回复: 13
收起左侧

[FatFs] STM32CbueMX+FatFS+SD+FreeRTOS DMA 超时bug

  [复制链接]

29

主题

101

回帖

188

积分

初级会员

积分
188
发表于 2019-5-8 13:43:50 | 显示全部楼层 |阅读模式
RTOS负载比较重的时候,SD卡操作容易卡在
  1. static uint32_t SDMMC_GetCmdResp1(SDIO_TypeDef *SDIOx, uint8_t SD_CMD, uint32_t Timeout)
  2. {
  3.   uint32_t response_r1;
  4.   
  5.   /* 8 is the number of required instructions cycles for the below loop statement.
  6.   The Timeout is expressed in ms */
  7.   register uint32_t count = Timeout * (SystemCoreClock / 8U /1000U);
  8.   
  9.   do
  10.   {
  11.     if (count-- == 0U)
  12.     {
  13.       <font color="#ff0000">return SDMMC_ERROR_TIMEOUT;</font>
  14.     }
  15.    
  16.   }while(!__SDIO_GET_FLAG(SDIOx, SDIO_FLAG_CCRCFAIL | SDIO_FLAG_CMDREND | SDIO_FLAG_CTIMEOUT));
  17. -----
  18. }
复制代码
因为SDIO_FLAG_CMDREND 标志在SD_DMAReceiveCplt中错误的清掉了,修改HAL驱动
/**
  * @brief  DMA SD receive process complete callback
  * @param  hdma 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
}

评分

参与人数 1金币 +100 收起 理由
eric2013 + 100 很给力!

查看全部评分

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106622
QQ
发表于 2019-5-8 17:55:16 | 显示全部楼层
非常感谢楼主分享,你的这个是那个系列。
回复

使用道具 举报

29

主题

101

回帖

188

积分

初级会员

积分
188
 楼主| 发表于 2019-5-8 18:51:08 | 显示全部楼层
eric2013 发表于 2019-5-8 17:55
非常感谢楼主分享,你的这个是那个系列。

Cub: 5.2
HAL:STM32Cube_FW_F4_V1.24.1
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106622
QQ
发表于 2019-5-9 01:02:53 | 显示全部楼层
captainliuy 发表于 2019-5-8 18:51
Cub: 5.2
HAL:STM32Cube_FW_F4_V1.24.1

感谢,正好要搞到这个,太及时了
回复

使用道具 举报

19

主题

125

回帖

182

积分

初级会员

积分
182
发表于 2021-10-12 22:46:13 | 显示全部楼层
STM32L4 没用啊,一样的超时。。。
回复

使用道具 举报

19

主题

125

回帖

182

积分

初级会员

积分
182
发表于 2021-10-12 22:46:42 | 显示全部楼层
SDMMC_CmdWriteSingleBlock函数中,SDMMC_GetCmdResp1超时。
回复

使用道具 举报

19

主题

125

回帖

182

积分

初级会员

积分
182
发表于 2021-10-12 22:51:37 | 显示全部楼层
如果用1线式SDIO就没这个问题。。。
回复

使用道具 举报

0

主题

1

回帖

1

积分

新手上路

积分
1
发表于 2022-3-15 13:57:57 | 显示全部楼层
ccschen 发表于 2021-10-12 22:46
STM32L4 没用啊,一样的超时。。。

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

使用道具 举报

19

主题

125

回帖

182

积分

初级会员

积分
182
发表于 2022-4-22 13:33:58 | 显示全部楼层
KAQ 发表于 2022-3-15 13:57
请问后面您的L4板问题解决了么

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

使用道具 举报

0

主题

1

回帖

1

积分

新手上路

积分
1
发表于 2022-6-30 10:20:35 | 显示全部楼层
ccschen 发表于 2022-4-22 13:33
解决了的,就是官方生成的代码,有文字错误。FREERTOS+DMA+FATFS,读写完成的信号量有个笔误。

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

使用道具 举报

10

主题

140

回帖

170

积分

初级会员

积分
170
发表于 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)) //笔误
回复

使用道具 举报

0

主题

3

回帖

3

积分

新手上路

积分
3
发表于 2022-8-11 16:08:36 | 显示全部楼层
大神,解决了我的问题,请问是怎么定位是这个问题呢?
回复

使用道具 举报

19

主题

125

回帖

182

积分

初级会员

积分
182
发表于 2023-8-2 21:53:55 | 显示全部楼层
然而,但是,可是,同样L4系列的,具体到不同子系列和封装尾号的,同样的方法解决不了,感觉快成SD专业户了,能用SD或TF,就不要用贴片式的。
回复

使用道具 举报

1

主题

4

回帖

7

积分

新手上路

积分
7
发表于 2024-1-7 11:32:17 | 显示全部楼层
4bit有问题,1bit还算正常,跟这个有关吗?
然后就是单功能没问题,跑的东西多了就有问题了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-4-27 03:38 , Processed in 0.298474 second(s), 26 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表