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

STM32+SDIO+DMA 4bits 出现卡死问题求助!!!

[复制链接]
chengdf83 提问时间:2011-11-26 21:46 /
我是使用的STM32F103VDT6芯片,TF卡使用的是sandisk class4 4G的。使用的是SDIO+DMA官方例程,单独测试没有发现问题,但是当我开启其他中断时(不管什么中断),比如我开启TIM3定时中断,中断频率为200Hz,中断中执行一个for循环来模拟中断处理,只要for循环的执行时间较长,就会出现TF卡的操作卡死问题,就是TF卡操作一直在等待DMA标志,并且for循环越长出现这种卡死的概率越大,当达到一定程度后TF卡完全不能操作。我大概估算了一下,差不多在中断执行时间达到总时间的20%左右就会明显有卡死现象,达到50%左右就基本上不能正常操作TF卡了。
由于我需要降低功耗,所以将主频降的比较低,4MHz,所以中断处理相对来说就显得执行时间较长,这样我才意识到这个问题,后来直接用官方例程实测,开通一个TIM3中断,执行for循环延时,当达到一定程度后,可以重现这个问题,所以我觉得应该是固件库或者是硬件的原因,不知道你们有没有发现这个问题,可以的话你们也可以这样测试一下,看能否重现这个问题,要是能解决的话,希望帮忙解决一下,要是这个问题得不到解决的话,我们只能放弃使用这个芯片了。
收藏 评论28 发布时间:2011-11-26 21:46

举报

28个回答
Andy-419672 回答时间:2015-2-10 09:58:37
if (errorstatus == SD_OK)
  {
                        /* 最后为了提高读写,开启4bits模式 */
    errorstatus = SD_EnableWideBusOperation(SDIO_BusWide_1b);       
  }  
用官网例程的话采用1bit模式就行了,应该是4bit模式和DMA配置方面的问题,具体的正在研究。
雪花苑 回答时间:2016-1-12 09:01:30
chengdf83 发表于 2011-11-28 13:13
非常感谢火雷达,我遇到的那个问题貌似解决了,呵呵。把流控加上后问题就搞定了,之前别人移植的代码,最近 ...

您好,关于您很久之前遇到的这个问题,我最近也遇到了,并且很纠结。请问您当时是怎么解决的?就是加了硬件流控么?可我加了硬件流控之后就会出现CRC校验错误。
decomen_leo 回答时间:2014-12-18 19:43:48
chengdf83 发表于 2011-11-28 13:13
非常感谢火雷达,我遇到的那个问题貌似解决了,呵呵。把流控加上后问题就搞定了,之前别人移植的代码,最近 ...

你说需要开启流控是啥意思,我也遇到了这个问题,希望您帮忙解决一下。QQ:1075785006
火雷达 回答时间:2011-11-27 10:30:28

RE:STM32+SDIO+DMA 4bits 出现卡死问题求助!!!

具体这个问题,我没有遇到过,不过能从你的描述来看,可能是你自己的程序问题:
1、用官方例程来测试没有问题,至少说明硬件和软件出现问题的几率比较小
2、加中断后,出现问题。这就很可能是中断处理的问题。
3、如果你没有加操作系统的话,就是你采用前后台的系统结构。
(1)把定时器的中断处理时间尽量减少(就是在中断响应函数执行时间缩短)
(2)把中断过程处理的for循环移到中断外面来处理,比如main函数里面,在中断函数只要做一个标记就可以了。
从你描述的过程中,应该是中断执行时间太久的原因(for循环越长出现这种卡死的概率越大),这个很可能是系统错过了某个事件。
不知道你的中断的优先级是怎么配置的。也有可能是让DMA中断不能及时响应。
chengdf83 回答时间:2011-11-27 12:20:29

RE:STM32+SDIO+DMA 4bits 出现卡死问题求助!!!

首先谢谢楼上的。
首先中断中没有涉及任何事情,只是延时问题。DMA是使用例程的,没有中断,是使用的查询方式,只有SDIO中断,并且SDIO中断的优先级最高,可以嵌套TIM3中断,整个系统就只有这两个中断。我没有使用操作系统,完全使用的是SDIO+DMA官方例程测试的。当然,把中断中的执行代码拿到中断外,这个问题就不会出现了,但是我的主频很低,中断中稍微多一点事务处理就很可能触发这个问题,我现在已经尽量将可以移出的处理移出来了,但是这个并没有找到问题的根源,说不准他就一定不会在什么时候出问题,而且以后系统需要扩展功能的话,这也是一个暗藏的问题。
我的意思是,即使在中断处理时间较长的情况下(条件比较苛刻的情况),也能保证程序不被卡死,因为只有这样才能保证系统的可靠性。
火雷达 回答时间:2011-11-27 13:37:41

