RAM的原理简单学习

DDR是RAM的一种,RAM常见的类型有SRAM,SDRAM,DDR他们的共同特点是,随机存储意味着读写速度快,掉电后数据丢失,所以常用来存储程序中的变量。

SRAM

静态随机存储器英文是static random-access memory 就是保持上电就可以保存数据而不需要刷新。数据线和地址线分离以IS62WV51216这个芯片为例,他数据位宽为16,大小为1MB,地址线宽是19。所以可以访问的空间大小就是2的19次方即524288=512KB,然后数据线是16位了,所以512KB*2 就是这个芯片的全部容量。然后在加上一些必要的控制线比如片选,字节选择等就可以完成读写控制,他的特点是不需要刷新读写速度快,但是价格高STM32单片机内部的RAM就是这种的。

SDRAM

同步动态随机存储器英文是 synchronous Dynamic random access memory ,他就是为了解决SRAM的成本高的问题而被发明出来的,同步则说明SDRAM工作时需要时钟线,动态是因为需要不断的刷新从而避免数据丢失。他的特点是集成度高,功耗低,成本低,适合做大容量存储。他的发展过程是SDRAM,DDR SDRAM,DDR2 SDRAM,DDR3 SDRAM,DDR4 SDRAM 。同样本次也找一个芯片来学习,W9825G6KH为例,他是一个16bit位宽的32M的SDRAM,速度常见为200Mhz。SDRAM 的组成就相对复杂一些。

CLK:时钟

CKE:时钟使能

CS:片选

RAS;行选通

CAS:列选通

WE:写势能

A0-A12:地址线,其中A10比较特殊是预充电:关闭打开的行准备新的行。

BANK:SDRRAM多是由多个bank组成的,常见由2,4,8等,当前新有4个bank所以他有两个bank选择线BS0和BS1.

D0-D15:数据线

U/L DQM:高低字节选择,如果数据线是8bit宽就不需要。

DDR就是SDRAM的升级版本,工作原理相同,但不仅在时钟频率上提高,而写在一个时钟周期传输两次数据即上升沿和下降沿都传输数据。这就是预取2bit随着技术的发展预取已经可以在DDR3的时候做到8bit,所以对于速度的提高是成倍的。这里就不深究其实现原理。

这里主要就其寻址方式进行分析学习一下,同SDRAM一样DDR也是将地址线分为行和列地址通过行和列宣统信号来决定。就那当前举例的芯片来说,他讲地址线中的全部作为行地址而A0-A8作为列地址,所以可以寻址的空间就是2^13*2^9=4194304=4MB,数据位宽为2字节16bit所以真实可以寻址的空间是8M,然后这个芯片的总存储容量是32m,所以这里就是bank的作用了,前面的地址线寻址范围实际上是一个bank的空间,再加上bank选择线2^2=4  所以最后可以寻址的空间就是8*4 = 32M 的空间了。

Tiny210 的DDR配置

我的板子是一个比较早的友善之臂的tiny210加他自家的TinySDK底板,不过DDR在核心板上所以核心板一样的原理都一样。核心板上一共有四颗DDR芯片型号为K4T1G084QQ-HCE6 ,通过查看手册知道这个芯片的是一个8bank的128M的内存芯片,具体的DDR初始化相关的参数配置细节这里不看了,主要看一下DDR的寻址配置。

这个芯片的地址线是A0-A13一共14条地址线其中行地址占全部地址线,列地址为A0-A9共10条,数据线宽为8bit。所以通过前面的原理可以知道他的寻址空间是 2^14*2^10*8=134217728就是128Gb所以和芯片的大小刚刚好相同。现在来看友善的电路连接方式:

从图中可以看到友善采用的方式是将8片的数据脚并在一起从而组成一个数据位宽为32位的数据接口,所以最后地址线的寻址只需要1G/4=128M的寻址空间就可以完成整个板载内存的寻址访问。现在看来虽然很清晰但是刚开始配置这一块的时候还是迷茫了几个小时,最后没办法先去简单看了SDRAM的寻址原理之后在来看这儿就好多了。 首先要排除原理图中的ADDR14这个的影响,因为这个地址线是预留给2G的硬件的。

