SDRAM:

   原理图如下:

        

jz2440 v3开发板上面用的内存芯片为钰创科技公司生产的EM63A165TS,一片内存大小为32MB大小,一共有两块,共64MB的大小.

SDRAM接的是BANK 6,所以他的起始地址是 0x30000000.

SDRAM的基本寻址关系

SDRAM的存储结构逻辑如上图,  SDRAM内部是一个存储阵列,阵列就如同表格一样,将数据"填进去".和表格的检索原理一样,先指定一个行,再指定一个列,两点确定一个坐标,就可以准确地找到所需要的

单元格,这就是SDRAM寻址的基本原理.这个单元被称为存储单元,这个表格(存储阵列)就是逻辑Bank(就是L-Bank).SDRAM一般含有四个L-Bank.

对SDRAM的访问可以分为如下几个步骤:

  1.CPU发出的片选信号nSCS0有效,它选中SDRAM芯片.

  2.SDRAM有四个L-Bank,需要两根地址线来选中其中的一个,根据开发板的设计, 选用了ADDR24和ADDR25作为L-Bank的选择信号.

  3.对被选中的芯片进行统一的行/列(存储单元)寻址.

    根据SDRAM芯片的列地址线数目设置CPU的相关寄存器后,CPU就会从32位的自动分出L-Bank选择信号, 行地址信号,列地址信号,然后发出行地址信号,列地址信号. L-Bank选择信号在发出行地址信号的同时发出,并维持到列地址信号结束. 有原理图可以看出, 行列地址公用地址线ADDR2-ADDR14(因为DDR的数据位宽为32位,根据2440 datasheet可知,地址线应从A2开始.没有使用ADDR0/1.

使用nSRAS,nSCAS两个信号来区分他们.对于jz2440 v3开发板的SDRAM芯片EM63A165TS的行地址数为13,列地址数位9,所以当nSRAS信号有效时,ADDR2-ADDR14发出来的时行地址信号,它对应的

32位地址空间的bit[23:11](为什么?),当nSCAS信号有效时,ADDR2-ADDR10发出来的时列地址信号,它对应32位地址空间的bit[10:2];

 

  4.找到存储芯片后,被选中的芯片就要进行统一的数据传输了.

    开发板使用两片16位的SDRAM芯片并联组成32位的位宽,与CPU的32跟数据线相连(DATA0-DATA31).

    BANK6的起始地址为0x30000000,所以SDRAM的访问地址为0x30000000-0x33FFFFFF,共64MB.

存储控制器的的寄存器的使用方法

存储控制器共有13个寄存器,BANK0-BANK5只需要设置BWSCON和BANKCONx两个寄存器,BANK6-BANK7外接SDRAM时, 除BWSCON和BANCONx外,还要设置REFLESH,BANKSIZE,MRSRB6,MRSRB7等4个寄存器.

由上图BANCON寄存器发现,每四位控制一个BANK,最高四位对应BANK7,以此类推.

STx: 启动/禁止SDRAM的数据掩码引脚,对于SDRAM,此位为0;对于SRAM,此位为1.

WSx: 是否使用寄存器的WAIT信号,通常设为0.

DWx: 使用两位来设置相应BANK的位宽,0b00对应8位,0b01应16位,0b10对应32位,0b11保留.

  比较特殊的是BANK0,它没有ST0和WS0,DW0只读--由OM0和OM1上电前的电平决定,OM1一直为低,所以只有当OM0为高时,位宽为16bit, 当OM0为低时,选择Nandflash mode.

                     

‭BWSCON可以设置成‭0010 0010 0000 0001 0001 0001 0001 0000‬    ‭0x2201 1110

BANKCONx (x为0~5)

这几个寄存器用来控制BANK0-BANK5外接设备的访问时序,jz2440上使用默认的0x0700

BANKCONx (x为6~7)

在8个BANK中,只有BAN6 AND BAN7可以外接SRAM和SDRAM.BANKCON6和BANKCON7与其他BANK有所不同.

MT: 用于设置本BANK外接的时ROM/SRAM还是SDRAM.SRAM 0b00, SDRAM 0b11

当MT=0b00,此寄存器与BANKCON0---BANKCON5类似.

当MT=0b11,值如下设置

Trcd: RAS to CAS delay, 设为推荐之0b01

SCAN: SDRAM的列地址数,对于这个SDRAM来说, 为9, 所以SCAN=0b01.

这个寄存器应设为 0x00018005

刷新控制寄存器RFFRESH(REFRESH CONTROL REGISTER) 设为0x008c0000 + R_CNT

REFEN: 0= 禁止SDRAM的刷新功能, 1=开启SDRAM的刷新功能

TREFMD: SDRAM的刷新模式. 0 =CBR/auto Refresh,1=Self Refresh(一般在系统休眠时使用).

Trp: 设置为0即可.

Tsrc: 设为默认值0b11即可.

Refresh Counter: 即上述的R_CNT

R_CNT如下计算:(SDRAM时钟频率就是HCLK)

   R_CNT = 2^11 + 1 - SDRAM时钟频率(Mhz) * SDRAM刷新周期(us)

如下图, 刷新周期 64ms/8192 = 7.8125us

在未使用PLL时, SDRAM时钟频率等于晶振频率12Mhz.

可以计算:

  R_CNT= 2^11 + 1 - 12 * 7.8125 = 1955

所以在未使用PLL时, REFRESH = 0x008c0000 + 1955 = 0x8c07a3

BANKSIZW寄存器REFRESH (BANKSIZE REGISTER)

BURST_EN:

  0: ARM核禁止突发传输

  1: ARM核允许突发传输

SCKE_EN[5]:

  0: 不使用信号令SDRAM进入省电模式,1使用SCKE信号令SDRAM进入省电模式.

SCKE_EN[4]:

  0: 时刻发出SCLK信号,1=仅在访问SDRAM期间发出SCLK信号.

BK76MAP:

  设置BANK7/6的大小.

  BANK6/7对应的地址空间与BANK0-5不同. BANK0-5的地址空间大小都是固定的128MB,BANK6/7的地址空间大小都是可变的.以保持这两个空间的地址连续,即BANK7的起始地址会随它们的大小变化. BANK6/7的取值意义如下:

jz2440 v3开发板BANK6外接的时64M的SDRAM(两片32MB),令[2:0]=0b001(64M/64M),表示BANK6 BANK7的容量都是64M.虽然BANK7没有使用.

综上, BANKSIZE寄存器的值应该设为 0xB1

SDRAM模式设置寄存器MRSRBx

能修改的只有CL,这是SDRAM时序的一个时间参数; 由datasheet可知, SDRAM芯片支持CL =2或者3,开发板选择了3,所以 MRSRB6/7的值为0x30

操作实例: 使用SDRAM

从NAND Flash启动CPU时, CPU会通过内部硬件将NandFlash开始的4KB数据复制到称为Steppingston的4KB内部RAM中(起始地址为0),然后跳到地址0开始执行.

例子中先使用汇编设置好储存控制器,使外接的SDRAM可用,然后把程序本身从Steppintstone复制到SDRAM处;最后跳转到执行.

.equ        MEM_CTL_BASE,       0x48000000  @命令用于把常量值设置为可以在文本段中使用的符号
.equ SDRAM_BASE, 0x30000000 .text
.global _start
_start:
bl disable_watch_dog @ 关闭WATCHDOG否则CPU会不断重启.
bl memsetup @ 拷贝之前,要先设置存储控制器,不然SDRAM用不了
bl copy_steppingstone_to_sdram @ 复制代码到SDRAM中
ldr pc, =on_sdram @ 跳转到中继续执行
on_sdram:
ldr sp, =0x34000000 @ 随便设一个没用到的地址吗?
bl main                 @ 跳转到main函数
halt_loop:                  @ 死循环
b halt_loop disable_watch_dog:
mov r1, #0x53000000        @ 直接往这个寄存器写0就可以达到关闭看门狗的目的
mov r2, #0x0
str r2, [r1]
mov pc, lr           @不会自动返回吗? 还要将PC指向跳转函数bl保存的Lr值 copy_steppingstone_to_sdram:        @ 这个函数主要实现将4K大小的数据从CPU内部SRAM拷贝到SDRAM
mov r1, #0                @ 这个地址就是Steppingstone的起始地址.
ldr r2, =SDRAM_BASE           @ SDRAM的起始地址
mov r3, #*1024             @ 4KB大的空间
:
ldr r4, [r1],#           @ 从steppintstone中读取4字节的数据到r4中,并让r4地址加4
str r4, [r2],#           @ 紧接着将刚刚刚读取到r4的数保存到r2所指向的内存单元中,r2一开始指向SDRAM的起始地址
cmp r1, r3           @ 比较是否已经拷贝4KB大小的数据了
bne 1b           @ 如果不相等,说明还没由拷贝完,继续跳转到标号1处执行.
mov pc, lr           @ 如果相等,函数返回. memsetup:
mov r1, #MEM_CTL_BASE       @ 0x4800000000
adrl r2, mem_cfg_val        @ ADRL 伪指令用于将一个地址加载到寄存器中。
add r3, r1, #           @ * = 54 r3 = r1 + 52, 基于base地址需要52个字节空间. 每个寄存器大小为4字节,共有13个寄存器
:
ldr r4, [r2], #    @ 将r2中存储寄存器中的地址保存到r4中, r2 = r2 + 4;指向下一个寄存器所代表的值
str r4, [r1], #          @ 将r4中的值取出来写到r1中, 以达到配寄存器的目的
cmp r1, r3 @ 比较一下是否写完了
bne 1b @ 如果没有,跳转到1标号处继续执行
mov pc, lr @ 否则函数返回 .align
mem_cfg_val:
.long 0x22011110 @ BWSCON
.long 0x00000700 @ BANKCON0
.long 0x00000700 @ BANKCON1
.long 0x00000700 @ BANKCON2
.long 0x00000700 @ BANKCON3
.long 0x00000700 @ BANKCON4
.long 0x00000700 @ BANKCON5
.long 0x00018005 @ BANKCON6
.long 0x00018005 @ BANKCON7
.long 0x008C07A3 @ REFRESH
.long 0x000000B1 @ BANKSIZE
.long 0x00000030 @ MRSRB6
.long 0x00000030 @ MRSRB7

main函数, 可以不关注这个函数的功能,实现LED点亮的功能, 方便验证函数已经跑到这.

#define    GPFCON        (*(volatile unsigned long *)0x56000050)
#define GPFDAT (*(volatile unsigned long *)0x56000054) #define GPF4_out (1<<(4*2))
#define GPF5_out (1<<(5*2))
#define GPF6_out (1<<(6*2)) void wait(volatile unsigned long dly)
{
for(; dly > ; dly--);
} int main(void)
{
unsigned long i = ; GPFCON = GPF4_out|GPF5_out|GPF6_out; // while(){
wait();
GPFDAT = (~(i<<)); //
if(++i == )
i = ;
} return ;
}