RE:STM32+SDIO+DMA 4bits 出现卡死问题求助!!!

你说的也是,这是个定时炸弹。
你可以详细描述下什么是卡死?
1、你确认一下,SDIO包括STM32的驱动中是否有循环等待某个标志位
2、你的应用程序中(SDIO相关的)是否有循环等待某个标志位。
3、错误处理:
关于DMA,如果有需要的话,每次使用前,全部重新初始化下。我以前看到过一个帖子,说ADC+DMA出现问题,这个建议仅供参考,不负责任的。
chengdf83 回答时间:2011-11-27 15:26:10

RE:STM32+SDIO+DMA 4bits 出现卡死问题求助!!!

主要卡死在两个地方:
1、就是在初始化SD卡的时候,有一个FindSCR()函数中:
while (!(SDIO->STA & (SDIO_FLAG_RXOVERR | SDIO_FLAG_DCRCFAIL | SDIO_FLAG_DTIMEOUT | SDIO_FLAG_DBCKEND | SDIO_FLAG_STBITERR)))
  {
    if (SDIO_GetFlagStatus(SDIO_FLAG_RXDAVL) != RESET)
    {
      *(tempscr + index) = SDIO_ReadData();
      index++;
    }
  }
卡死在这个while循环中,不过这个可以使用index来判断,当大于1时就跳出,不会影响操作。这个姑且算是解决了吧。呵呵。
2、另一个就卡死在SD_ReadBlock()或者SD_WriteBlock()函数的DMA查询那里,比如SD_ReadBlock()中的:
SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND | SDIO_IT_RXOVERR | SDIO_IT_STBITERR, ENABLE);
    SDIO_DMACmd(ENABLE);
    DMA_RxConfiguration(readbuff, BlockSize);
    while (DMA_GetFlagStatus(DMA2_FLAG_TC4) == RESET)
    {}
这个就不好解决了,呵呵。通过观察SDIO中断标志,可以看出大多时候是出现了SDIO_IT_RXOVERR错误,但是极个别时候是数据正常。
另外,应用程序中是没有循环等待的。
测试程序是使用的官方例程,里面的DMA是每次使用前都重新配置了的。
很谢谢你的关注,呵呵。
chengdf83 回答时间:2011-11-27 15:37:55

RE:STM32+SDIO+DMA 4bits 出现卡死问题求助!!!

另外,我弱弱的问一下,SDIO发送和接受都是硬件操作吧?那我的中断操作应该不会影响SDIO硬件的发送、响应以及数据接收啊。也就是说前面的SDIO初始化配置都是命令发送以及响应,我查看了,命令发送和响应都是硬件一气呵成的,只要命令一旦装载到命令寄存器,硬件就开始运作,直到接收响应并且置标志位,中断在这些操作中是不会起到干扰的。
当我的中断延时加长后,在SDIO还没有正式传数据的时候就开始出现异常了(就是上面的第一个卡死的地方),这个好像是在读取SCR寄存器,用来确认SD卡是否支持4bits模式,但是这里读取的也是SDIO硬件的FIFO寄存器,也是硬件完成接收操作的。也就是说在出现异常前,所有的通信都是硬件完成,中断也只是间隔在每个操作进程之间的,按照常理来想,中断的长短应该不能引起这种异常啊。所以怎么想都想不通。  呵呵   还望指点迷津啊。
chengdf83 回答时间:2011-11-27 15:42:14

RE:STM32+SDIO+DMA 4bits 出现卡死问题求助!!!

还有一个比较重要的信息,好像卡死的基本上都是读数据的时候,包括第一种卡死的那个while其实也是读数据,写数据好像还没有发现卡死过,虽然也有while循环。是不是跟FIFO有关啊?
火雷达 回答时间:2011-11-27 18:33:22

RE:STM32+SDIO+DMA 4bits 出现卡死问题求助!!!

while (DMA_GetFlagStatus(DMA2_FLAG_TC4) == RESET)
{}
这个就不好解决了,呵呵。通过观察SDIO中断标志,可以看出大多时候是出现了SDIO_IT_RXOVERR错误,

SDIO_IT_RXOVERR这种错误是怎么解决的?
如果出现了这种错误,你所等待的标志位还是正常的吗?
如果出现错误标志位的话,你所等待的标志位没有置位的话,那你就是在一直等。就是死循环了。
等待的时候,还有做出错处理。
是不是这种情况?
火雷达 回答时间:2011-11-27 18:39:23

RE:STM32+SDIO+DMA 4bits 出现卡死问题求助!!!

