硬汉嵌入式论坛

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

[FatFs] 用stm32F4的sdio驱动emmc

  [复制链接]

3

主题

13

回帖

22

积分

新手上路

积分
22
发表于 2019-2-14 17:06:19 | 显示全部楼层 |阅读模式
本帖最后由 孤独的行程者 于 2019-2-15 16:45 编辑

请问有哪个大神用stm32玩过emmc的,可以一起分享下资料。
我参考网上的资料,按照这样顺序下发指令:CMD0 -> CMD1 -> CM2 -> CMD3 -> CMD9 -> 获取卡的信息->CMD7 -> CMD8(eMMC需要获得两次卡的信息,这是第二次)(读取ExtCSD寄存器信息)
现在我获取容量错误的,但是可以用扇区进行读写,跑Fatfs文件系统就不行。

JDEDC JESD84-B451中文.pdf

5.25 MB, 下载次数: 140

这是emmc参考资料

sdio_sdcard.c

65.98 KB, 下载次数: 92

这是我写的程序,请大神看看是什么问题

sdio_sdcard.h

23.48 KB, 下载次数: 67

SdioEmmcDrive.c

70.86 KB, 下载次数: 101

这是阿莫论坛的参考资料

SdioEmmcDrive.h

23.96 KB, 下载次数: 77

回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106678
QQ
发表于 2019-2-14 17:21:55 | 显示全部楼层
这个有研究价值。

MicroPython要发布一个带eMMC的套件,到时可以看看他们的驱动。

一般来说,只要你实现了读写函数,添加到FatFS的接口文件diskio.C就行。
回复

使用道具 举报

3

主题

13

回帖

22

积分

新手上路

积分
22
 楼主| 发表于 2019-2-14 17:29:33 | 显示全部楼层
现在是获取emmc容量的计算错误,进行扇区读写是没问题的,但不知道是不是所有扇区读写都没问题,我只是简单测试了几个扇区读写。
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106678
QQ
发表于 2019-2-15 00:09:11 | 显示全部楼层
孤独的行程者 发表于 2019-2-14 17:29
现在是获取emmc容量的计算错误,进行扇区读写是没问题的,但不知道是不是所有扇区读写都没问题,我只是简单 ...

amobbs上有位网友开源的,你参考下

https://www.amobbs.com/forum.php?mod=viewthread&tid=5577382
回复

使用道具 举报

2

主题

569

回帖

575

积分

金牌会员

积分
575
发表于 2019-2-15 08:52:29 | 显示全部楼层
嗯 阿莫上有人写了程序,还有人画了板子…
大于4.0版本的emmc估计32处理器玩不了
淘宝上还有emmc模块底板PCB,焊接好的成品模块都有卖的
玩的人还不少,估计都是冲着大容量自带磨损均衡等管理功能去的吧
选用时要注意工业等级,品质按常规理解, 三桑>透希巴>三低,坑屎顿
如果不考虑工业等级的话,还不如在板子上直接焊接一个sd卡上去,还省一个sd卡座子!
回复

使用道具 举报

3

主题

13

回帖

22

积分

新手上路

积分
22
 楼主| 发表于 2019-2-15 16:44:31 | 显示全部楼层
本帖最后由 孤独的行程者 于 2019-2-15 16:49 编辑

我已上传阿莫论坛的资料,你可以看下。我就是参考阿莫论坛的程序写的,不过有部分看不太懂,部分是照搬,现在就卡在那里。我是想知道那个论坛里有个人也参考程序能执行,但是我没帐号下载不了
QQ截图20190215164048.png
回复

使用道具 举报

3

主题

13

回帖

22

积分

新手上路

积分
22
 楼主| 发表于 2019-2-15 16:48:04 | 显示全部楼层
leiyitan 发表于 2019-2-15 08:52
嗯 阿莫上有人写了程序,还有人画了板子…
大于4.0版本的emmc估计32处理器玩不了
淘宝上还有emmc模块底板 ...

我是买了NanoPi M4配用的emmc模块,尝试用stm32f4看看能不能用fatfs文件系统进行读写文件,想代替nandflash存储大量文件
回复

使用道具 举报

3

主题

13

回帖

22

积分

新手上路

积分
22
 楼主| 发表于 2019-2-15 16:50:59 | 显示全部楼层
本帖最后由 孤独的行程者 于 2019-2-15 16:54 编辑

现在就卡死在这部分

