锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

外设篇:SD卡等外存设备

时间:2023-02-12 20:30:00 mlc连接器mmc集成电路

介绍主流存储设备

内存和外存的区别:一般是RAM(random access memory,随机访问存储器的特点是读写任何字节,丢失电源)称为内存,并将其放在手中ROM(read only memory,只读存储器,类似Flash SD卡等,用来存放东西,掉电不丢失,不能随机访问地址,只能以块为单位访问)称为外存

软盘,硬盘,光盘,CD、磁带
(1)存储原理多为磁存储,缺点是读写速度和可靠性。优点是技术成熟,价格便宜。广泛应用于桌面电脑,几乎不用于嵌入式设备。
(2)现代存储的发展方向是Flash存储,闪存技术是利用电气原理存储1和0,从而制成存储设备。因此,闪存设备没有物理运动(硬盘中的磁头),因此读写速度可以快,没有物理损耗。

纯粹的Flash:NandFlash、NorFlash
(1)这些是最早、最原始的Flash颗粒形成芯片。也就是说。NandFlash、NorFlash芯片只为存储单元做了最基本的读写界面,然后要求外部SoC来提供Flash读写控制器以和Flash读写时序。
(2)缺陷:1。读写界面的顺序比较复杂。2.内部无碎片处理机制,需要SoC自己来管理Flash坏块;3.各厂家Flash接口不一致,甚至同一厂家的不同型号和系列Flash界面不一致,导致产品升级麻烦。
(3)NandFlash分MLC和SLC两种。SLC技术早,可靠性高,缺点是容量不大(或者容量太贵,一般SLC Nand都是512MB以下);MLC技术相对较新,不成熟,可靠性差,优点是容量可以大而便宜,现在基本发展MLC技术。SLC MLC_百度百科

SD卡、MMC卡、MicroSD、TF卡
(1)这些卡其实是内部的Flash与直接颗粒相比,存储颗粒Nand芯片有统一的外包装和接口。
(2)卡有统一的标准,比如SD卡都是遵照SD发布规范。规定了这些规范SD读写速度、读写界面顺序、读写命令集、卡尺寸、引脚数量和定义。这样做的好处是不同的制造商SD卡可以通用。

iNand、MoviNand、eSSD
(1)手机、相机等电子产品,往年的趋势是使用SD卡/TF扩等扩展存储容量;但近年来的趋势是直接内置大容量Flash芯片而不是外部扩展卡。
(2)外部扩展卡长时间接触不良可能导致不可靠。
(3)主流发展方向是使用iNand、MoviNand、eSSD(还有其他名称)制作电子产品的存储芯片。这些东西的本质是NandFlash,内部由Nand存储颗粒组成,然后集成块设备管理单元,集成SD卡为代表的各种卡的优势和原始的NandFlash芯片的优点。
优点:1、向SD卡学习,有统一的接口标准(包括引脚定义、物理包装、接口顺序)。2.原始Nand学习,以芯片而不是卡片的方式发布;3.内置Flash管理模块提供了坏块管理等功能Nand易于管理。

SD卡的特点和背景知识
SD卡和MMC卡的关系
(1)MMC标准比SD标准早,SD标准兼容MMC标准。
(2)MMC卡可以被SD读卡器读写,而SD卡不可以被MMC读卡器读写。

SD卡和Nand、Nor等Flash芯片差异
(1)SD卡/MMC卡等卡类接口标准统一,Nand芯片没有统一的标准(每种产品都会有差异)
SD卡与MicroSD的区别
(1)体积大小不同,传输原理完全相同。
SD卡与TF卡的区别
(1)外观上,SD卡大而TF卡小;用途上,SD用于数码相机等TF广泛用于手机,GPS等;
(2)时间,SD卡1999年推出,TF卡于2004年推出;SD卡由日本松下、东芝和美国SanDisk和TF卡由Motorola与SanDisk共同推出。
(3)SD卡有写保护TF卡没有,TF卡可以通过卡套转换成SD卡使用。

SD卡的编程接口
SD卡的物理接口
(1)SD卡由9个针脚与外界物理连接,9个脚有2个地,1个电源,6个信号线。