你要防止硬件错误,这就是很多程序要做的工作,同时还要做正确的出错处理。
chengdf83 回答时间:2011-11-28 11:29:37

RE:STM32+SDIO+DMA 4bits 出现卡死问题求助!!!

我跟进去看了,之前认为和写数据没有关系是错误的,读写都有可能错误,就是卡在while (DMA_GetFlagStatus(DMA2_FLAG_TC4) == RESET)处,我将中断延时去掉,开启硬件流控后,也会卡死在这里,反而不开流控还没有卡死,真是郁闷。
chengdf83 回答时间:2011-11-28 11:31:32

RE:STM32+SDIO+DMA 4bits 出现卡死问题求助!!!

出现错误标志后,是按照例程中的处理方式处理的,处理函数是SD_ProcessIRQSrc():
---------------------------------------------------
/*******************************************************************************
* Function Name  : SD_ProcessIRQSrc
* Description    : Allows to process all the interrupts that are high.
* Input          : None
* Output         : None
* Return         : SD_Error: SD Card Error code.
*******************************************************************************/
SD_Error SD_ProcessIRQSrc(void)
{
  uint32_t count = 0, restwords = 0;
  if (DeviceMode == SD_INTERRUPT_MODE)
  {
#ifdef DISPSDINFO
    printf("\t\tSD_INTERRUPT_MODE\n");
#endif
    if (SDIO_GetITStatus(SDIO_IT_RXFIFOHF) != RESET)
    {
      for (count = 0; count < SD_HALFFIFO; count++)
      {
        *(DestBuffer + count) = SDIO_ReadData();
      }
      DestBuffer += SD_HALFFIFO;
      NumberOfBytes += SD_HALFFIFOBYTES;
    }
    else if (SDIO_GetITStatus(SDIO_IT_TXFIFOHE) != RESET)
    {
      if ((TotalNumberOfBytes - NumberOfBytes) < SD_HALFFIFOBYTES)
      {
        restwords = ((TotalNumberOfBytes - NumberOfBytes) %  4 == 0) ?
                    ((TotalNumberOfBytes - NumberOfBytes) / 4) :
                    ((TotalNumberOfBytes - NumberOfBytes) / 4 + 1);
        for (count = 0; count < restwords;  count++, SrcBuffer++, NumberOfBytes += 4)
        {
          SDIO_WriteData(*SrcBuffer);
        }
      }
      else
      {
        for (count = 0; count < SD_HALFFIFO; count++)
        {
          SDIO_WriteData(*(SrcBuffer + count));
        }
        SrcBuffer += SD_HALFFIFO;
        NumberOfBytes += SD_HALFFIFOBYTES;
      }
    }
  }
  if (SDIO_GetITStatus(SDIO_IT_DATAEND) != RESET)
  {
#ifdef DISPSDINFO
    printf("\t\tSDIO_IT_DATAEND\n");
#endif
    if (DeviceMode != SD_DMA_MODE)
    {
      while ((SDIO_GetFlagStatus(SDIO_FLAG_RXDAVL) != RESET)  &&  (NumberOfBytes < TotalNumberOfBytes))
      {
        *DestBuffer = SDIO_ReadData();
        DestBuffer++;
        NumberOfBytes += 4;
      }
    }
    if (StopCondition == 1)
    {
      TransferError = SD_StopTransfer();
    }
    else
    {
      TransferError = SD_OK;
    }
    SDIO_ClearITPendingBit(SDIO_IT_DATAEND);
    SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND |
                  SDIO_IT_TXFIFOHE | SDIO_IT_RXFIFOHF | SDIO_IT_TXUNDERR |
                  SDIO_IT_RXOVERR | SDIO_IT_STBITERR, DISABLE);
    TransferEnd = 1;
    NumberOfBytes = 0;
    return(TransferError);
  }
  if (SDIO_GetITStatus(SDIO_IT_DCRCFAIL) != RESET)
  {
#ifdef DISPSDINFO
    printf("\t\tSDIO_IT_DCRCFAIL\n");
#endif
    SDIO_ClearITPendingBit(SDIO_IT_DCRCFAIL);
    SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND |
                  SDIO_IT_TXFIFOHE | SDIO_IT_RXFIFOHF | SDIO_IT_TXUNDERR |
                  SDIO_IT_RXOVERR | SDIO_IT_STBITERR, DISABLE);
    NumberOfBytes = 0;
    TransferError = SD_DATA_CRC_FAIL;
    return(SD_DATA_CRC_FAIL);
  }
  if (SDIO_GetITStatus(SDIO_IT_DTIMEOUT) != RESET)
  {
#ifdef DISPSDINFO
    printf("\t\tSDIO_IT_DTIMEOUT\n");
#endif
    SDIO_ClearITPendingBit(SDIO_IT_DTIMEOUT);
    SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND |
                  SDIO_IT_TXFIFOHE | SDIO_IT_RXFIFOHF | SDIO_IT_TXUNDERR |
                  SDIO_IT_RXOVERR | SDIO_IT_STBITERR, DISABLE);
    NumberOfBytes = 0;
    TransferError = SD_DATA_TIMEOUT;
    return(SD_DATA_TIMEOUT);
  }
  if (SDIO_GetITStatus(SDIO_IT_RXOVERR) != RESET)
  {
#ifdef DISPSDINFO
    printf("\t\tSDIO_IT_RXOVERR\n");
#endif
    SDIO_ClearITPendingBit(SDIO_IT_RXOVERR);
    SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND |
                  SDIO_IT_TXFIFOHE | SDIO_IT_RXFIFOHF | SDIO_IT_TXUNDERR |
                  SDIO_IT_RXOVERR | SDIO_IT_STBITERR, DISABLE);
    NumberOfBytes = 0;
    TransferError = SD_RX_OVERRUN;
    return(SD_RX_OVERRUN);
  }
  if (SDIO_GetITStatus(SDIO_IT_TXUNDERR) != RESET)
  {
#ifdef DISPSDINFO
    printf("\t\tSDIO_IT_TXUNDERR\n");
#endif
    SDIO_ClearITPendingBit(SDIO_IT_TXUNDERR);
    SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND |
                  SDIO_IT_TXFIFOHE | SDIO_IT_RXFIFOHF | SDIO_IT_TXUNDERR |
                  SDIO_IT_RXOVERR | SDIO_IT_STBITERR, DISABLE);
    NumberOfBytes = 0;
    TransferError = SD_TX_UNDERRUN;
    return(SD_TX_UNDERRUN);
  }
  if (SDIO_GetITStatus(SDIO_IT_STBITERR) != RESET)
  {
#ifdef DISPSDINFO
    printf("\t\tSDIO_IT_STBITERR\n");
#endif
    SDIO_ClearITPendingBit(SDIO_IT_STBITERR);
    SDIO_ITConfig(SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_DATAEND |
                  SDIO_IT_TXFIFOHE | SDIO_IT_RXFIFOHF | SDIO_IT_TXUNDERR |
                  SDIO_IT_RXOVERR | SDIO_IT_STBITERR, DISABLE);
    NumberOfBytes = 0;
    TransferError = SD_START_BIT_ERR;
    return(SD_START_BIT_ERR);
  }
  return(SD_OK);
}
---------------------------------------------------
chengdf83 回答时间:2011-11-28 11:54:58