Makefile

sdram.bin : head.S  leds.c
arm-linux-gcc -c -o head.o head.S
arm-linux-gcc -c -o leds.o leds.c
arm-linux-ld -Ttext 0x30000000 head.o leds.o -o sdram_elf
arm-linux-objcopy -O binary -S sdram_elf sdram.bin
arm-linux-objdump -D -m arm sdram_elf > sdram.dis
clean:
rm -f sdram.dis sdram.bin sdram_elf *.o

最后将程序烧录到nandflash中验证一下.

韦东山嵌入式Linux学习笔记05--存储管理器的更多相关文章

  1. 韦东山嵌入式Linux学习笔记02--如何给开发板烧录程序

    购买韦东山嵌入式开发板jz2440 v3会标配两根usb线和一根网线,OpenJtag需要单独购买, 我暂时还没买到该工具. 下面介绍usb烧录以及通过网线烧录程序. 1.usb烧录程序: 借助DNW ...

  2. 韦东山嵌入式Linux学习笔记08--中断体系结构

    中断是什么? 举个栗子, 系统怎么知道你什么时候插入鼠标这个设备? 可以有两种处理方式: 1. 查询方式: 轮询去检测是否有设备插入; 2. 中断的方式 当鼠标插入这个事件发生时, 置位某个寄存器,告 ...

  3. 韦东山嵌入式Linux学习笔记07--Nandflash

    常用的flash有两种, Norflash和Nandflash, 前几年市场上的产品比较常见的方案时Norflash和Nandflash搭配使用, 因为norflash比较昂贵,相同的容量norfla ...

  4. 韦东山嵌入式Linux学习笔记04--点亮开发板的一个LED灯

    搜索开发板原理图LED的走线           LED8是网线接口的指示灯. 在这里我们尝试用汇编代码控制D10, 也就是LED1,它连接到EINT4/GPF4,读取芯片手册 有原理图可知,如果需要 ...

  5. 韦东山嵌入式Linux学习笔记03--如何搭建软件环境

    1. 从网上下一个虚拟机,比如vmvare station 2.下一个ubuntu镜像回来安装,  我下了14.04来安装.参考链接:  https://blog.csdn.net/qq1326702 ...

  6. 韦东山嵌入式Linux学习笔记01--转载: 板子ping不通PC怎么办

    请参考链接:https://blog.csdn.net/u013490896/article/details/71250060 我的环境: window 10 jz2440 v3 我采用的连接方式如下 ...

  7. 韦东山 嵌入式linux教程 笔记

    @ 目录 资源链接 一.常用命令 二.shell 三.如何更改PATH? 四.路径 五.vi编辑器 六.进阶命令 七.NAT配置网络 (第2篇-P34) 八.开发板挂载 Ubuntu 的 NFS 目录 ...

  8. 嵌入式Linux学习笔记之第一阶段---基础篇

    嵌入式Linux学习分五个阶段 第一阶段: 01嵌入式环境搭建初期 02C语言语法概述 03C语言内存操作 04c语言函数 05linux基础 06gun基础 第二阶段: 01-linux之io系统编 ...

  9. 嵌入式Linux学习笔记(三) 字符型设备驱动--LED的驱动开发

    在成功构建了一个能够运行在开发板平台的系统后,下一步就要正式开始应用的开发(这里前提是有一定的C语言基础,对ARM体系的软/硬件,这部分有疑问可能要参考其它教程),根据需求仔细分解任务,可以发现包含的 ...