通过芯片这部分的原理图可以看到,他将DDR芯片的bank脚B2接在了SOC的DDR控制器的片选脚Xm1CSn1/BA2上,而芯片的真正片选脚接在了Xm1CSn0上,所以这样看来应该是设计把两种方案,一是将四片DDR准备让控制器作为两片256的内存在驱动了,第二是作为一个DDR芯片来驱动此时这个脚就做BA2使用,在我自己调试这一部分时还是花了些时间搞明白这一点的。所以目前对于SOC的DDR控制器而言外部应该是接了32位数据位宽的4 bank的DDR芯片两片或者32位宽的8bank芯片;在DDR控制器看来是这样的外部的内存应该是数据位宽32bit,行地址14bit,列地址10bit,四个bank的芯片2片或者行地址14bit,列地址10bit,八个bank的芯片1片;当作为两片DDR内存时一个芯片的寻址范围就是2^14*2^10*4*4=268435456就是256MB,其中第一个4表示有4个bank,而后面的4 因为现在的数据线位32bit就是四个字节了,最后整个个SDRAM 的寻址空间就是256Gx2=512M;其次是 2^14*2^10*4*8 = 536890912即512M。其中第二种就是我目前U-boot的上512GB的DDR的配置方案了。说道这里的吐槽一下友善的DDR的裸机例程太坑了,虽然注释已经写了提供的历程不是他们的最后u-boot中的初始化配置方案,但是他的配置代码由多余的就不说了,还只是初始化了128M的内存空间,一开始以为大小最起码是正确的可能和他们真正用到u-boot中的初始化比稳定性差一点,所以我在移植u-boot时在代码重定向的地址就超过了128M所以就跑到了未初始化的地址范围外了,然后直接死掉这个问题查的我好苦最后才发现是给的DDR例程初始化只能128M内的空间可以正常使用。

最后来看一下代码的配置并验证一下,这里也是只重点看DRAM控制器的配置部分。参考三星的手册的部分我先在下面贴出来

s5p210_mem_init:

    @ 1. DMC0 Drive Strength (Setting 2X)
