注:以下内容有参考朱老师物联网大讲堂裸机部分课件
1.SDRAM引入
1.1 常见存储器介绍:
DRAM介绍
同步动态随机存取内存(synchronous dynamic random-access memory,简称SDRAM),有一个同步接口的动态随机存取内存。
DDR:DDR就是DDR SDRAM,是SDRAM的升级版。(DDR:double rate,双倍速度的SDRAM)
DDR有好多代:DDR1 DDR2 DDR3 DDR4 LPDDR
1.2 DRAM特征:
1、中央处理器(CPU)与主机板上的主存储器(SDRAM)存取资料的的时钟(Clock)相同,所以称为同步。
2、容量大、价格低、掉电易失性、随机读写、总线式访问
3、SDRAM/DDR都属于动态内存(相对于静态内存SRAM),都需要先运行一段初始化代码来初始化才能使用
2.硬件电路
SDRAM在系统中属于SoC外接设备(外部外设。以前说过随着半导体技术发展,很多东西都逐渐集成到SoC内部去了。现在还长期在外部的一般有:Flash、SDRAM/DDR、网卡芯片如DM9000、音频Codec。现在有一些高集成度的芯片也试图把这几个集成进去,做成真正的单芯片解决方案。)
SDRAM通过地址总线和数据总线接口(总线接口)与SoC通信。
2.1 内存部分接口框图
单片内存框图
开发板原理图上使用的是K4T1G164QQ,但是实际开发板上贴的不是这个,是另一款。但是这两款是完全兼容的,进行软件编程分析的时候完全可以参考K4T1G164QQ的文档。
全球做SDRAM的厂商不多,二线厂家做的产品参数都是向一线厂家(三星、KingSton)看齐,目的是兼容一线厂家的设计,然后让在意成本的厂商选择它的内存芯片替代一线厂家的内存芯片。SDRAM的这个市场特征就导致这个东西比较标准化,大部分时候细节参数官方(芯片原厂家)都会给你一个参考值。
内存命名规则解读
K4T1G164QE:
K表示三星产品,4表示是DRAM,T表示产品号码,1G表示容量(1Gb,等于128MB,我们开发板X210上一共用了4片相同的内存,所以总容量是128×4=512MB)16表示单芯片是16位宽的,4表示是4bank。
2.2 S5PV210部分的接口框图
2.3 数据手册
2.3.1 S5PV210的数据手册
MEMORY ADDRESS MAP
2.3.2 内存芯片的数据手册
2.4 总结
1、一块内存的数据总线是16位,两块并联得到32位,我们共有4块
2、从芯片名称(K4T1G164QQ)中的1G可知每一块的大小为1Gb,等于128MB,所以我们总共的内存大小为512MB
3、两个内存端口分别连接了两块内存所以各自端口的大小为256MB
由数据手册可知:
DRAM0:内存地址范围:0x20000000~0x3FFFFFFF(512MB),对应引脚是Xm1xxxx
DRAM1: 内存地址范围:0x40000000~0x7FFFFFFF(1024MB),对应引脚是Xm2xxxx
所以内存合法地址是:0x20000000~0x2FFFFFFF(256MB) + 0x40000000~0x4FFFFFFF(256MB)
3.汇编初始化SDRAM实现过程
根据数据手册的步骤对照代码如下(sdram_init.S)
DDR2内存类型的初始化顺序(共28步):
我们以DMC0为例,DMC1同理
1.为了给控制器和内存设备提供稳定的电源,控制器必须断言并保持CKE在逻辑低电平。
然后提供稳定的时钟。注意:XDDR2SEL应该在高位,以保持CKE在低位。
我们的驱动强度设为2X,所以我们就需要将0x0000AAAA写入对应的寄存器
.global sdram_asm_init
sdram_asm_init:
ldr r0, =0xf1e00000
ldr r1, =0x0
str r1, [r0, #0x0] //这部分无相关解释,我们暂且保留
/* DMC0 Drive Strength (Setting 2X) */
ldr r0, =ELFIN_GPIO_BASE // 基地址:0xE0200000
// MP1_0DRV_SR_OFFSET=0x3CC 寄存器中对应0b10,就是2X
ldr r1, =0x0000AAAA
str r1, [r0, #MP1_0DRV_SR_OFFSET]
ldr r1, =0x0000AAAA
str r1, [r0, #MP1_1DRV_SR_OFFSET]
ldr r1, =0x0000AAAA
str r1, [r0, #MP1_2DRV_SR_OFFSET]
ldr r1, =0x0000AAAA
str r1, [r0, #MP1_3DRV_SR_OFFSET]
ldr r1, =0x0000AAAA
str r1, [r0, #MP1_4DRV_SR_OFFSET]
ldr r1, =0x0000AAAA
str r1, [r0, #MP1_5DRV_SR_OFFSET]
ldr r1, =0x0000AAAA
str r1, [r0, #MP1_6DRV_SR_OFFSET]
ldr r1, =0x0000AAAA
str r1