存储控制器--SDRAM
来源:互联网 发布:北京肝病三甲医院 知乎 编辑:程序博客网 时间:2024/04/30 13:52
2存储控制器
上一节写的太细,这节写重点
正如在GPIO里面说的
这个ARM统一编址(1G~4G留给寄存器)
0x0000_0000~0x4000_0000这1G
给外设用的,硬件把这些地址分成8块
叫做BANK0~BANK7
BANK0地址是0~128
BANK7是(1G-128M)~1G
那么一块的大小是多少呢?!
1G/8=128M。。。。
上面有NOR FLASH IDE 网卡A 网卡B 串口芯片 内存
这些BANK就是由存储控制器管理的。
存储管理器实际上是管理类似于内存这样直接寻址的外设
出厂的时候这些外设就已经粘在这些BANK上面
一开始是没法使用的,所以当然是要设置好这个存储管理器了。
这里我们就配置存储管理器使用SDRAM内存
因为我们S3C2440硬件上对外的地址线只有27根,所以寻址128M
要加上8个片选,用来选择那个BANK,一共1G
寄存器当然是不用对外地址线了
不过这些跟我们没关系,他们是透明的,我们写代码也不需要指定那个BANK
只需要给地址,CPU会自己处理
如图BANK6接的外设是内存,正是我们今天要弄明白的内存。
显然BANK6的地址是0x3000_0000~0x3800_0000这128M了,我们这个S3C2440的内存SDRAM没用完,万恶的资本家只用了64M的内存设备在上面
2.1 BANK寄存器
现在来介绍一下BANK的操作方法,就是在BANK寄存器地址操作了
那么BANK需要几个寄存器操作呢!?
一共是
BWSCON
BANKCON0~BANKCON7
REFRESH
BANKSIZE
MRSRB6~MRSRB7
一共1+8+1+1+2=13个吧
其中
BWSCON控制0~7
BANKCONx控制自己对应的BANK
REFRESH控制BANK6~BANK7
BANKSIZE控制6~7
MRSPBx也是控制6~7
我们只讨论BANK6
因为这个接内存SDRAM,显然内存是很复杂的东西,不然为什么那么贵
SDRAM这种内存,是要刷新的,所以没办法,要靠REFRESH,所以它只能接BANK6
BANKSIZE是用于处理BANK6和BANK7的关系
一下是依次介绍
就不多介绍0~5的BANK了,因为没有例子
2.11BWSCON
每4位控制一个BANK,以6作参考
ST6 启动SRDAM的数据掩码引脚,不知道什么意思,反正SDRAM就要是0的意思 SRAM是1,其他外设也是0
WS6 WAIT信号,设为0
DW6 位宽,我SDRAM是32位,所以当然是10了
BANK7是和BANK6一伙的,这里我也不理解,我开发板程序也没用过BANK7
不过就是说BANK7直接和BANK6数据一致就对了。
说白了,实际上这东西只要管DW这个位宽,就是外设的位宽
我开发板BANK6的SDRAM是32位,BANK5的扩展串口是8位,其余BANK0~BANK4都是16位
那么分别DW就是
0b10
0b00
0b01
那么最后BWSCON就是0x22011110
为什么BANK0是0b00呢,那是因为
我也不知道。不过它是特殊的。因为它只读,而且只有DW没有ST和WS
2.12BANKCONx
这是BANK6/7专用的
BANK0~5就是中间那段PMC~Tacs 0~14位了
BANK6.7如果把MT=00,就是BANK0~5无差别
MT是11则使用SCAN Trcd这一共4位
当然我们这里MT是11了
SCAN是知名列地址位数的,这是SDRAM在硬件上的构造,我这里是9位的
所以是0b01
MT=11
Trcd=0b01 推荐
内存行地址传输到列地址的延迟时间。
这里看芯片手册,建议是3clocks
SCAN=01
加起来就是
0x0001_8005
2.13REFRESH
顾名思义就是设置刷新频率的
Refresh Counter:
有用的一共5个值,先从最重要的Refresh Counter说起
这个值就是用来设置SDRAM的刷新周期,至于为什么SDRAM要刷新,因为他是动态RAM,说白了成本比静态RAM低,所以要刷新维持值。
我SDRAM的刷新周期是7.8125us,即每7.8125us要刷一次
这里还设计HCLK,即时钟频率,我们这里SDRAM时钟频率是晶振频率,这是裸板是12MHz
一般而言1/周期=频率
周期和频率我们都有了,现在就是要求那个
这里公式大致成立,只是那东西不是1,在这里他式子是2^11+1-refresh_count
这样就可以把refresh_count算出来,我算了是1955
REFEN:使能刷新,显然是呀1了
TREFMD:刷新模式,我们选择自动率先年
Trp:百度
Tsrc:百度
这些刷新clocks之类的不用管那么多了,使用默认就好
最后整个寄存器就是0x008C07A3
2.14BANKSIZE
这个也比较好理解
其中
介绍BK76MAP,我因为我至今不理解BANK6/7如何实现空间地址连续。
不过既然是64M的SDRAM,我就设置成64M好了
其他的3个值就请自行查找了,这里不重要
值就是0xB1
2.15MRSPBx
不重要,直接给值0x30
2.2使用SDRAM
现在我们知道寄存器要设置成什么值,然后才能配合BANK6的32位,列地址是9的SDRAM了
那么是不是只要我们设置了这些寄存器就可以使用这个SDRAM呢?
那么简单?
很明显---------
是的
当你设置好这些寄存器,BANK6激活。
SDRAM起作用。地址是在0x3000_0000
意味着从0x3000_0000后的64M都可以把代码拷到上面执行
--------------那么问题来了
之前的GPIO实验的代码不是在内存里面跑的的吗!?
还真不是,
之前的代码是烧写在NAND Flash(硬盘),执行在Steppingstone(CPU自带RAM,只有4k)
烧写在NAND Flash上的代码是在NAND FLASH开头的,CPU上电会自动把头4K(那个GPIO程序<<4k)复制到Steppingstone,然后执行。
Steppingstone一下简称片内内存
那么我们为了验证SDRAM,当然要代码在SDRAM上运行了
-------------------------------------------------------------------------------------
完成步骤:
1.把片内内存复制到SDRAM的地址0x3000_0000上面
2.跳到0x3000_0000上面
实现方法:
1:就是通过寄存器和地址之间的复制了,命令当然就是ldr/str
2:这里需要先了解一个概念,就是代码运行的地方,这里指的是CPU认为这个代码运行的地方。并未实际运行的地方。
那么我们可以让CPU认为这个代码运行在0x3000_0000上面。
使用绝对跳转指令(给pc寄存器赋值A,但A不是具体地址,而是代码上的一个标识符)就可以跳到上面了。
只要让这个标识符被CPU认为实在SDRAM上面就可以了。
这里就要使用arm-linux-ld在链接是指定代码段的起始地址了参数是-Ttext
-------------------------------------------------------------------------------------------------
3.代码
那么综合步骤就是
1 初始化存储器
2 片内内存复制到内存SDRAM
3 跳到SDRAM
.equ MEM_CTL_BASE, 0x48000000.equ SDRAM_BASE, 0x30000000.text.global _start_start: bl disable_watch_dog @ 关闭WATCHDOG,否则CPU会不断重启 bl memsetup @ 设置存储控制器 bl copy_steppingstone_to_sdram @ 复制代码到SDRAM中 <span style="background-color: rgb(255, 153, 0);">ldr pc, =on_sdram</span> @ 跳到SDRAM中继续执行on_sdram: ldr sp, =0x34000000 @ 设置堆栈 bl mainhalt_loop: b halt_loop----------------以上就是全部步骤,下面是封装的函数-------------------------------------------------disable_watch_dog: @ 往WATCHDOG寄存器写0即可 mov r1, #0x53000000 mov r2, #0x0 str r2, [r1] <span style="background-color: rgb(51, 255, 255);">mov pc, lr</span> @ 返回copy_steppingstone_to_sdram: @ 将Steppingstone的4K数据全部复制到SDRAM中去 @ Steppingstone起始地址为0x00000000,SDRAM中起始地址为0x30000000 mov r1, #0 ldr r2, =SDRAM_BASE mov r3, #4*10241: ldr r4, [r1],#4 @ 从Steppingstone读取4字节的数据,并让源地址加4 str r4, [r2],#4 @ 将此4字节的数据复制到SDRAM中,并让目地地址加4 cmp r1, r3 @ 判断是否完成:源地址等于Steppingstone的未地址? bne 1b @ 若没有复制完,继续 mov pc, lr @ 返回memsetup: @ 设置存储控制器以便使用SDRAM等外设 mov r1, #MEM_CTL_BASE @ 存储控制器的13个寄存器的开始地址 adrl r2, mem_cfg_val @ 这13个值的起始存储地址 add r3, r1, #52 @ 13*4 = 541: ldr r4, [r2], #4 @ 读取设置值,并让r2加4 str r4, [r1], #4 @ 将此值写入寄存器,并让r1加4 cmp r1, r3 @ 判断是否设置完所有13个寄存器 bne 1b @ 若没有写成,继续 <span style="background-color: rgb(51, 255, 255);">mov pc, lr</span> @ 返回.align 4mem_cfg_val: @ 存储控制器13个寄存器的设置值 .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
上面只有橙色底的是跳到SDRAM的绝对跳转指令。其
其余如蓝色底虽然也是绝对跳转,但是不会跳到SDRAM,因为lr寄存器存的是片内内存的地址。push进栈麻麻嘛。。。
看看makefile
<span style="background-color: rgb(255, 255, 255);">sdram.bin : head.S leds.carm-linux-gcc -c -o head.o head.Sarm-linux-gcc -c -o leds.o leds.carm-linux-ld </span><span style="background-color: rgb(255, 153, 0);">-Ttext 0x30000000</span><span style="background-color: rgb(255, 255, 255);"> head.o leds.o -o sdram_elfarm-linux-objcopy -O binary -S sdram_elf sdram.binarm-linux-objdump -D -m arm sdram_elf > sdram.disclean:rm -f sdram.dis sdram.bin sdram_elf *.o</span>
看到链接到0x3000_0000了。就是说CPU认为这段代码在这个地址运行
具体就是标识符(程序标号_start,on_sdram等等)都是表示0x3000_0000之后的地址
而且很明显我们知道C语言地址是摆在这个汇编之后的
yoghourt_man
0 0
- 存储控制器SDRAM实验
- 存储控制器--SDRAM
- 存储控制器和SDRAM 实验
- 存储控制器和SDRAM 实验
- 【嵌入式Linux+ARM】存储控制器(操作SDRAM)
- SDRAM控制器
- SDRAM控制器
- 存储-SDRAM
- SDR SDRAM控制器的
- SDRAM控制器设计
- 细说SDRAM控制器
- 存储控制器与外设之间的关系 (SDRAM与BANK6连接概述)
- SDRAM工作原理及S3C2410 SDRAM控制器配置方法
- SDRAM工作原理及S3C2410 SDRAM控制器配置方法
- SDRAM工作原理及S3C2410 SDRAM控制器配置方法
- SDRAM工作原理及S3C2410 SDRAM控制器配置方法
- SDRAM工作原理和S3C2410 SDRAM扩展控制器配置方法
- SDRAM工作原理及S3C2410 SDRAM控制器配置方法
- [LeetCode 111]Minimum Depth of Binary Tree
- 2/1+3/2+5/3+8/5....前二十项和
- 通过自定义的URL Scheme启动你的App
- 加速Android Studio/Gradle构建
- 如何入门参加数学建模竞赛
- 存储控制器--SDRAM
- 钱币兑换
- 技术负责人如何搞定老板之我所见
- 字符串替换
- What does `return x ? : 1` mean in C language? [duplicate] stackoverflow
- Java Math类
- Random
- design_pattern_derivative_statistics
- android service 详解