SD卡驱动开发心得体会

简介: 最近在负责SD卡驱动的开发移植工作,支持vfat文件系统,现在谈一下开发心得吧!         SD卡高度集成闪存,具备串行和随机存取能力。可以通过专用优化速度的串行接口访问,数据传输可靠。

最近在负责SD卡驱动的开发移植工作,支持vfat文件系统,现在谈一下开发心得吧!

 

      SD卡高度集成闪存,具备串行和随机存取能力。可以通过专用优化速度的串行接口访问,数据传输可靠。接口允许几个卡垛叠,通过他们的外部连接。接口完全符合最新的消费者标准,叫做SD卡系统标准,由SD卡系统规范定义。 SD卡系统是一个新的大容量存储系统,基于半导体技术的变革。它的出现,提供了一个便宜的、结实的卡片式的存储媒介,为了消费多媒体应用。SD卡可以设计出便宜的播放器和驱动器而没有可移动的部分。一个低耗电和广供电电压的可以满足移动电话、电池应用比如音乐播放器、个人管理器、掌上电脑、电子书、电子百科全书、电子词典等等。

 

一、SD Bus Protocol

  SD总线有两种SD Bus和SPI Bus。笔者以SD Bus为例:

  SD Bus由CLK,CMD,DAT0-3,VDD,VSS组成。SD bus模式下的命令和数据流都有一个起始位和一个停止位。命令格式固定为48bits,(start bit 固定为‘0’)+ (transmitter bit为‘1’)+(command & address or parameter)+(CRC7)+(end bit '1')。

   而响应格式有两种,看命令响应的类型,R1,R3,R6的响应格式为,(start bit 固定为‘0’)+ (transmitter bit为‘0’)+(command & status(R1),OCR(R3)or RCA(R6))+(CRC7)+(end bit '1')。R2的响应格式为,(start bit 固定为‘0’)+ (transmitter bit为‘0’)+(CID or CSD))+(CRC7)+(end bit '1')。

 

二、SD卡初始化处理

  首先初始化一下controller,比如fifo,dma模式,enbale位等。初始化好了controller后,需要设置一下啊通讯时钟,设好后就可以去跟SD memory card去做沟通了。这个过程都是通过发送CMD来完成的,首先读取controller的detect寄存器,看有没有卡插入,有插入的情况下才发送CMD0去reset card to idle state,再发送CMD8,把controller提供的电压信息和check pattern发送给SD卡,这一步成功就可以发送ACMD41去获取SD OCR信息,这一步需要把controller的capacity support info和要求SD发送它的OCR给controller,这一步成功后,就可以接着发送CMD2去读SD的CID信息,再发CMD3去读SD卡的RCA,再发CMD9去读SD卡的CSD,这个很重要,卡的容量信息在这里面,再设置通讯bus的宽带,有1线跟4线的区别,最后把CLK设置高一些,可以为25MHZ,这样读数据就快很多。到此为止,卡的初始化工作已经完成,可以进行读写。

 

三、如何判断SD卡是standard SD card还是high capacity SD card

    在初始化过程中,发送ACMD41后,获取的SD OCR寄存器信息,在它的第30bit也就是CCS(card capacity status),如果该位为1,则表明是high capacity SD card,为0的话就是standard SD card。

 

四、SD信息注册给VFAT

   由于需要读取SD卡中vfat文件系统中的文件,因此我们需要把SD卡read操作函数指针、设备类型、容量信息、CID信息注册给fat部分。就是这个结构static block_dev_desc_t mmc_blk_dev = {0};

 

 mmc_blk_dev.if_type = IF_TYPE_MMC;
 mmc_blk_dev.part_type = PART_TYPE_DOS;
 mmc_blk_dev.dev = 0;
 mmc_blk_dev.lun = 0;
 mmc_blk_dev.type = 0;

 mmc_blk_dev.blksz = STORAGE_BLOCK_SIZE;
 /*mmc_blk_dev.lba = 0x400000; get from CSD info */
 mmc_blk_dev.removable = 0;
 mmc_blk_dev.block_read = mmc_block_read;
 ret = fat_register_device(&mmc_blk_dev, 1);

 