//得到卡信息
//cardinfo:卡信息存储区
//返回值:错误状态
SD_Error SD_GetCardInfo(SD_CardInfo *cardinfo)
{
        SD_Error errorstatus=SD_OK;
        u8 tmp=0;          
        cardinfo->CardType=(u8)CardType;                                 //卡类型
        cardinfo->RCA=(u16)RCA;                                                        //卡RCA值
        tmp=(u8)((CSD_Tab[0]&0xFF000000)>>24);
        cardinfo->SD_csd.CSDStruct=(tmp&0xC0)>>6;                //CSD结构
        cardinfo->SD_csd.SysSpecVersion=(tmp&0x3C)>>2;        //2.0协议还没定义这部分(为保留),应该是后续协议定义的
        cardinfo->SD_csd.Reserved1=tmp&0x03;                        //2个保留位  
        tmp=(u8)((CSD_Tab[0]&0x00FF0000)>>16);                        //第1个字节
        cardinfo->SD_csd.TAAC=tmp;                                                   //数据读时间1
        tmp=(u8)((CSD_Tab[0]&0x0000FF00)>>8);                          //第2个字节
        cardinfo->SD_csd.NSAC=tmp;                                                  //数据读时间2
        tmp=(u8)(CSD_Tab[0]&0x000000FF);                                //第3个字节
        cardinfo->SD_csd.MaxBusClkFrec=tmp;                                  //传输速度          
        tmp=(u8)((CSD_Tab[1]&0xFF000000)>>24);                        //第4个字节
        cardinfo->SD_csd.CardComdClasses=tmp<<4;            //卡指令类高四位
        tmp=(u8)((CSD_Tab[1]&0x00FF0000)>>16);                         //第5个字节
        cardinfo->SD_csd.CardComdClasses|=(tmp&0xF0)>>4;//卡指令类低四位
        cardinfo->SD_csd.RdBlockLen=tmp&0x0F;                    //最大读取数据长度
        tmp=(u8)((CSD_Tab[1]&0x0000FF00)>>8);                        //第6个字节
        cardinfo->SD_csd.PartBlockRead=(tmp&0x80)>>7;        //允许分块读
        cardinfo->SD_csd.WrBlockMisalign=(tmp&0x40)>>6;        //写块错位
        cardinfo->SD_csd.RdBlockMisalign=(tmp&0x20)>>5;        //读块错位
        cardinfo->SD_csd.DSRImpl=(tmp&0x10)>>4;
        cardinfo->SD_csd.Reserved2=0;                                         //保留
//         if((CardType==SDIO_STD_CAPACITY_SD_CARD_V1_1)||(CardType==SDIO_STD_CAPACITY_SD_CARD_V2_0)||(SDIO_MULTIMEDIA_CARD==CardType))//标准1.1/2.0卡/MMC卡
//        {
                cardinfo->SD_csd.DeviceSize=(tmp&0x03)<<10;        //C_SIZE(12位)
                 tmp=(u8)(CSD_Tab[1]&0x000000FF);                         //第7个字节       
                cardinfo->SD_csd.DeviceSize|=(tmp)<<2;
                tmp=(u8)((CSD_Tab[2]&0xFF000000)>>24);                //第8个字节       
                cardinfo->SD_csd.DeviceSize|=(tmp&0xC0)>>6;
                cardinfo->SD_csd.MaxRdCurrentVDDMin=(tmp&0x38)>>3;
                cardinfo->SD_csd.MaxRdCurrentVDDMax=(tmp&0x07);
                tmp=(u8)((CSD_Tab[2]&0x00FF0000)>>16);                //第9个字节       
                cardinfo->SD_csd.MaxWrCurrentVDDMin=(tmp&0xE0)>>5;
                cardinfo->SD_csd.MaxWrCurrentVDDMax=(tmp&0x1C)>>2;
                cardinfo->SD_csd.DeviceSizeMul=(tmp&0x03)<<1;//C_SIZE_MULT
                tmp=(u8)((CSD_Tab[2]&0x0000FF00)>>8);                  //第10个字节       
                cardinfo->SD_csd.DeviceSizeMul|=(tmp&0x80)>>7;
//                 cardinfo->CardCapacity=(cardinfo->SD_csd.DeviceSize+1);//计算卡容量
//                cardinfo->CardCapacity*=(1<<(cardinfo->SD_csd.DeviceSizeMul+2));
//                cardinfo->CardBlockSize=1<<(cardinfo->SD_csd.RdBlockLen);//块大小
//                cardinfo->CardCapacity*=cardinfo->CardBlockSize;
               
                cardinfo->CardBlockSize = 1 << (cardinfo->SD_csd.RdBlockLen);

//这部分就是计算容量的
                cardinfo->CardCapacity = (uint64_t)((uint64_t)(cardinfo->EmmcExtCsd.EXT_CSD.SEC_COUNT[3] << 24 | cardinfo->EmmcExtCsd.EXT_CSD.SEC_COUNT[2] << 16 |
                cardinfo->EmmcExtCsd.EXT_CSD.SEC_COUNT[1] << 8 | cardinfo->EmmcExtCsd.EXT_CSD.SEC_COUNT[0]) * cardinfo->CardBlockSize);


//        }else if(CardType==SDIO_HIGH_CAPACITY_SD_CARD)        //高容量卡
//        {
//                 tmp=(u8)(CSD_Tab[1]&0x000000FF);                 //第7个字节       
//                cardinfo->SD_csd.DeviceSize=(tmp&0x3F)<<16;//C_SIZE
//                 tmp=(u8)((CSD_Tab[2]&0xFF000000)>>24);         //第8个字节       
//                 cardinfo->SD_csd.DeviceSize|=(tmp<<8);
//                 tmp=(u8)((CSD_Tab[2]&0x00FF0000)>>16);        //第9个字节       
//                 cardinfo->SD_csd.DeviceSize|=(tmp);
//                 tmp=(u8)((CSD_Tab[2]&0x0000FF00)>>8);         //第10个字节       
//                 cardinfo->CardCapacity=(long long)(cardinfo->SD_csd.DeviceSize+1)*512*1024;//计算卡容量
//                cardinfo->CardBlockSize=512;                         //块大小固定为512字节
//        }          
        cardinfo->SD_csd.EraseGrSize=(tmp&0x40)>>6;
        cardinfo->SD_csd.EraseGrMul=(tmp&0x3F)<<1;          
        tmp=(u8)(CSD_Tab[2]&0x000000FF);                        //第11个字节       
        cardinfo->SD_csd.EraseGrMul|=(tmp&0x80)>>7;
        cardinfo->SD_csd.WrProtectGrSize=(tmp&0x7F);
        tmp=(u8)((CSD_Tab[3]&0xFF000000)>>24);                //第12个字节       
        cardinfo->SD_csd.WrProtectGrEnable=(tmp&0x80)>>7;
        cardinfo->SD_csd.ManDeflECC=(tmp&0x60)>>5;
        cardinfo->SD_csd.WrSpeedFact=(tmp&0x1C)>>2;
        cardinfo->SD_csd.MaxWrBlockLen=(tmp&0x03)<<2;         
        tmp=(u8)((CSD_Tab[3]&0x00FF0000)>>16);                //第13个字节
        cardinfo->SD_csd.MaxWrBlockLen|=(tmp&0xC0)>>6;
        cardinfo->SD_csd.WriteBlockPaPartial=(tmp&0x20)>>5;
        cardinfo->SD_csd.Reserved3=0;
        cardinfo->SD_csd.ContentProtectAppli=(tmp&0x01);  
        tmp=(u8)((CSD_Tab[3]&0x0000FF00)>>8);                //第14个字节
        cardinfo->SD_csd.FileFormatGrouop=(tmp&0x80)>>7;
        cardinfo->SD_csd.CopyFlag=(tmp&0x40)>>6;
        cardinfo->SD_csd.PermWrProtect=(tmp&0x20)>>5;
        cardinfo->SD_csd.TempWrProtect=(tmp&0x10)>>4;
        cardinfo->SD_csd.FileFormat=(tmp&0x0C)>>2;
        cardinfo->SD_csd.ECC=(tmp&0x03);  
        tmp=(u8)(CSD_Tab[3]&0x000000FF);                        //第15个字节
        cardinfo->SD_csd.CSD_CRC=(tmp&0xFE)>>1;
        cardinfo->SD_csd.Reserved4=1;                 
        tmp=(u8)((CID_Tab[0]&0xFF000000)>>24);                //第0个字节
        cardinfo->SD_cid.ManufacturerID=tmp;                    
        tmp=(u8)((CID_Tab[0]&0x00FF0000)>>16);                //第1个字节
        cardinfo->SD_cid.OEM_AppliID=tmp<<8;          
        tmp=(u8)((CID_Tab[0]&0x000000FF00)>>8);                //第2个字节
        cardinfo->SD_cid.OEM_AppliID|=tmp;            
        tmp=(u8)(CID_Tab[0]&0x000000FF);                        //第3个字节       
        cardinfo->SD_cid.ProdName1=tmp<<24;                                  
        tmp=(u8)((CID_Tab[1]&0xFF000000)>>24);                 //第4个字节
        cardinfo->SD_cid.ProdName1|=tmp<<16;          
        tmp=(u8)((CID_Tab[1]&0x00FF0000)>>16);                   //第5个字节
        cardinfo->SD_cid.ProdName1|=tmp<<8;                 
        tmp=(u8)((CID_Tab[1]&0x0000FF00)>>8);                //第6个字节
        cardinfo->SD_cid.ProdName1|=tmp;                  
        tmp=(u8)(CID_Tab[1]&0x000000FF);                          //第7个字节
        cardinfo->SD_cid.ProdName2=tmp;                          
        tmp=(u8)((CID_Tab[2]&0xFF000000)>>24);                 //第8个字节
        cardinfo->SD_cid.ProdRev=tmp;                 
        tmp=(u8)((CID_Tab[2]&0x00FF0000)>>16);                //第9个字节
        cardinfo->SD_cid.ProdSN=tmp<<24;          
        tmp=(u8)((CID_Tab[2]&0x0000FF00)>>8);                 //第10个字节
        cardinfo->SD_cid.ProdSN|=tmp<<16;          
        tmp=(u8)(CID_Tab[2]&0x000000FF);                           //第11个字节
        cardinfo->SD_cid.ProdSN|=tmp<<8;                  
        tmp=(u8)((CID_Tab[3]&0xFF000000)>>24);                 //第12个字节
        cardinfo->SD_cid.ProdSN|=tmp;                             
        tmp=(u8)((CID_Tab[3]&0x00FF0000)>>16);                 //第13个字节
        cardinfo->SD_cid.Reserved1|=(tmp&0xF0)>>4;
        cardinfo->SD_cid.ManufactDate=(tmp&0x0F)<<8;   
        tmp=(u8)((CID_Tab[3]&0x0000FF00)>>8);                //第14个字节
        cardinfo->SD_cid.ManufactDate|=tmp;                           
        tmp=(u8)(CID_Tab[3]&0x000000FF);                        //第15个字节
        cardinfo->SD_cid.CID_CRC=(tmp&0xFE)>>1;
        cardinfo->SD_cid.Reserved2=1;         
        return errorstatus;
}
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106678
QQ
发表于 2019-2-18 00:15:48 | 显示全部楼层
孤独的行程者 发表于 2019-2-15 16:44
我已上传阿莫论坛的资料,你可以看下。我就是参考阿莫论坛的程序写的,不过有部分看不太懂,部分是照搬, ...

