uboot环境下mmc操作_【记录】将Uboot 2011.06中mmc驱动移植到uboot 1.1.6的过程
【记录】将Uboot 2011.06中mmc驱动移植到uboot 1.1.6的过程
时间:2011-8-14
作者:crifan
联系方式:green-waste (at) 163.com
附上代码:
【背景】
硬件:
(1)TQ2440,CPU是S3C2440,带SD/MMC控制器。
(2)自己的金士顿的1GB的SD卡
软件:
(1)TQ2440的uboot 1.1.6
(2)自己已经移植旧的mmc的驱动成功,可以实现mmcinfo, fatls mmc 0, fatload mmc 0 addr file,但是旧的mmc中检测出来的sd卡的容量不对,原因是由于READ_BL_LEN是15,大于12了,用的计算方法是错误的。
详情参见:
【记录】在TQ2440的uboot中添加SD/MMC支持+添加USB Mass Storage支持+解决fatls乱码问题
【目的】
想要实现正确检测我的1GB的SD卡的容量,所以要把正确的mmc驱动移植过来。
而目前最新的uboot 2011.06版本的中,已经有最新的mmc驱动,但是和uboot 1.1.6比,mmc的整个架构都变了,需要把mmc部分,整个都改了,再添加对应的底层函数,才可以。
【将Uboot 2011.06中mmc驱动移植到uboot 1.1.6的全过程】
1.添加文件,修改makefile等准备工作
先是把mmc最直接相关的cmd_mmc.c,整个替换了
这样就支持了更多的mmc相关的命令了:
mmcinfo
mmc rescan
mmc part
mmc list
mmc dev
fatls mmc 0
fatload mmc 0 addr filename
同时,替换了最新的mmc.h头文件,该文件包含了对应的sd/mmc所有的命令等定义。
由于旧的uboot中在board.c的start_armboot()中没有mmc初始化部分,所以也要填上对应内容:#ifdef CONFIG_GENERIC_MMC
puts(“MMC:“);
mmc_initialize(gd->bd);
#endif
而后再去添加对应的makefile等,使得编译通过,不多细说。
2. s3c_mmc_init()
用beyondcompare,将uboot 2011.06和uboot 1.1.6相比较,发现新的mmc驱动框架中,主要实现几个核心函数即可,此处我的sd/mmc控制器是三星的S3C2440的,所以简称为s3c,对应的第一个要实现的函数为:/* this is a weak define that we are overriding */
int board_mmc_init(bd_t *bd)
{
return s3c_mmc_init(bd);
}
中的:s3c_mmc_init()
其中,主要是初始化mmc中一些核心的参数,主要代码是:mmc->send_cmd = s3cmmc_send_cmd;
mmc->set_ios = s3cmmc_set_ios;
mmc->init = s3cmmc_init;
将挂上发送命令,设置总线宽度/频率等,初始化三个函数的指针
mmc->host_caps = MMC_MODE_4BIT | MMC_MODE_HS;
告诉sd host支持4bit模式 即High Speed即50MHz模式
mmc->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
此处电压是参考其他驱动写上的,具体含义没有深入去了解
mmc->f_max = get_PCLK();
mmc->f_min = 400*1000;
设置所支持的最大和最小频率
mmc->block_dev.part_type = PART_TYPE_DOS;
设置sd卡分区的类型是DOS,即常见的FAT分区
mmc->b_max = 0;
设置最大的block数目,0为没限制,mmc系统会自动初始化
都设置好了,再去调用
mmc_register(mmc);
上述内容都设置好了,然后就是分别去实现上述三个核心的函数:
3. s3cmmc_init()
init函数中,主要就是初始化sd的硬件相关的部分
其主要代码和之前旧的差不多,只是把blocksize设置,频率设置,等等,都放到了setios函数或者send_cmd函数中了而已,没有太多需要解释的,参考之前代码即可。
4. s3cmmc_set_ios()
set_ios中,主要就是两个:
(1)当传入的参数中clock不为0时候,去根据所需要的频率去设置对应的SDIPRE寄存器即可;
(2) 根据传入的总线宽度,此处即1或者4,1就是最开始的默认的,4就是对应的wide bus,设置对应的SDIDCON寄存器即可。
5. s3cmmc_send_cmd()
发送命令,这个函数可以个大头,需要花不少精力的。
通过看uboot 2011.06中其他mmc驱动的实现,大概看懂了此处,mmc发送命令的函数,其实处理了两个事情,一个是发送普通命令,二是对于数据的读写,其实也是通过发送对应对应的命令,然后读写对应数据的。
即普通的发送命令,只需要发送命令即可;
而包括数据读写的命令,参数是放在data中的,data不为空的时候,就不仅仅要发送对应的命令,还要接着读写数据的。
此处暂时不去实现数据的write,只考虑read的情况,目的是实现相关的命令fatls mmc 0和fatload mmc 0 addr file。
(1)单纯的发送命令
关于发送命令,之前也已经有了对应的函数send_cmd,把旧函数,拿过来,改一下,也基本就实现了。
【关于发送命令之后的response】
另外需要提及一点的是,如果发送命令需要反馈response的,对于
cmd->resp_type中有MMC_RSP_PRESENT的,那么至少要返回一个response,而如果是长的response,即MMC_RSP_136,是需要返回四个response的,详情参考代码。
【使用readl/writel时候,需要传入寄存器的地址而不是寄存器的值】
另外还有点要说明的,对于用writel/readl,readb/writeb等函数来代替直接寄存器操作的,传入的寄存器地址,是需要是地址的,而不能是寄存器的值,即:
原先读一个寄存器:csta = sdi->SDICSTA;
现在用readl时,要传入寄存器的地址,要这样调用:csta = readl(&sdi->SDICSTA);
而不能是csta = readl(sdi->SDICSTA);
关于这点,也是参考了别的代码和调试,才发现这点的。
【诡异问题:S3C2410_SDICMDCON_SENDERHOST的含义】
不过,这里在调试代码过程中,发现一个有点诡异的问题,那就是,对于设置command control寄存器的时候,原先代码是:
ccon |=S3C2410_SDICMDCON_SENDERHOST | S3C2410_SDICMDCON_CMDSTART;
其中
#define S3C2410_SDICMDCON_SENDERHOST(1<<6)
但是对应的S3C2410和S3C2440的datasheet中,都没有提到这一点,而只是网上这些S3C2410和S3C2440的sd卡驱动的参考代码,包括uboot和kernel中的,却有这个位的设置,而如果去掉这一位的设置,命令就无法正常发送。
虽然看名字S3C2410_SDICMDCON_SENDERHOST知道大概是host是sender,但是对于这一位的具体含义是什么,还是不懂,希望如果有知情的可以解释一下。
(2)带读数据的命令的发送和之后的数据读取
但是对于带读数据的命令的发送,包括MMC_CMD_READ_MULTIPLE_BLOCK=CMD17读块数据和MMC_CMD_SEND_EXT_CSD=CMD8读扩展CSD等等,就不仅仅要先发送命令,还要接着读对应的数据才可以的。
对于read block等命令,其处理的时候,要先设置好datasize寄存器,
再根据之前设置的SDIDCON中的bus width是1还是4,决定设置数据控制寄存器中是S3C2440_SDIDCON_DS_WORD还是S3C2440_SDIDCON_DS_BYTE,
等设置好了SDIDCON之后,接着再去发送对应的带数据读的命令,然后接着处理的流程和之前旧的代码是一样的,即先去fifosta中找到fifo中有多少个数据,然后一个个读取,每次读取1个字节还是4个字节,由之前的bus width决定。
等读完当前fifo了再去重复读取fifosta,再去判断有多少个字节数据需要读取,
这样一点点把数据读出来即可。
读数据的过程中,需要通过读取SDIDSTA得知数据的状态是否正常,如果有错误,比如超时,CRC错误等,就退出。
此部分流程,基本和旧的代码没太大区别。
但是代码调试过程中,这部分代码,在读取数据部分,始终出错,让我调试了很久,最后找到原因,竟然是自己不小心,在读取了SDIDCON的值后,忘了把原来的bus width那一位给设置回去,所以再之前去设置bus width=4=word之后,此处还是用bus width=1=byte的模式来读数据,所以出现第一次读SDIFSTA而获得的FIFO中的字节数,竟然是有奇数的,比如0x1c7,而不是期望的64啊之类的,应该是4的倍数的,最后加上对应的正确的设置后,后面的读取数据就都对了。
【未解决的疑问:CMD8和CMD13超时】
在最后可以成功读数据之后,却也还是发现有两个命令会超时:
MMC CMD8 Timeout
MMC CMD13 Timeout
具体原因未知。有待后期再去找原因,或者哪个高手告知一下原因。
最后贴上可以成功检测出我的1GB的SD卡的log信息:EmbedSky> help mmc
mmc read addr blk# cnt
mmc write addr blk# cnt
mmc rescan
mmc part – lists available partition on current mmc device
mmc dev [dev] [part] – show or set current mmc device [partition]
mmc list – lists available devices
EmbedSky> mmcinfo
MMC CMD8 Timeout
MMC CMD13 Timeout
Status Error: 0x002D0032
Device: TQ2440 SD/MMC
Manufacturer ID: 2
OEM: 544d
Name: SD01G
Tran Speed: 25000000
Rd Block Len: 512
SD version 1.10
High Capacity: No
Capacity: 982.5 MB
Bus Width: 4-bit
EmbedSky> mmc rescan
MMC CMD8 Timeout
MMC CMD13 Timeout
Status Error: 0x002D0032
EmbedSky> mmc part
Partition Map for UNKNOWN device 0—Partition Type: DOS
PartitionStart SectorNum SectorsType
124320119176
EmbedSky> mmc dev
mmc0 is current device
EmbedSky> mmc list
TQ2440 SD/MMC: 0
EmbedSky> fatls mmc 0
MMC CMD13 Timeout
512nikon001.dsc
misc/
dcim/
3701fisrttest.html
2 file(s), 2 dir(s)
uboot环境下mmc操作_【记录】将Uboot 2011.06中mmc驱动移植到uboot 1.1.6的过程相关推荐
- python环境下数据操作_数据分析环境搭建和Python基础知识
搭建数据分析环境主要包括使用anaconda管理包和环境:使用Jupyter notebook将说明文本.数学方程.代码和可视化内容全部组合到一个易于共享的文档中.Python基础知识包括关键点(数据 ...
- mac php 连接mysql数据库_Mac环境下php操作mysql数据库的方法分享
Mac环境下php操作mysql数据库的方法分享 今天在mac上搭建好了php的环境,我们就把php操作mysql数据库的方法分享给大家,有需要的小伙伴参考下. Mac本地环境搭建 在Mac系统,我们 ...
- mac php 连接mysql数据库_Mac环境下php操作mysql数据库的方法分享_PHP教程
Mac环境下php操作mysql数据库的方法分享 今天在mac上搭建好了php的环境,我们就把php操作mysql数据库的方法分享给大家,有需要的小伙伴参考下. Mac本地环境搭建 在Mac系统,我们 ...
- jsp mysql环境_MySQL在JSP环境下的操作应用
前提: 将mysql数据库的驱动放在工作目录的web-inf/lib目录下(这样才能在jsP中连结上) 用javaBean连接,将编译好得.class文件放在classes文件下,若文件包含packa ...
- 痞子衡嵌入式:在IAR开发环境下将整个源文件代码重定向到任意RAM中的方法
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是在IAR开发环境下将整个源文件代码重定向到任意RAM中的方法. 痞子衡旧文 <在IAR下将关键函数重定向到RAM中执行的方法> ...
- uboot环境下mmc操作_android uboot中的mmc命令
一:mmc的命令如下: 1:对mmc读操作 mmc read addr blk# cnt 2:对mmc写操作 mmc write addr blk# cnt 3:对mmc擦除操作 mmc erase ...
- uboot环境下mmc操作_uboot mmc命令详解
uboot mmc命令详解 一:mmc的命令如下: 1:对mmc读操作 mmc read addr blk# cnt 2:对mmc写操作 mmc write addr blk# cnt 3:对mmc擦 ...
- redis持久化策略梳理及主从环境下的策略调整记录
转载自 https://www.cnblogs.com/kevingrace/p/6266319.html redis是一个支持持久化的内存数据库,也就是说redis需要经常将内存中的数据同步到磁盘来 ...
- opencv在python环境下的安装_关于python环境下的opencv安装
吐槽: 这一天我终于记起了这个博客.今天搞python环境下的opencv,又弄了一天,很烦躁.之前配置VS的opencv也是花了好久的时间,然后突然发现之前记录在电脑上的文档都找不到了,于是决定还是 ...
最新文章
- win7下的IP-主机名映射
- unity中使用自定义shader进行光照贴图烘培无法出现透明度的坑爹问题
- php 其他格式数据与数组互转
- Nginx-04:Nginx配置实例之反向代理1
- Mongodb部署及使用
- Ubuntu安装中文语言包
- jzoj1282-资源勘探【统计】
- ccf 智能运维 裴丹_智能运维 聊一聊实时计算系统
- 一步步学习SPD2010--附录B--创建新的批准流程
- 基于51单片机+DS1302时钟模块+LCD1602显示
- 用canvas画出可爱的哆啦A梦
- 车牌字符识别LPRNet:License Plate Recognition via Deep Neural Networks
- windows10专业版安装详细教程
- 使用Bugzilla,你肯定会遇到的坑。
- 数字中国 · 青云科技:数字化转型过程中企业如何用好云计算?
- 苹果电脑装Windows7系统U盘启动盘制作教程
- 美团开放平台品牌商接口对接步骤(Java)
- 震坤行工业超市研发效能提升之路 | 云效
- 恐鬼症(Phasmophobia)联机版
- 技术人员如何从外包开始自己的事业
热门文章
- python爬虫网络请求超时是什么意思_爬虫请求超时设置
- sql中如何统计各种零件的总数量_如何应用GOF设计模式中的构建者模式创建复合对象实例...
- jemter安装Transactions per Second和Response Times Over Time插件
- 关于静态局部全局变量
- ARM 之三 Keil uVision4、Keil uVision5、Keil C51同一系统下的共存
- 算法练习day18——190409(Manacher)
- java城市公交查询系统案例_013JAVA.JSP城市公交查询系统.zip
- gps数据处理matlab,基于Matlab的数据处理方法在GPS高程拟合中的应用
- php+html5+jquery断点续传_PHP学习路线:PHP从入门到精通教程
- xlsx to html c,js-xlsx使用