把该结构填好后,调用fat_register_device(&mmc_blk_dev, 1)注册。

 

五、uboot下FAT

    uboot下支持fat12、16、32。在 fat_register_device这个接口中有一个bug,用mkdosfs格式化的SD卡,其生成的MBR信息跟在PC上不一样。fat.c中的代码片段&buffer[DOS_FS_TYPE_OFFSET]起始的3个字节数据是否为“FAT”来判断其文件系统是不是FAT格式的,DOS_FS_TYPE_OFFSET为0x36,但是用mkdosfs格式化的SD卡,其生成的MBR信息,其"FAT"描述在偏移0x52处,所以在fat_register_device()接口中需要做兼容性调整。这个小bug可以从static int
read_bootsectandvi(boot_sector *bs, volume_info *volinfo, int *fatsize)这个接口的实现里看出。在这个
read_bootsectandvi(boot_sector *bs, volume_info *volinfo, int *fatsize)接口中已经做了兼容,在boot sector中fat_length,如果为0的话,就做了增加偏移量,用mkdosfs格式化的SD卡,其生成的MBR信息中fat_length恰恰为0.

 

六、总结

   SD卡驱动开发并不复杂,在写代码之前先把SD卡协议搞清楚,再把controller的寄存器意思搞明白,就可以动手干活了。调试是痛苦滴,SD work成功了,也会带来一丝喜悦!

 

 

 

 

目录
相关文章
|
8月前
|
监控 安全 Cloud Native
海外泼天流量丨浅谈全球化技术架构
全球化是对技术架构的终极挑战,面临的不仅仅是技术的问题,而是包含了经济、文化等多因素差异的用户关系问题。积极借助遍布全球的云计算基础设施和云原生的架构设计原则,将能更加高效的构建高可用的全球化技术架构,支持全球业务的持续增长。
382 109
|
安全 Linux 数据安全/隐私保护
【SPI协议】了解ARM平台上的SPI的基本应用
【SPI协议】了解ARM平台上的SPI的基本应用
1117 0
|
NoSQL Redis 数据库
Python 数据库开发实战-Mac系统下通过homebrew安装Redis数据库
此文章的前置条件是 “Mac系统已安装过Homebrew”,如果未安装,可访问 “Mac 安装 homebrew 详细教程” 一文,详细介绍Homebrew的用法。利用 “Homebrew” 对 “Redis” 进行安装管理,那是一个方便啊。
|
C语言 固态存储
可变参数宏__VA_ARGS__和...
__VA_ARGS__ 是一个可变参数的宏(gcc支持)。实现思想就是宏定义中参数列表的最后一个参数为省略号(也就是三个点)。这样预定义宏_ _VA_ARGS_ _就可以被用在替换部分中,替换省略号所代表的字符串。
2658 0
|
Linux Shell
内核调试之devmem直接读写寄存器
内核调试之devmem直接读写寄存器
|
机器学习/深度学习 运维 Python
从零开始实现VAE和CVAE
扩散模型可以看作是一个层次很深的VAE(变分自编码器),前向(forward,或者译为正向)的过程,通过在多个尺度上添加噪声来逐步扰乱数据分布;然后是反向的过程,去学习如何恢复数据结构,上述的破坏和恢复过程分别对应于VAE中的编码和解码过程。所以VAE是一个重要的概念需要掌握,本文将用python从头开始实现VAE和CVAE,来增加对于它们的理解。
270 0
|
缓存 测试技术 芯片
内核笔记](二)——设备树基础
内核笔记](二)——设备树基础
678 0
|
数据采集 Shell 芯片
vxworks的pci设备驱动调试
vxworks的pci设备驱动调试
1039 0
vxworks的pci设备驱动调试
|
IDE Unix Shell
芯驰(E3-gateway)开发板环境搭建以及调试遇到问题的解决
芯驰(E3-gateway)开发板环境搭建以及调试遇到问题的解决