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

STM32CubeMX+FreeRTOS+SD+FATFS碰到 DMA FIFO溢出问题

[复制链接]
juky2008 提问时间:2018-2-17 10:46 /
本帖最后由 juky2008 于 2018-2-19 09:46 编辑

大家好:
      我最近在使用的原子哥的STM32F407的开发板,芯片是STM32F407ZET6,原先我使用CubeMX4.21和F4库 1.16.0 调试SD卡驱动,用CubeMX配置收发DMA传输,但是生成的sd_disk.c中SD_read,SD_write函数并没有调用BSP_SD_ReadBlocks_DMA,BSP_SD_WriteBlocks_DMA函数。生成代码可以读取SD卡的信息,fatfs也可以挂载,但是多次新建文件打开和关闭后,fatfs返回FR_DISK_ERR;可能是由于SD卡无响应后超时导致。
    然后我下载STM32CubeMX4.24和1.19.0库文件,配置好后,生成的sd_disk.c中SD_read,SD_write函数使用了BSP_SD_ReadBlocks_DMA,BSP_SD_WriteBlocks_DMA函数和信号量(队列),进行了线程保护,但是生成的代码并不能使用。读写函数都卡在了 event = osMessageGet(SDQueueID, SD_TIMEOUT);分析后发现程序中并没有释放信号量,于是我在sd_disk.c文件最后添加了
  1. void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)
  2. {
  3.   BSP_SD_ReadCpltCallback();
  4. }

  5. void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd)
  6. {
  7.   BSP_SD_WriteCpltCallback();
  8. }
复制代码


void DMA2_Stream6_IRQHandler(void)中断调用了HAL_SD_TxCpltCallback回调函数,但是HAL_SD_RxCpltCallback()回调函数并没有被调用。FatFs不能正常读写SD卡。
最后我在CubeMX中开启了SDIO global interrupt 中断后SD卡后,HAL_SD_RxCpltCallback()才被调用。现在Fatfs可以正常读写SD卡(8GB)了。
间隔200ms给Fatfs测试任务发送通知,Fatfs测试任务完成创建文件(文件名不重复),写入数据(8192字节),关闭文件的功能,25000次(大概3小时)都没有问题,但是任务的完成时间由原来的200ms间隔(每次给任务发送通知),逐渐增加到1.2秒(每次任务完成后,会通过串口打印将信息发给电脑,串口助手有时间戳)。这个原因我现在不清楚。
通过仿真发现在中断函数中一直进入FIFO Error错误。但是SD卡可以正常读写。我没有找到原因。
  1. void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
  2. {
  3.   /* FIFO Error Interrupt management ******************************************/
  4.   if ((tmpisr & (DMA_FLAG_FEIF0_4 << hdma->StreamIndex)) != RESET)
  5.   {
  6.     if(__HAL_DMA_GET_IT_SOURCE(hdma, DMA_IT_FE) != RESET)
  7.     {
  8.       /* Clear the FIFO error flag */
  9.      regs->IFCR = DMA_FLAG_FEIF0_4 << hdma->StreamIndex;

  10.      /* Update error code */
  11.      hdma->ErrorCode |= HAL_DMA_ERROR_FE;
  12.     }
  13.   }
  14. }
复制代码




请大家多多指教,谢谢!


<
收藏 1 评论11 发布时间:2018-2-17 10:46

举报

11个回答
juky2008 回答时间:2018-2-18 20:26:57
本帖最后由 juky2008 于 2018-2-19 09:48 编辑