ldr r0, =S5PC100_GPIO_BASE
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, [r0, #MP1_7DRV_SR_OFFSET]
ldr r1, =0x00002AAA
str r1, [r0, #MP1_8DRV_SR_OFFSET] @ 2. ?????PHY DLL
ldr r0, =APB_DMC_0_BASE
@step 3: PhyControl0 DLL parameter setting, manual 0x00101000
ldr r1, =0x00101000
str r1, [r0, #DMC_PHYCONTROL0]
@PhyControl1 DLL parameter setting, LPDDR/LPDDR2 Case
ldr r1, =0x00000086
str r1, [r0, #DMC_PHYCONTROL1] @step 2: PhyControl0 DLL on
ldr r1, =0x00101002
str r1, [r0, #DMC_PHYCONTROL0]
@step 4: PhyControl0 DLL start
ldr r1, =0x00101003
str r1, [r0, #DMC_PHYCONTROL0] find_lock_val:
@Loop until DLL is locked
ldr r1, [r0, #DMC_PHYSTATUS]
and r2, r1, #0x7
cmp r2, #0x7
bne find_lock_val @Force Value locking
and r1, #0x3fc0
mov r2, r1, LSL #18
orr r2, r2, #0x100000
orr r2 ,r2, #0x1000
orr r1, r2, #0x3
str r1, [r0, #DMC_PHYCONTROL0] @ 3. ?????DMC0
@step 5: ConControl auto refresh off
ldr r1, =0x0FFF2010
str r1, [r0, #DMC_CONCONTROL]
@step 6: MemControl BL=4, 1 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off
@burst 4, num_chip 1 dw=32,type ddr2 ,PALL 0
@ 0x00202400 0x00212400
@以上内容全部是参考网上的三星参考代码部分初始化的,一下才是我修改的
@解释:
@最低8个bit的00
@关闭动态时钟
@关闭power down 这部分都是降低功耗才会考虑的
@ 4 我的DDR芯片是DDR2
@ 2 前面说了用4个8bit组成了32bit数据宽度
@ 0 四片等效成一片 前面也说了
@ 2 根据手册只能是2
ldr r1, =0x00202400
str r1, [r0, #DMC_MEMCONTROL]
@step 7: MemConfig0 256MB config, 8 banks,Mapping Method[12:15]0:linear, 1:linterleaved, 2:Mixed
@解释:
@ 3 前面说了这个型号的DDR是内部由8个bank的
@ 2 row地址宽14
@ 3 col地址宽10
@ 0 线性地址
@ E0 不可用地址空间的掩码,手册中说如果你是F8则寻址空间就是0~0x07ffffff 很清楚把,
所以我这里512M就是E0 就是0~0x1fffffff
@ 20 这一片内存的基地址手册可以看出如果为20则就是0x20000000 所以DMC0上就是刚刚好全部映射20000000~3fffffff
ldr r1, =0x20E00323
str r1, [r0, #DMC_MEMCONFIG0]
@MemConfig1 如果等效为两颗芯片,才需要配置第二个芯片
@解释:
@ 3 前面说了这个型号的DDR是内部由8个bank的,这里却配置为4个bank其实就是
前面说的他巧用了一条片选线用来作为bank的第三条线
@ 2 row地址宽14
@ 3 col地址宽10
@ 0 线性地址
@ F0 不可用地址空间的掩码,手册中说如果你是F8则寻址空间就是0~0x07ffffff 很清楚把,所以我这里256M就是F0
@ 40 这一片内存的基地址手册可以看出如果为40则就是0x40000000加上我前面就是0x3fffffff 这里就是从RAM1的地址空间开始映射则就是
@ldr r1, =0x40F00323
@str r1, [r0, #DMC_MEMCONFIG1]
@以下内容全部是参考网上的三星参考代码部分初始化的,一上才是我修改的
@step 8:PrechConfig
ldr r1, =0xFF000000
str r1, [r0, #DMC_PRECHCONFIG]
@step 9:TimingAref 7.8us@133MHz=1038(0x40E), 100MHz=780(0x30C), 20MHz=156(0x9C), 10MHz=78(0x4E)
ldr r1, =DMC0_TIMINGA_REF
str r1, [r0, #DMC_TIMINGAREF]
@TimingRow for @200MHz
ldr r1, =DMC0_TIMING_ROW
str r1, [r0, #DMC_TIMINGROW]
@TimingData CL=4
ldr r1, =DMC0_TIMING_DATA
str r1, [r0, #DMC_TIMINGDATA]
@TimingPower
ldr r1, =DMC0_TIMING_PWR
str r1, [r0, #DMC_TIMINGPOWER] @ 4.DDR2 DRAM
@DirectCmd chip0 Deselect
ldr r1, =0x07000000
str r1, [r0, #DMC_DIRECTCMD]
@step 16:DirectCmd chip0 PALL
ldr r1, =0x01000000
str r1, [r0, #DMC_DIRECTCMD]
@step 17:DirectCmd chip0 EMRS2
ldr r1, =0x00020000
str r1, [r0, #DMC_DIRECTCMD]
@step 18:DirectCmd chip0 EMRS3
ldr r1, =0x00030000
str r1, [r0, #DMC_DIRECTCMD]
@step 19:DirectCmd chip0 EMRS1 (MEM DLL on, DQS# disable)
ldr r1, =0x00010400
str r1, [r0, #DMC_DIRECTCMD]
@step 20:DirectCmd chip0 MRS (MEM DLL reset) CL=4, BL=4
ldr r1, =0x00000542
str r1, [r0, #DMC_DIRECTCMD]
@DirectCmd chip0 PALL
ldr r1, =0x01000000
str r1, [r0, #DMC_DIRECTCMD]
@DirectCmd chip0 REFA
ldr r1, =0x05000000
str r1, [r0, #DMC_DIRECTCMD]
@DirectCmd chip0 REFA
ldr r1, =0x05000000
str r1, [r0, #DMC_DIRECTCMD]
@DirectCmd chip0 MRS (MEM DLL unreset)
ldr r1, =0x00000442
str r1, [r0, #DMC_DIRECTCMD]
@DirectCmd chip0 EMRS1 (OCD default)
ldr r1, =0x00010780
str r1, [r0, #DMC_DIRECTCMD]
@DirectCmd chip0 EMRS1 (OCD exit)
ldr r1, =0x00010400
str r1, [r0, #DMC_DIRECTCMD]
@ConControl auto refresh on
ldr r1, =0x0FFF2030
str r1, [r0, #DMC_CONCONTROL]
@PwrdnConfig
ldr r1, =0xFFFF00FF
str r1, [r0, #DMC_PWRDNCONFIG]
@MemControl BL=4, 1 chip, DDR2 type, dynamic self refresh, force precharge, dynamic power down off
ldr r1, =DMC0_MEMCONTROL
str r1, [r0, #DMC_MEMCONTROL] mov pc, lr

最后DDR的寻址范围就是0x20000000-0x40000000共512M的空间,采用间歇的四个点128M 256M  348M这几个点写入4K的数据再读出来验证是没有问题的,所以证实初始化是没有问题的。有空了在事实第二种等效成为两片芯片的情况配置一下试试。

有空试了一下,不成立最后分析原因,是因为硬件连接的方式只能支持这种配置,因为电路上将DDR芯片的片选接在了CS0上,如果配置为两片芯片,那么最终的后果就是只能访问256M的存储空间,因为配置成两片模式在访问第二片DDR的地址时,内存控制器就将片选脚失能了,此时DDR是无法访问的所以前面说的等效两片DDR的配置方式不成立。

u-boot 移植 --->4、Tiny210核心板的DDR初始化下详解的更多相关文章

  1. WebService核心文件【server-config.wsdd】详解及调用示例

    WebService核心文件[server-config.wsdd]详解及调用示例 作者:Vashon 一.准备工作 导入需要的jar包: 二.配置web.xml 在web工程的web.xml中添加如 ...

  2. ES6,ES2105核心功能一览,js新特性详解

    ES6,ES2105核心功能一览,js新特性详解 过去几年 JavaScript 发生了很大的变化.ES6(ECMAScript 6.ES2105)是 JavaScript 语言的新标准,2015 年 ...

  3. 【docker-compose】使用docker-compose部署运行spring boot+mysql 【处理容器的时区问题】【详解】【福利:使用docker-compose构建 wordpress+mysql】

    ==================================================================================================== ...

  4. Spring Boot的前世今生以及它和Spring Cloud的关系详解。

    要了解Spring Boot的发展背景,还得从2004年Spring Framework1.0版本发布开始说起,不过大家都是从开始学习Java就使用Spring Framework了,所以就不做过多展 ...

  5. Spring Boot 2 中的默认日志管理与 Logback 配置详解

    Spring Boot在所有内部日志中使用Commons Logging,但是对底层日志的实现是开放的.在Spring Boot生态中,为Java Util Logging .Log4J2 和Logb ...

  6. Nginx的特性与核心类别及配置文件和模块详解

    1.root path 设置web资源路径,用于指定请求的根文档目录,从根开始匹配 root:root/URI 2.alias path 指定路径别名,只能用于location中,从最后一个/开始匹配 ...

  7. Spring Boot源码(六):Bean的创建详解

    继续之前的项目: People加上无参构造方法: @Component public class People { // private User user; public People(){ Sys ...

  8. Android 核心分析 之八Android 启动过程详解

    Android 启动过程详解 Android从Linux系统启动有4个步骤: (1) init进程启动 (2) Native服务启动 (3) System Server,Android服务启动 (4) ...

  9. Hibernate入门核心配置文件和orm元数据配置文件详解

    框架是什么? 框架是用来提高开发效率的 封装了一些功能,我们需要使用这些功能时,调用即可,不用手动实现 所以框架可以理解为一个半成品的项目,只要懂得如何使用这些功能即可 Hibernate是完全面向对 ...

随机推荐

  1. Java语法糖详解

    语法糖 语法糖(Syntactic Sugar),也称糖衣语法,是由英国计算机学家 Peter.J.Landin 发明的一个术语,指在计算机语言中添加的某种语法,这种语法对语言的功能并没有影响,但是更 ...

  2. Java并发组件三之Semaphore

    使用场景:常用于使用有限的资源,限制线程并发的最大数量.默认情况下,信号量是非公平性的(先等待先执行为公平.类似于买东西的时候大家排队付款,先来的先付款是公平的.但是这时候有人插队,那就是非公平的)设 ...

  3. Trove自动钓鱼脚本(国际服

    #WinActivateForce ; Script config. Do NOT change value here, might working inproperly! global Versio ...

  4. Property attribute.

    class property(object): """ Property attribute. fget function to be used for getting ...

  5. 406 UDP协议是面向非连接的协议 Keep-Alive

    HTTP The Definitive Guide   Table 3-1. Common HTTP methods   Method Description Message body?   GET ...

  6. LeetCode上并发题目无Go版本:台湾同胞试水 — 交替打印FooBar

    https://mp.weixin.qq.com/s/I5va3PI1oGIj8R_n3Nw2yw

  7. 分布式跟踪的一个流行标准是OpenTracing API,该标准的一个流行实现是Jaeger项目。

    https://github.com/jaegertracing/jaeger https://mp.weixin.qq.com/s/-Tn2AgyHoq8pwMun8JHcGQ Jaeger的深入分 ...

  8. IntelliJ Idea 解决 Could not autowire. No beans of 'xxxx' type found 的错误提示

    IntelliJ Idea 解决 Could not autowire. No beans of 'xxxx' type found 的错误提示哈,在使用 @Autowired 时,今天又遇一坑,这俩 ...

  9. XCTF-黑客精神

    杂言 前段时间键盘坏了,电脑硬盘也坏了,买东西装系统再偷个懒放了一周左右假.期间学习巩固了一下安卓开发的知识.用了固态才知道什么叫纵享丝滑,当初就不该省这个钱. 前期工作 查壳,无.运行,点击按钮就跳 ...

  10. Java通过openOffice实现word,excel,ppt转成pdf实现在线预览

    Java通过openOffice实现word,excel,ppt转成pdf实现在线预览 一.OpenOffice 1.1 下载地址 1.2 JodConverter 1.3 新建实体类PDFDemo ...