Hans 发表于 2019-11-12 15:11:00

FatFs + eMMC 返回 FR_DISK_ERROR

本帖最后由 Hans 于 2019-11-12 15:17 编辑

Hi 各位高手们,

我在尝试以STM32CubeMX 建置一专案,用FatFs 方式去操作 eMMC的部分,由于CubeMX仅只有SDCard 可以选择,所以必须以SDCard 设置为eMMC的方式。
在网上查询到在使用全新的eMMC需要格式化,则使用f_mkfs 并用 f_opendir 读取,但是却都返回 FR_DISK_ERROR,尝试几次都相同,还请各位高手协助。


附图及附档都在其中

再麻烦各位了!

感谢!


Hans 发表于 2019-11-14 10:05:42

本帖最后由 Hans 于 2019-11-14 10:18 编辑

更新
昨日测出 CLK & CMD 都有信号产生

目前有侦错 CSD的部分如图
可以抓出其中与 Datasheet 相关的资讯,但好像不是完全一样
https://i.imgur.com/dlmOqpZ.pnghttps://i.imgur.com/bZwL1NX.png

eMMC : Micron 8G
有人能提点一下,有什么需要注意的吗?目前状况仍然是 DISK_ERROR ,但是已经可以确定IC可以连上

eric2013 发表于 2019-11-12 20:10:55

返回这个错误,是表示你的diskio.c文件里面驱动实现有问题。

Hans 发表于 2019-11-13 08:20:03

eric2013 发表于 2019-11-12 20:10
返回这个错误,是表示你的diskio.c文件里面驱动实现有问题。

感谢 Eric 大的回覆

diskio.c 驱动指的是这个部分吗? 仅撷取一小部分您的demo

/*
* when using cachable memory region, it may be needed to maintain the cache
* validity. Enable the define below to activate a cache maintenance at each
* read and write operation.
* Notice: This is applicable only for cortex M7 based platform.
*/

#define ENABLE_SD_DMA_CACHE_MAINTENANCE1

/* Private variables ---------------------------------------------------------*/
/* Disk status */
static volatile DSTATUS Stat = STA_NOINIT;
static volatileUINTWriteStatus = 0, ReadStatus = 0;
/* Private function prototypes -----------------------------------------------*/
static DSTATUS SD_CheckStatus(BYTE lun);
DSTATUS SD_initialize (BYTE);
DSTATUS SD_status (BYTE);
DRESULT SD_read (BYTE, BYTE*, DWORD, UINT);
#if _USE_WRITE == 1
DRESULT SD_write (BYTE, const BYTE*, DWORD, UINT);
#endif /* _USE_WRITE == 1 */
#if _USE_IOCTL == 1
DRESULT SD_ioctl (BYTE, BYTE, void*);
#endif/* _USE_IOCTL == 1 */

const Diskio_drvTypeDefSD_Driver =
{
SD_initialize,
SD_status,
SD_read,
#if_USE_WRITE == 1
SD_write,
#endif /* _USE_WRITE == 1 */

#if_USE_IOCTL == 1
SD_ioctl,
#endif /* _USE_IOCTL == 1 */
};

/* Private functions ---------------------------------------------------------*/
static DSTATUS SD_CheckStatus(BYTE lun)
{
Stat = STA_NOINIT;

if(BSP_MMC_GetCardState() == MMC_TRANSFER_OK)
{
    Stat &= ~STA_NOINIT;
}

return Stat;
}

---------------------------------------------------------------------------------------------------------
另外我在侦错时,会在下面这个部分的HAL_GetTick返回ERROR,再麻烦您,谢谢!
---------------------------------------------------------------------------------------------------------
#if _USE_WRITE == 1
DRESULT SD_write(BYTE lun, const BYTE *buff, DWORD sector, UINT count)
{
DRESULT res = RES_ERROR;
WriteStatus = 0;
uint32_t timeout;

#if (ENABLE_SD_DMA_CACHE_MAINTENANCE == 1)
uint32_t alignedAddr;
/*
   the SCB_CleanDCache_by_Addr() requires a 32-Byte aligned address
   adjust the address and the D-Cache size to clean accordingly.
   */
alignedAddr = (uint32_t)buff &~0x1F;
SCB_CleanDCache_by_Addr((uint32_t*)alignedAddr, count*BLOCKSIZE + ((uint32_t)buff - alignedAddr));
#endif


if(BSP_MMC_WriteBlocks_DMA((uint32_t*)buff,
                            (uint32_t)(sector),
                            count) == MMC_OK)
{
    /* Wait that writing process is completed or a timeout occurs */

    timeout = HAL_GetTick();
    while((WriteStatus == 0) && ((HAL_GetTick() - timeout) < SD_TIMEOUT))
    {
    }
    /* incase of a timeout return error */
    if (WriteStatus == 0)
    {
      res = RES_ERROR;
    }
    else
    {
      WriteStatus = 0;
      timeout = HAL_GetTick();

      while((HAL_GetTick() - timeout) < SD_TIMEOUT)
      {
      if (BSP_MMC_GetCardState() == MMC_TRANSFER_OK)
      {
          res = RES_OK;
          break;
      }
      }
    }
}
return res;
}

eric2013 发表于 2019-11-13 08:35:48

你的硬件制作没问题吧,这点要优先保证