更多信息:SD卡_百度百科

SD协议与SPI协议
(1)SD卡与SRAM/DDR/SROM等等:SRAM/DDR/SROM这种存储芯片是总线式的,只要连接初始化,就可以通过SoC直接访问地址;但是SD卡不能通过接口直接访问地址,其访问需要按照一定的接口协议(时间序列)进行。
(2)SD虽然卡只有一个物理接口,但它支持两种读写协议:SD协议和SPI协议。

SPI协议特点(低速,接口操作时间简单,适合单片机)
(1)SPI协议是单片机中广泛使用的通信协议,不是为了SD卡是专门发明的。
(2)SPI协议相对SD协议速度相对较低。
(3)SD卡支持SPI协议是为了方便单片机的使用。

SD协议特征(高速、接口时间复杂,适合SDIO接口的SoC)
(1)SD协议是专门用于和解的SD卡通信的。
(2)SD协议要求SoC中有SD要求控制器高速运行SoC主频不能太低。

S5PV210的SD/MMC控制器

(1)数据手册Section8.7,为SD/MMC介绍控制器。SD/MMC CONTROLLER
(2)SD存储单元除外Flash外,还有SD卡管理模块,我们SoC和SD卡通时,9针引脚SD协议/SPI协议向SD卡管理模块发送命令、时钟、数据等信息SD卡返回信息SoC来交互。工作中的每一项任务(如初始化)SD比如读一块,比如写,比如擦除····)都需要一定的时间序来完成(所谓时间序是先向的SD卡发送xx命令,SD卡回xx消息,然后再去SD卡发送xx命令····)

SD卡的时钟是自动的,不需要我们手动配置。

SD我们通常不需要写一些代码,制造商或UBOOT中都已经给我们写好了,我们知道他是怎么写的,以后会做细微的调整。

S5PV210的SD卡启动详解1
SoC为何要支持SD卡启动
(1)一般原则是:SoC支持的启动方式越多,以后使用越方便,用户的选择性越大,SoC适用面越广。
(2)SD卡有一些好处,比如不借用专用烧录工具(类似)Jlink)的情况下对SD刷卡,然后刷卡SD卡插入卡槽,SoC既可启动;例如,可以使用;SD卡启动量产刷机(量产卡)。像我们X210开发板,板贴好,内部iNand是空的,此时直接启动没有启动;板出厂前官方刷机时,预先插入量产卡SD卡槽,然后打iNand因为这个时候iNand是空的,所以第一次启动失败,会转向第二次启动,从外部SD2通道的SD卡启动了。启动后,将执行刷机操作iNand进行刷机,刷机完成后自动重启(这回重启时iNand中已经有image所以可以启动)。刷机完成后SD拔掉量产卡,烧机48小时,无死机即可装箱送货。

SD卡启动的难点在哪里?(SRAM、DDR、SDCard)
(1)SRAM、DDR总线访问,SRAM可直接使用,无需初始化。DDR使用前需要初始化,但总之,CPU可以直接和SRAM/DRAM打交道;而SD卡需要时序访问,CPU不能直接和SD卡打交道;NorFlash总线访问可以读取,所以Norflash启动非常简单,可以直接启动,但是SD/NandFlash不行。
(2)以前只有Norflash台式机笔记本可作为启动介质BIOS就是Norflash做的。后来三星在2440中使用了它SteppingStone的技术,让Nandflash也可以作为启动介质。SteppingStone(翻译为启动基石)技术SoC内部内置4KB的SRAM,然后开机时SoC根据OMpin如果是,判断用户设置的启动模式NandFlash启动,则SoC启动部分的硬件直接从外部NandFlash中读开头4KB到内部SRAM作为启动内容。
(3)启动基石技术进一步发展,完善6410芯片,完全成熟210芯片。210中有96KB的SRAM,并且有一段iROM代码作为BL0,BL0再去启动BL1(210中的BL2440中也有0件事要做,但当时是硬件自动完成的,系统没有210中那么详细)。