RE:STM32+SDIO+DMA 4bits 出现卡死问题求助!!!

加了硬件流控之后,出现SDIO_IT_DCRCFAIL错误了,晕死,搞到最后,和网上别人遇到的问题差不多了。但是没见到一位给出了解决方案的。
去掉流控,今天测试又没有出现SDIO_IT_RXOVERR错误了,程序就一直在while (DMA_GetFlagStatus(DMA2_FLAG_TC4) == RESET)卡起,期间没有进过SDIO中断,DMA2->ISR寄存器一直是0,也就是说SDIO没有出现传输错误,也没有传输完成,甚至都没有超时,DMA的寄存器也没有反应,就是DMA也没有操作完成,好像所有一套硬件机制都冻结了一样。
chengdf83 回答时间:2011-11-28 11:56:32

RE:STM32+SDIO+DMA 4bits 出现卡死问题求助!!!

不加流控的话,会不会导致硬件冻结呢?  呵呵   好像也不合常理。哎  我都快疯了。
chengdf83 回答时间:2011-11-28 13:13:07

RE:STM32+SDIO+DMA 4bits 出现卡死问题求助!!!

非常感谢火雷达,我遇到的那个问题貌似解决了,呵呵。把流控加上后问题就搞定了,之前别人移植的代码,最近天天看资料才发现流控制没有开启。
弄了这么多天,唉,还好,解决了。呵呵
火雷达 回答时间:2011-11-28 20:56:06

回复:STM32+SDIO+DMA 4bits 出现卡死问题求助!!!

问题解决了,就好了,这个MCU功能太复杂,很多东西忘记配置。
12下一页

所属标签

相似问题

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32Cube扩展软件包
意法半导体边缘AI套件
ST - 理想汽车豪华SUV案例
ST意法半导体智能家居案例
STM32 ARM Cortex 32位微控制器
关注我们
st-img 微信公众号
st-img 手机版