Hans 发表于 2019-11-13 08:48:33

eric2013 发表于 2019-11-13 08:35
你的硬件制作没问题吧,这点要优先保证

HAL_GetTick 会产生错误 与硬件相关性较大吗?

硬件部分测量过大致上没啥问题

eric2013 发表于 2019-11-13 08:55:51

Hans 发表于 2019-11-13 08:48
HAL_GetTick 会产生错误 与硬件相关性较大吗?

硬件部分测量过大致上没啥问题

这个是滴答定时器的获取api,你要配置好使用的滴答定时器还是其它定时器做的时间基准

Hans 发表于 2019-11-13 09:30:40

本帖最后由 Hans 于 2019-11-13 10:34 编辑

eric2013 发表于 2019-11-13 08:55
这个是滴答定时器的获取api,你要配置好使用的滴答定时器还是其它定时器做的时间基准
我用的是预设的定时器 Systick,主频设480MHz,SDMMC设70MHz 除频 = 2 大约35MHz,其余的就没特别设置,不知您在移植的时候有针对这个部分做特别的设置吗?


另外我有参考先前版上帖子,皆有测试过其中方式,但仍然是一样的状况

http://www.armbbs.cn/forum.php?mod=viewthread&tid=94962&highlight=fatfs




再麻烦您!

eric2013 发表于 2019-11-13 11:23:53

Hans 发表于 2019-11-13 09:30
我用的是预设的定时器 Systick,主频设480MHz,SDMMC设70MHz 除频 = 2 大约35MHz,其余的就没特别设置, ...

我们的程序没有特别设置。

Hans 发表于 2019-11-13 13:33:57

本帖最后由 Hans 于 2019-11-13 13:55 编辑

eric2013 发表于 2019-11-13 11:23
我们的程序没有特别设置。

Hans 发表于 2019-11-13 13:37:41

eric2013 发表于 2019-11-13 11:23
我们的程序没有特别设置。

好的 感谢老大
我稍早有对 【V7-025_FatFS文件系统例子(SD卡)】,进行修改
发现结果仍然是一样的状态,这让我开始怀疑硬体的问题。

还是十分感谢 您的协助!

dsLearner 发表于 2019-12-9 13:57:28

楼主你好,请问下你之前研究的FatFs+eMMC,现在成功了吗?
我最近在弄eMMc,我用的eMMC是16G的,USB连接电脑后U盘容量显示只有1G。对比了下H7-TOOL的github源码,发现在github源码中,MMC的hal库函数中,MMC_PowerON()函数内有判断MMC卡类型的语句,可供选择的选项是MMC_HIGH_CAPACITY_CARD、MMC_LOW_CAPACITY_CARD。
然而在stm32f4的Hal库函数中并没有以上两个选项,而是MMC_HIGH_VOLTAGE_CARD、MMC_DUAL_VOLTAGE_CARD这两个选项,不知这是否对eMMC卡的容量识别有影响?
在我的程序初始化过程中,得知初始化的时候CardType = MMC_DUAL_VOLTAGE_CARD。

另外,执行f_write()函数,运行没有返回值,卡在里面的函数了。

eric2013 发表于 2019-12-9 14:00:25

dsLearner 发表于 2019-12-9 13:57
楼主你好,请问下你之前研究的FatFs+eMMC,现在成功了吗?
我最近在弄eMMc,我用的eMMC是16G的,USB连接电 ...

F4不是原生支持eMMC的,不过也可以搞搞,我记得amobbs上有坛友分享过,你找找看。

dsLearner 发表于 2019-12-9 15:18:47

eric2013 发表于 2019-12-9 14:00
F4不是原生支持eMMC的,不过也可以搞搞,我记得amobbs上有坛友分享过,你找找看。

请问下,你之前研究过F4 的eMMC驱动吗?

amobbs上有坛友分享的源码在github找到了 amobbs论坛上的源码
经查看,该源码是修改SD卡的驱动来驱动eMMC的,暂未尝试。请问,你试过直接套用他的函数来实现驱动eMMC吗?

目前我的工程是使用STM32CubeMX V5.4.0 配置了MMC 8bit + FatFs+ USBD HS ,然后结合 STM32F4 eMMC支持 这个帖子下的12244.rar文件内的eMMC驱动,来驱动eMMC,通过初步查看,12244.rar文件内的eMMC驱动是通过调用MMC 的hal库的来的。将驱动函数加入到我的工程后,发现识别的容量不正确,16G的eMMC只识别出1G,使用FatFs R0.12c版本,BYTE workBuf;f_mkfs(USERPath, FM_FAT32, 512, workBuf, sizeof workBuf);格式化语句如上。
STM32F4 + eMMC 之 EXT_CSD寄存器读取和写入]使用了该文章的函数,直接获取容量值,可以获得正确的容量值,但是不清楚如何该容量值是否能与USB识别的容量值挂钩。



eric2013 发表于 2019-12-10 08:57:14

dsLearner 发表于 2019-12-9 15:18
请问下,你之前研究过F4 的eMMC驱动吗?

amobbs上有坛友分享的源码在github找到了 amobbs论坛上的源码 ...

这个不清楚哦,我没有用过F4驱动eMMC,只是之前偶尔看到过。
页: [1]
查看完整版本: FatFs + eMMC 返回 FR_DISK_ERROR