S5PV回顾210的启动过程
(1)210启动首先执行内部iROM(也就是BL0),BL0会判断OMpin决定从哪个设备开始,如果启动设备是SD卡,则BL0会从SD卡读取前16KB(不一定是16,反正16是工作)到SRAM开始执行(这部分是BL1,这就是steppingstone技术)
(2)BL执行后剩下的就是软件了,SoC别再担心了。

SD卡启动流程(bin文件小于16KB时和大于16KB时)
(1)启动的第一种情况是整个镜像大小小于16KB。这个时候相当于我的整个镜像。BL1被steppingstone直接进行硬件加载。
(2)启动的第二种情况是整个镜像大小大于16KB。(只要大于16KB,哪怕是17KB,或者是700MB都是一样的)此时整个镜像要分为两部分:第一部分16KB大小,第二部分是剩下的大小。然后作为第一部分BL1.负责去初始化DRAM加载第二部分DRAM中去执行(uboot就是这样做的)。

最重要但隐含未说的话
(1)问题:iROM怎么读?SD卡/NandFlash的?
(2)三星在iROM一些代码提前内置到初始外部SD卡/NandFlash,并内置各种读取SD卡/NandFlash的代码在iROM中。BL0执行是通过调用这些来执行的device copy function来读取外部SD卡/NandFlash中的BL1的。

p>S5PV210的SD卡启动详解2
SoC支持SD卡启动的秘密(iROM代码)
(1)三星系列SoC支持SD卡/NandFlash启动,主要是依靠SteppingStone技术,具体在S5PV210中支持steppingstone技术的是内部的iROM代码。
再看iROM application note:block device copy function

 

扇区和块的概念
(1)早期的块设备就是软盘硬盘这类磁存储设备,这种设备的存储单元不是以字节为单位,而是以扇区为单位。磁存储设备读写的最小单元就是扇区,不能只读取或写部分扇区。这个限制是磁存储设备本身物理方面的原因造成的,也成为了我们编程时必须遵守的规律。
(2)一个扇区有好多个字节(一般是512个字节)。早期的磁盘扇区是512字节,实际上后来的磁盘扇区可以做的比较大(譬如1024字节,譬如2048字节,譬如4096字节),但是因为原来最早是512字节,很多的软件(包括操作系统和文件系统)已经默认了512这个数字,因此后来的硬件虽然物理上可能支持更大的扇区,但是实际上一般还是兼容512字节扇区这种操作方法。所以,1k有2个block。
(3)一个扇区可以看成是一个块block(块的概念就是:不是一个字节,是多个字节组成一个共同的操作单元块),所以就把这一类的设备称为块设备。常见的块设备有:磁存储设备硬盘、软盘、DVD和Flash设备(U盘、SSD、SD卡、NandFlash、Norflash、eMMC、iNand)
(4)linux里有个mtd驱动,就是用来管理这类块设备的。
(5)磁盘和Flash以块为单位来读写,就决定了我们启动时device copy function只能以整块为单位来读取SD卡。

用函数指针方式调用device copy function
(1)第一种方法:宏定义方式来调用。好处是简单方便,坏处是编译器不能帮我们做参数的静态类型检查。
(2)第二种方法:用函数指针方式来调用。

typedef unsigned int bool;

// 第一种方法:宏定义
#define CopySDMMCtoMem(z,a,b,c,e)(((bool(*)(int, unsigned int, unsigned short, unsigned int*, bool))(*((unsigned int *)0xD0037F98)))(z,a,b,c,e))


// 第二种方法:用函数指针方式调用
typedef bool(*pCopySDMMC2Mem)(int, unsigned int, unsigned short, unsigned int*, bool);


// 实际使用时
pCopySDMMC2Mem p1 = (pCopySDMMC2Mem)0xD0037F98;
p1(x, x, x, x, x);		// 第一种调用方法
(*p1)(x, x, x, x, x);	// 第二种调用方法
*p1(x, x, x, x, x);		// 错误,因为p1先和()结合,而不是先和*结合。

S5PV210的SD卡启动实战