不好意思啊,这就帮不上了
回复

使用道具 举报

3

主题

13

回帖

22

积分

新手上路

积分
22
 楼主| 发表于 2019-2-20 15:33:31 | 显示全部楼层
容量计算部分搞定了,是发送指令顺序的问题,还差用文件系统进行读写部分,在网上查说要重新格式化就可以用文件系统进行读写了。现在有个问题就是用fr=f_mkfs("0",1,4096)来格式化,实际容量有8g的,格式化完之后只有1g的容量。
回复

使用道具 举报

8

主题

46

回帖

70

积分

初级会员

积分
70
发表于 2019-11-5 18:05:17 | 显示全部楼层
孤独的行程者 发表于 2019-2-20 15:33
容量计算部分搞定了,是发送指令顺序的问题,还差用文件系统进行读写部分,在网上查说要重新格式化就可以用 ...

请问楼主能否提供您的程序呢?
目前我也遇到了eMMC的错误状况,想能否给予参考呢?
或是阿莫的程序也可

非常感谢您!
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106678
QQ
发表于 2019-11-7 09:12:43 | 显示全部楼层
Hans 发表于 2019-11-5 18:05
请问楼主能否提供您的程序呢?
目前我也遇到了eMMC的错误状况,想能否给予参考呢?
或是阿莫的程序也可

