你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

高手请进,困扰很久的问题:STM32F7与MMC通讯异常错误

[复制链接]
小小小小强 提问时间:2018-9-5 19:27 /
本帖最后由 小小小小强 于 2018-9-6 09:15 编辑

我板子的配置是STM32F7 + Sandisk EMMC,软件环境为freertos + fatfs,EMMC驱动为ST HAL库自带的,驱动程序能够正常读写EMMC。在长时间读写后会遇到STM32发送命令后读取不到响应的问题,复现问题的时间有长有短,但是每次都是在HAL_MMC_ReadBlocks_DMA中出错,报错的代码位置为:
do
  {
    if (count-- == 0)
    {
                printf("line:%d,sta:0x%x,res_cmd=0x%x,SD_CMD:%d,req_cmd:%d,dctl:0x%x\r\n",__LINE__,SDMMCx->STA,SDMMCx->RESPCMD,SD_CMD,\
                        SDMMCx->CMD,SDMMCx->DCTRL);
      return SDMMC_ERROR_TIMEOUT;
    }

  }while(!__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT));
都是count=0后超时退出,我把count值修改到非常大也会遇到相同的问题。通过Sandisk实验室的MMC分析仪抓取整个通信过程分析,MMC在收到命令后是正常响应了,是STM32端没有读到响应,由于已经是直接读取寄存器了,所以我这个小白就不知道如何判断为什么STM32没有收到回复了,也不知道改如何修改,既然MMC已经回复了,有哪些原因可能会导致SDMMC STA寄存器相应位的值没有改变?希望各位高手提出建议,感激不尽。


收藏 评论16 发布时间:2018-9-5 19:27

举报

16个回答
feixiang20 回答时间:2018-9-5 23:27:59
是不是count这个变量在中断函数里面声明错误呢,定义没赋值么,时钟开了么,时钟时间设置过长么

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

小小小小强 回答时间:2018-9-6 09:02:50



谢谢楼上关注。我贴出更完整代码,都是STM32F7 HAL库自带
static uint32_t SDMMC_GetCmdResp1(SDMMC_TypeDef *SDMMCx, 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 / 8 /1000);
  
  do
  {
    if (count-- == 0)
    {
                printf("line:%d,sta:0x%x,res_cmd=0x%x,SD_CMD:%d,req_cmd:%d,dctl:0x%x\r\n",__LINE__,SDMMCx->STA,SDMMCx->RESPCMD,SD_CMD,\
                        SDMMCx->CMD,SDMMCx->DCTRL);
      return SDMMC_ERROR_TIMEOUT;
    }
   
  }while(!__SDMMC_GET_FLAG(SDMMCx, SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT));
//省略STA判断
}
count变量值为函数形参根据系统时钟计算出来的。现在系统时钟为208M,MMC CLK为20.48M,通讯为8BIT模式
小小小小强 回答时间:2018-9-6 09:04:52
另外,出错的时候测量,CLK线上一直有时钟,通过sandisk FAE用MMC通讯分析仪查看,STM32付出CMD后,MMC是正确回复了的,是STM32端没有读到。
小小小小强 回答时间:2018-9-6 09:10:56
feixiang20 发表于 2018-9-5 23:27
是不是count这个变量在中断函数里面声明错误呢,定义没赋值么,时钟开了么,时钟时间设置过长么 ...

count值没有在中断函数里声明,出错时测量CLK线上信号正常。
小小小小强 回答时间:2018-9-6 18:44:28
人工顶下
hpingfr 回答时间:2018-10-30 11:31:36
也遇到这个问题了,有没有高手给解决一下
e190 回答时间:2018-12-1 16:09:35
请问楼主这个问题解决了吗?我也遇到这个问题
小小小小强 回答时间:2018-12-27 08:24:18
这个问题已经接近,办法是需要在调用MMC的API前先关闭中断,调用返回后重新打开中断

评分

参与人数 1蝴蝶豆 +2 收起 理由
STMCU + 2

查看全部评分

captainliuy 回答时间:2019-5-8 10:30:53
st论坛里有人给出的解释,但是没有给出解决办法,是因为中断的问题。

Do you happen to be using an RTOS and the SDIO in DMA mode? I've just solved what I believe is the same problem in the STM32F4 HAL drivers.



The problem presents itself when an RTOS context switch happens AFTER SDIO_SendCommand() is called (which begins to clock out the CMD), but before the SDMMC_FLAG_CMDREND flag is set. If a task context switch happens at this time, and does not return to the current task before SD_DMAReceiveCplt() is called, the SDMMC_FLAG_CMDREND is cleared, and never "noticed" by the SDMMC_GetCmdResp1() timeout loop.



In the attached Saleae Logic capture:

ERROR is low after an SDIO timeout occurs.

SDIO wait_loop is low when entering the waiting loop in SDMMC_GetCmdResp1(), high when exiting

ClearSDIOFlags is low then high whenever the SDIO flags are cleared.

SD_CMD is the SDIO CMD line

SD_D0 is the SD_D0 line

PJ11 goes low then high each time the loop in SDMMC_GetCmdResp1() checks the flags in the loop.



When the error happens at the end of the capture, an RTOS context switch happens so the CPU executes another task shortly after SDIO_SendCommand() is called. The flags are not being checked at this point, and while they are properly set, they are eventually cleared by the SD_DMAReceiveCplt() ISR function before SDMMC_GetCmdResp1() ever gets back into the execution context.



Hope this helps.

评分

参与人数 1蝴蝶豆 +3 收起 理由
STMCU + 3

查看全部评分

12下一页
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版