任务:大于16KB的bin文件使用SD卡启动
(1)总体思路:将我们的代码分为2部分:第一部分BL1小于等于16KB,第二部分为任意大小,iROM代码执行完成后从SD卡启动会自动读取BL1到SRAM中执行;BL1执行时负责初始化DDR,然后手动将BL2从SD卡copy到DDR中正确位置,然后BL1远跳转到BL2中执行BL2.
(2)细节1:程序怎么安排?程序整个分为2个文件夹BL1和BL2,各自管理各自的项目。
(3)细节2:BL1中要完成:关看门狗、设置栈、开iCache、初始化DDR、从SD卡复制BL2到DDR中特定位置,跳转执行BL2。
(4)细节3:BL1在SD卡中必须从Block1开始(Block0不能用,这个是三星官方规定的),长度为16KB内,我们就定为16KB(也就是32个block);BL1理论上可以从33扇区开始,但是实际上为了安全都会留一些空扇区作为隔离,譬如可以从45扇区开始,长度由自己定(实际根据自己的BL2大小来分配长度,我们实验时BL2非常小,因此我们定义BL2长度为16KB,也就是32扇区)。


(5)细节4:DDR初始化好之后,整个DDR都可以使用了,这时在其中选择一段长度足够BL2的DDR空间即可。我们选0x23E00000(因为我们BL1中只初始化了DDR1,地址空间范围是0x20000000~0x2FFFFFFF)。

#define SD_START_BLOCK	45
#define SD_BLOCK_CNT	32
#define DDR_START_ADDR	0x23E00000



typedef unsigned int bool;

// 通道号:0,或者2
// 开始扇区号:45
// 读取扇区个数:32
// 读取后放入内存地址:0x23E00000
// with_init:0
typedef bool(*pCopySDMMC2Mem)(int, unsigned int, unsigned short, unsigned int*, bool);

typedef void (*pBL2Type)(void);


// 从SD卡第45扇区开始,复制32个扇区内容到DDR的0x23E00000,然后跳转到23E00000去执行
void copy_bl2_2_ddr(void)
{
	// 第一步,读取SD卡扇区到DDR中
	pCopySDMMC2Mem p1 = (pCopySDMMC2Mem)0xD0037F98);
	
	p1(2, SD_START_BLOCK, SD_BLOCK_CNT, (unsigned int *)DDR_START_ADDR, 0);		// 读取SD卡到DDR中
	// 第二步,跳转到DDR中的BL2去执行
	pBL2Type p2 = (pBL2Type)DDR_START_ADDR;
	p2();
}

代码划分为2部分(BL1和BL2)

BL1中的重定位

BL2远跳转
(1)因为我们BL1和BL2其实是2个独立的程序,链接时也是独立分开链接的,所以不能像以前一样使用ldr pc, =main这种方式来通过链接地址实现远跳转到BL2。
(2)我们的解决方案是使用地址进行强制跳转。因为我们知道BL2在内存地址0x23E00000处,所以直接去执行这个地址即可。


S5PV210的SD卡启动实战2
烧录启动实验
代码分为2部分启动(上一节讲的)的缺陷
(1)代码分为2部分,这种技术叫分散加载。这种分散加载的方法可以解决问题,但是比较麻烦。
(2)分散加载的缺陷:第一,代码完全分2部分,完全独立,代码编写和组织上麻烦;第二,无法让工程项目兼容SD卡启动和Nand启动、NorFlash启动等各种启动方式。


uboot中的做法
(1)第二种思路:程序代码仍然包括BL1和BL2两部分,但是组织形式上不分为2部分而是作为一个整体来组织。它的实现方式是:iROM启动然后从SD卡的扇区1开始读取16KB的BL1然后去执行BL1,BL1负责初始化DDR,然后从SD卡中读取整个程序(BL1+BL2)到DDR中,然后从DDR中执行(利用ldr pc, =main这种方式以远跳转从SRAM中运行的BL1跳转到DDR中运行的BL2)。