参考我们H7-TOOL的即可。

https://github.com/armfly
回复

使用道具 举报

8

主题

46

回帖

70

积分

初级会员

积分
70
发表于 2019-11-7 10:25:55 | 显示全部楼层
eric2013 发表于 2019-11-7 09:12
参考我们H7-TOOL的即可。

https://github.com/armfly

非常感谢您的回覆!
已有参考网址,但找不到eMMC相关资料呢
能麻烦您协助吗?

不知是否为以下网址
https://github.com/armfly/H7-TOOL_STM32H7_App
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106678
QQ
发表于 2019-11-7 11:23:58 | 显示全部楼层
Hans 发表于 2019-11-7 10:25
非常感谢您的回覆!
已有参考网址,但找不到eMMC相关资料呢
能麻烦您协助吗?

QQ截图20191107112340.jpg
回复

使用道具 举报

8

主题

46

回帖

70

积分

初级会员

积分
70
发表于 2019-11-7 17:56:07 | 显示全部楼层

感谢您的协助
另外想与您请教
这个程序是不是没有使用到eMMC的功能呢?
对照后与我的设置大致相同 不知道有否更详细的程序呢?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106678
QQ
发表于 2019-11-8 08:14:27 | 显示全部楼层
Hans 发表于 2019-11-7 17:56
感谢您的协助
另外想与您请教
这个程序是不是没有使用到eMMC的功能呢?