仿真时发现 在stm32f4xx_hal_sd.c ,只要一执行SDIO_ConfigData(hsd->Instance, &config);后就出现错误。
  1. HAL_StatusTypeDef HAL_SD_WriteBlocks_DMA(SD_HandleTypeDef *hsd, uint8_t *pData, uint32_t BlockAdd, uint32_t NumberOfBlocks)
  2. {
  3.   SDIO_DataInitTypeDef config;
  4.   uint32_t errorstate = HAL_SD_ERROR_NONE;
  5.   
  6.   if(NULL == pData)
  7.   {
  8.     hsd->ErrorCode |= HAL_SD_ERROR_PARAM;
  9.     return HAL_ERROR;
  10.   }
  11.   
  12.   if(hsd->State == HAL_SD_STATE_READY)
  13.   {
  14.     hsd->ErrorCode = HAL_DMA_ERROR_NONE;
  15.    
  16.     if((BlockAdd + NumberOfBlocks) > (hsd->SdCard.LogBlockNbr))
  17.     {
  18.       hsd->ErrorCode |= HAL_SD_ERROR_ADDR_OUT_OF_RANGE;
  19.       return HAL_ERROR;
  20.     }
  21.    
  22.     hsd->State = HAL_SD_STATE_BUSY;
  23.    
  24.     /* Initialize data control register */
  25.     hsd->Instance->DCTRL = 0U;
  26.    
  27.     /* Enable SD Error interrupts */  
  28. #ifdef SDIO_STA_STBITER
  29.     __HAL_SD_ENABLE_IT(hsd, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR | SDIO_IT_STBITERR));   
  30. #else /* SDIO_STA_STBITERR not defined */
  31.     __HAL_SD_ENABLE_IT(hsd, (SDIO_IT_DCRCFAIL | SDIO_IT_DTIMEOUT | SDIO_IT_TXUNDERR));   
  32. #endif /* SDIO_STA_STBITERR */
  33.    
  34.     /* Set the DMA transfer complete callback */
  35.     hsd->hdmatx->XferCpltCallback = SD_DMATransmitCplt;
  36.    
  37.     /* Set the DMA error callback */
  38.     hsd->hdmatx->XferErrorCallback = SD_DMAError;
  39.    
  40.     /* Set the DMA Abort callback */
  41.     hsd->hdmatx->XferAbortCallback = NULL;
  42.    
  43.     if(hsd->SdCard.CardType != CARD_SDHC_SDXC)
  44.     {
  45.       BlockAdd *= 512U;
  46.     }
  47.    
  48.     /* Set Block Size for Card */
  49.     errorstate = SDMMC_CmdBlockLength(hsd->Instance, BLOCKSIZE);
  50.     if(errorstate != HAL_SD_ERROR_NONE)
  51.     {
  52.       /* Clear all the static flags */
  53.       __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
  54.       hsd->ErrorCode |= errorstate;
  55.       hsd->State = HAL_SD_STATE_READY;
  56.       return HAL_ERROR;
  57.     }
  58.    
  59.     /* Write Blocks in Polling mode */
  60.     if(NumberOfBlocks > 1U)
  61.     {
  62.       hsd->Context = (SD_CONTEXT_WRITE_MULTIPLE_BLOCK | SD_CONTEXT_DMA);
  63.       
  64.       /* Write Multi Block command */
  65.       errorstate = SDMMC_CmdWriteMultiBlock(hsd->Instance, BlockAdd);
  66.     }
  67.     else
  68.     {
  69.       hsd->Context = (SD_CONTEXT_WRITE_SINGLE_BLOCK | SD_CONTEXT_DMA);
  70.       
  71.       /* Write Single Block command */
  72.       errorstate = SDMMC_CmdWriteSingleBlock(hsd->Instance, BlockAdd);
  73.     }
  74.     if(errorstate != HAL_SD_ERROR_NONE)
  75.     {
  76.       /* Clear all the static flags */
  77.       __HAL_SD_CLEAR_FLAG(hsd, SDIO_STATIC_FLAGS);
  78.       hsd->ErrorCode |= errorstate;
  79.       hsd->State = HAL_SD_STATE_READY;
  80.       return HAL_ERROR;
  81.     }
  82.    
  83.     /* Enable SDIO DMA transfer */
  84.     __HAL_SD_DMA_ENABLE(hsd);
  85.    
  86.     /* Enable the DMA Channel */
  87.     HAL_DMA_Start_IT(hsd->hdmatx, (uint32_t)pData, (uint32_t)&hsd->Instance->FIFO, (uint32_t)(BLOCKSIZE * NumberOfBlocks)/4);   //DMA2 stream6 发送0x80个数据,执行这条语句后,寄存器S6NDTR从0x80变成0xFFFF,太奇怪了。此时寄存器TCIF6=0,FEIF6=0;
  88.    
  89.     /* Configure the SD DPSM (Data Path State Machine) */
  90.     config.DataTimeOut   = SDMMC_DATATIMEOUT;
  91.     config.DataLength    = BLOCKSIZE * NumberOfBlocks;
  92.     config.DataBlockSize = SDIO_DATABLOCK_SIZE_512B;
  93.     config.TransferDir   = SDIO_TRANSFER_DIR_TO_CARD;
  94.     config.TransferMode  = SDIO_TRANSFER_MODE_BLOCK;
  95.     config.DPSM          = SDIO_DPSM_ENABLE;
  96.     SDIO_ConfigData(hsd->Instance, &config);//执行完这条语句后,S6NDTR=0xFF7F, 相当于发送的字节数0xFFFF-0xFF7F=0x80,难道是巧合?此时寄存器TCIF6=1,FEIF6=1;接着就进入DMA2_Stream6的FIFO ERROR中断了,每次都一样。但是数据已经发送出去了,TCIF也等于1了,Fatfs的f_write() 返回FR_OK。
  97.    
  98.     return HAL_OK;
  99.   }
  100.   else
  101.   {
  102.     return HAL_BUSY;
  103.   }
  104. }
复制代码


大家有没有碰到过这个问题啊?




feixiang20 回答时间:2018-3-16 09:49:22
是不是相关寄存器配置错误呢?FIFO失能?

评分

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

查看全部评分

wenyangzeng 回答时间:2018-3-16 10:10:33
FIFO关掉试看看,这个FIFO不那么好玩。

评分

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

查看全部评分

无薪税绵 回答时间:2018-3-16 10:29:24
会不会是SD卡的问题?
换一张SD卡再试试。

评分

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

查看全部评分

juky2008 回答时间:2018-3-16 11:30:18
本帖最后由 juky2008 于 2018-3-16 11:40 编辑

换过SD卡了,一样的问题。但都可以正常读写,用FATFS读写时间长后,sd卡的存储时间变长。
我主要想用STM32CubeMX生成,比较方便,SDIO的DMA配置上不能取消FIFO功能。如果不用DMA功能,SD卡响应会超时。
谢谢大家的回复。
toofree 回答时间:2018-3-16 14:14:55
这个问题太高端,我没搞过,只能帮你攒人气。
希望有能力的大佬快来帮忙!
yygkqzh 回答时间:2018-3-16 17:21:07
SDIO有3种方式 ,polling、IT,DMA,既然DMA不能使用,你可以首先试试POLLING、IT模式。
再退一步讲,你可以使用裸机试试能否成功,有没有错误消息,一步一步来。

评分

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

查看全部评分

juky2008 回答时间:2018-3-16 19:14:41
谢谢大家的提醒,我按照大家的方法去一步一步调试。
枫天2015 回答时间:2018-11-22 15:08:44
既然解决了?怎么不说明是哪的问题,怎么解决的呢
12下一页

所属标签

相似问题

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版