再来分析uboot的SD卡启动细节
(1)uboot编译好之后有200多KB,超出了16KB。uboot的组织方式就是前面16KB为BL1,剩下的部分为BL2.
(2)uboot在烧录到SD卡的时候,先截取uboot.bin的前16KB(实际脚本截取的是8KB)烧录到SD卡的block1~bolck32;然后将整个uboot烧录到SD卡的某个扇区中(譬如49扇区)
(3)实际uboot从SD卡启动时是这样的:iROM先执行,根据OMpin判断出启动设备是SD卡,然后从S卡的block1开始读取16KB(8KB)到SRAM中执行BL1,BL1执行时负责初始化DDR,并且从SD卡的49扇区开始复制整个uboot到DDR中指定位置(0x23E00000)去备用;然后BL1继续执行直到ldr pc, =main时BL1跳转到DDR上的BL2中接着执行uboot的第二阶段。

总结:uboot中的这种启动方式比上节讲的分散加载的好处在于:能够兼容各种启动方式。

解决X210开发板的软开关按键问题
X210开发板的软启动电路详解
(1)210供电需要的电压比较稳定,而外部适配器的输出电压不一定那么稳定,因此板载了一个稳压器件MP1482.这个稳压芯片的作用就是外部适配器电压在一定范围内变化时稳压芯片的输出电压都是5V。
(2)MP1482芯片有一个EN(Enable)引脚,这个引脚可以让稳压芯片输出或关闭输出。EN为高电平时有输出电压,EN引脚为低电平时稳压芯片无输出。
(3)两个因素可以影响EN引脚的电平:第一个是POWER按键(SW1),POWER按键按下时EN为高电平,POWER按键弹起时EN为低电平;第二个是POWER_LOCK(EINT0)引脚,这个引脚为POWER_LOCK模式下高电平,则EN为高;若这个引脚为EINT0模式或者为POWER_LOCK模式但输出为低电平,则EN为低。
(4)图中还有EINT1引脚,这个引脚的作用是用来做中断,提供给CPU用来唤醒的。

为什么要软启动
(1)一般的电路设计都是用拨码开关来做电源开关的(打到一侧则接通,打到另一侧则关闭)。这种方式的优点是设计简单,缺点是电路太简单,整个主板要么有电要么没电无法做休眠模式、低功耗模式等。
(2)软启动电路是比较接近于实际产品的,其他开发板的硬开关其实是简化版的,和实际产品还有差异。

开发板供电置原理和分析
(1)软开关在设计时有一个置锁电路,用EINT0(也就是GPH0_2)引脚来控制的。
(2)EINT0这个引脚是有复用设计(两个完全不相干的功能挤在同一个引脚上,同时我们只能让这个引脚用于其中一种功能,这就叫复用)的,一个是GPIO(也就是GPH0_2引脚)、一个是PS_HOLD_CONTROL。(注意:EINT0功能算是GPIO下的一个子功能)
(3)PS_HOLD在Section2.4 Power Management章节下的4.10.5.8节下。
(4)PS_HOLD_CONTROL寄存器(0xE010E81C),共有3个位有用。
bit0, 0表示这个引脚为GPIO功能,1表示这个引脚为PS_HOLD功能
bit9,0表示这个引脚方向为输入,1表示这个引脚方向为输出
bit8,0表示这个引脚输出为低电平,1表示输出为高电平。
分析:我们要使用软启动置锁,则需要将bit0、8、9都置为1即可。

// 第0步:开发板置锁
	// 写法1
	//ldr r0, =0xE010E81C
	//ldr r1, =0x301
	//str r1, [r0]
	// 写法2
	//ldr r0, =0xE010E81C
	//ldr r1, [r0]
	//orr r1, r1, #0x300
	//orr r1, r1, #0x01
	//str r1, [r0]
	// 写法3
	ldr r0, =0xE010E81C
	ldr r1, [r0]
	ldr r2, =0x301
	orr r1, r1, r2
	str r1, [r0]

写代码+实验验证
(1)要想让开发板和普通的开发板一样,一按下按键程序运行后即可松手不会断电,则只要在程序的开头部分添加代码去置锁开关板即可。
(2)置锁代码的方法是:给PS_HOLD_CONTROL寄存器的bit0、8、9均写入1即可。
(3)注意:此时开发板已经置锁,POWER按键已经失效,关机时需要按下复位按键。 

锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章