这个就是完整的程序,可以直接操作访问。
早前做的数据测试:

H7-TOOL 读写emmc速度实测
http://www.armbbs.cn/forum.php?m ... 4768&fromuid=58
(出处: 硬汉嵌入式论坛)



回复

使用道具 举报

0

主题

1

回帖

1

积分

新手上路

积分
1
发表于 2020-5-30 21:09:27 | 显示全部楼层
楼主大神,你是用dma方式吗,能提供整个工程吗,感谢楼主
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106678
QQ
发表于 2020-5-31 09:54:21 | 显示全部楼层
Lcb2573539554 发表于 2020-5-30 21:09
楼主大神,你是用dma方式吗,能提供整个工程吗,感谢楼主

后面参考我的吧,8线SDIO DMA模式。

H7的8线SDIO DMA驱动eMMC的裸机性能,读43MB/S,写18.8MB/S
http://www.armbbs.cn/forum.php?m ... 5953&fromuid=58
(出处: 硬汉嵌入式论坛)
回复

使用道具 举报

1

主题

60

回帖

63

积分

初级会员

积分
63
发表于 2022-7-11 00:16:32 | 显示全部楼层
孤独的行程者 发表于 2019-2-20 15:33
容量计算部分搞定了,是发送指令顺序的问题,还差用文件系统进行读写部分,在网上查说要重新格式化就可以用 ...

是怎么样的顺序呢?我也是卡在容量上了,读取为0
回复

使用道具 举报

1

主题

3

回帖

6

积分

新手上路

积分
6
发表于 2022-9-8 15:50:07 | 显示全部楼层
楼主我遇到和你一摸一样的问题,不知道该怎么解决了。请问解决了吗?
回复

使用道具 举报

1

主题

3

回帖

6

积分

新手上路

积分
6
发表于 2022-9-8 15:50:48 | 显示全部楼层
遇到和楼主一样的问题,请问楼主解决了吗?
回复

使用道具 举报

0

主题

11

回帖

11

积分

新手上路

积分
11
发表于 2023-2-14 08:56:04 | 显示全部楼层
孤独的行程者 发表于 2019-2-20 15:33
容量计算部分搞定了,是发送指令顺序的问题,还差用文件系统进行读写部分,在网上查说要重新格式化就可以用 ...

老哥,可以咨询一下驱动emmc的部分吗,有偿,qq:1336624567
回复

使用道具 举报

0

主题

11

回帖

11

积分

新手上路

积分
11
发表于 2023-2-14 09:07:11 | 显示全部楼层
hezz 发表于 2022-9-8 15:50
遇到和楼主一样的问题,请问楼主解决了吗?

你好,你解决了吗,沟通一下可以么
回复

使用道具 举报

0

主题

11

回帖

11

积分

新手上路

积分
11
发表于 2023-2-14 10:02:25 | 显示全部楼层
孤独的行程者 发表于 2019-2-20 15:33
容量计算部分搞定了,是发送指令顺序的问题,还差用文件系统进行读写部分,在网上查说要重新格式化就可以用 ...

这个顺序是怎么改的呢
回复

使用道具 举报

0

主题

11

回帖

11

积分

新手上路

积分
11
发表于 2023-2-14 15:03:06
world_all 发表于 2022-7-11 00:16
是怎么样的顺序呢?我也是卡在容量上了,读取为0

老哥,你这个驱动emmc做好了吗

0

主题

11

回帖

11

积分

新手上路

积分
11
发表于 2023-2-14 15:03:42
hezz 发表于 2022-9-8 15:50
楼主我遇到和你一摸一样的问题,不知道该怎么解决了。请问解决了吗?

老哥,你这个emmc搞定了吗

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

本版积分规则

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

GMT+8, 2024-4-29 12:20 , Processed in 0.259062 second(s), 28 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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