随机推荐

  1. javascript中ClassName属性的详解与实例

    在javascritp中,我们可以通过style属性可以控制元素的样式,从而实现行为层通过DOM的style属性去干预显示层显示的目标,但是这种方法是不好的,而且为了实现通过DOM脚本设置的样式,你不 ...

  2. Ceph 分布式存储架构解析与工作原理

    目录 文章目录 目录 Ceph 简介 Ceph 的架构:分布式服务进程 Ceph Monitor(MON) Ceph Object Storage Device Daemon(OSD) Ceph Me ...

  3. jq 点击除了某元素以外的其他所有元素

    $('body').click(function(e){ if(($(e.target).attr('class')!='header-top-nav-ipt')){ alert('除了class=h ...

  4. Laravel6.0 使用 Jwt-auth 实现多用户接口认证

    后台管理员认证 (admins 表) 首先创建数据库和表 (admins),在 routes/api.php 中,写上如下路由并创建对应控制器和方法. Route::namespace('Api')- ...

  5. 用xcode打包完成,出现的Archive界面怎么打开?

    要出现这个界面 只需在xcode界面进入windows 的下拉菜单Organizer

  6. 【Python开发】urllib2.urlopen超时问题

    原帖地址:http://hi.baidu.com/yss1983/item/933fbe45a09c43e01381da06 问题描述:     没有设置timeout参数,结果在网络环境不好的情况下 ...

  7. 【DSP开发】HyperLink 编程和性能考量

    冯华亮/Brighton Feng---Communication Infrastructure 摘要 HyperLink 为两个 KeyStone 架构 DSP 之间提供了一种高速,低延迟,引脚数量 ...

  8. elk 概念整理 集群状态 - yellow - 面试的问题 -- 官方配置文档 水平扩容以及数据保障

    1. primary shard   -- raid0 2.replicas shard -- raid1 3.index -- 图书馆的借书指引 4.MySQL vs elasticsearch # ...

  9. web端 微软 RDLC 报表插件 宽大于高 横向打印失效 解决方案

    起因于系统报表工具使用的RDLC,本地测试一直使用的纵向打印,未测试过横向打印

  10. 解决VS2008之后平台(如VS2012/VS2013/VS2015)调试模式下不显示主界面窗口的问题

    问题描述:win10操作系统下,VS2008工程调试模式下正常显示主界面窗口,使用VS2012/VS2013/VS2015环境打开VS2008工程,调试模式下应用程序转为后台进程,不显示主界面窗口:另 ...