(三)内存 SDRAM 驱动实验 (杨铸 130 页)(勉强能懂个大概)
SDRAM 芯片讲解:
地址: 行地址 (A0-A12) 列地址 (A0-A8) 片选信号(BA0 BA1)(L-BANK)(因为SDRAM有 4片)
两片SDRAM 连线唯一区别在 UDQM LDQM
DQM0 ---片1 LDQM
DQM1----片1 UDQM
DQM2----片2 LDQM
DQM3---片2 UDQM
————————————————————————————————————————————————————————————
1、读操作(见杨铸 121)
地址线上送上要读数据的地址自然要有地址才行,(就好比送快递,首先你得确定好要送达的目的地址在哪里一样)
确定地址:CS低电平 即 nSCS0 拉低,选中外接设备 , L—BANK 也选中SDRAM 内部对应 某一片 (这样就定址了),而且同时
RAS 行地址选通信号也处于有效状态,当然这是要写列地址肯定要 行地址稳定才行(需要时间 tRCD=2),
列地址也假装不稳定,需要一个时间延迟(我们称为 CAS 潜伏期),当然并非不稳定,是芯片自身原因。
地址这样一步步确定,就可以读了(怎么不是写啊,因为 WE 无效,不让写啊,所以相当于读了。有效,就是写)
2、预充电操作
要对同一个L-BANK 的另一行进行寻址,自然要把原先一行关掉。重新发行列地址。
关掉原先一行,要预充电(目的是对整个存储体原有信息进行重写,然后再关闭操作行)
即预充电包含两步(重写+关闭原先行),但是预充电不定期,只在读操作执行
3、写操作
和读操作一样,唯一区别是 经过行延迟(tRCD后)输入写命令(WE低电平有效,拉低,就可以写)
在写完最后一个数据后, 延迟 tWR,发送预充电命令。关闭激活页。
等待 tRP 时间后可以进行下一次操作。
4、写操作
5、刷新操作
——————————————————————————————————————————————
以上可以结合 杨铸书籍和s3c2440芯片手册 memory contrl 来分析的,不算难,除了刷新没耐性看,还好
————————————————————————————————————————————————————————————
开始做内存驱动实验:(2.6.8)
本程序文件主要实现了: 关闭看门狗,初始化内存,复制ROM数据到内存中,然后调到内存执行 Xmain 函数,从 xmain 函数返回后, 将 全部 LED 点亮,进入死循环。
;
; 内存初始化实验
;
AREA Init, CODE, READONLY
ENTRY
start
; close watchdog
ldr r0, = 0x53000000 ; 将看门狗控制寄存器地址放入r0
mov r1, #
str r1, [r0] ; 设置看门狗控制寄存器的值为0 bl initmem ; 跳转到initmem代码段,初始化内存 bl copyall ; 跳转到数据拷贝代码段,将ROM中数据拷贝到内存中 IMPORT xmain ; 引入main.c中的xmain函数
ldr sp, =0x34000000 ; 调用C程序之前先初始化栈指针
ldr lr, =endxmain ; 设置xmain函数的返回地址
ldr pc, =xmain ; 跳转到C程序中的xmain函数的入口处执行 endxmain
ldr r0, =0x56000010 ; LED的GPIO接口配置寄存器(只针对QQ2440,MINI2440开发板)
ldr r1, =0x00015400 ; GPIO配置数据
str r1, [r0] ; 设置GPIO
ldr r0, =0x56000014 ; LED控制寄存器地址
ldr r1, =0x000000e0 ; 全部LED亮
str r1,[r0]
loop
b loop ; 死循环 copyall
IMPORT |Image$$RO$$Base| ; 引入编译器Image$$RO$$Base符号变量
IMPORT |Image$$RW$$Limit| ; 引入编译器Image$$RW$$Limit符号变量
ldr r0, = |Image$$RO$$Base| ; 取得Image$$RO$Base域基址的值
ldr r1, = |Image$$RW$$Limit|; 取得Image$$RW$Base域结束地址的值 ldr r2, =0x0 ; 数据拷贝源地址
copyallloop
teq r0,r1 ; 测试是否拷贝完成
beq quitcopyallloop ; 拷贝完成,跳往quitcopyallloop退出
ldr r3, [r2], # ; 四字节加载
str r3, [r0], # ; 四字节存储
b copyallloop ; 返回继续执行
quitcopyallloop
bx lr ; 调用返回 (lr 即存放 PC指针的值,也就是子程序的返回地址) initmem ; 内存初始化
ldr r0, =0x48000000 ; 加载内存相关寄存器首地址r0
ldr r1, =0x48000034 ; 加载内存相关寄存器尾地址到r1 adr r2, memdata ; 将寄存器配置数据地址段首地址加载到r2 // 这里是相对地址 initmemloop
ldr r3, [r2], # ; 循环设置存寄存器
str r3, [r0], #
teq r0, r1
bne initmemloop ; 循环到最后一个寄存器时退出函数
bx lr memdata
DCD 0x22000000 ;BWSCON 选中 bank6 bank7 32bit数据输入输出 // 用于分配一片连续的字存储单元并用指定的数据初始化(参考芯片手册, BWSCON 到 MRSRB7 正好13个字,也就是 0x48000000---0x48000034)
DCD 0x00000700 ;BANKCON0
DCD 0x00000700 ;BANKCON1
DCD 0x00000700 ;BANKCON2
DCD 0x00000700 ;BANKCON3
DCD 0x00000700 ;BANKCON4
DCD 0x00000700 ;BANKCON5
DCD 0x00018005 ;BANKCON6 // 确定存储芯片类型为 SDRAM RAS到CAS delay 3个时钟周期 列地址 9 bit
DCD 0x00018005 ;BANKCON7 // 同上
DCD 0x008e07a3 ;REFRESH // sdram 刷新控制
DCD 0x000000b1 ;BANKSIZE
DCD 0x00000030 ;MRSRB6
DCD 0x00000030 ;MRSRB7 END
讲解:http://www.cnblogs.com/idle_man/archive/2010/12/18/1910158.html (跳转到数据拷贝代码段,将ROM中数据拷贝到内存中)// 这里看杨铸 P95 页一目了然
copyall
IMPORT |Image$$RO$$Base| ; 引入编译器Image$$RO$$Base符号变量
IMPORT |Image$$RW$$Limit| ; 引入编译器Image$$RW$$Limit符号变量
ldr r0, = |Image$$RO$$Base| ; 取得Image$$RO$Base域基址的值
ldr r1, = |Image$$RW$$Limit|; 取得Image$$RW$Base域结束地址的值
对于刚学习ARM的人来说,如果分析它的启动代码,往往不明白下面几个变量的含义:|Image$$RO$$Limit|、|Image$$RW$$Base|、|Image$$ZI$$Base|。
在ADS的Debug Settings中有一栏是Linker/ARM Linker,在output选项中有一个RO base选项,下面应该有一个地址,我这里是0x0000 0000(不是每个都一样的),后面的RW base 地址是0x3000 0000,
然后在Options选项中有Image entry point ,是一个初始程序的入口地址,我这里是0x0000 0000 。
|Image$$RO$$Base| = Image entry point = 0x0000 0000 ;表示程序代码存放的起始地址
|Image$$RO$$Limit|=程序代码起始地址+代码长度+1=0x0c100000+Tatal RO size+1
|Image$$RW$$Base| = 0x0c200000 ;由RW base 地址指定
内存初始化也可以通过C语言来实现:
#define MEM_CTL_BASE 0x48000000
#define MEM_CTL_END 0x48000034
unsigned long const mem_cfg_val[]=
{
0x22000000, //BWSCON // 用于分配一片连续的字存储单元并用指定的数据初始化
0x00000700, //BANKCON0
0x00000700, //BANKCON1
0x00000700, //BANKCON2
0x00000700, //BANKCON3
0x00000700, //BANKCON4
0x00000700, //BANKCON5
0x00018005, //BANKCON6
0x00018005, //BANKCON7
0x008e07a3, //REFRESH
0x000000b1, //BANKSIZE
0x00000030, //MRSRB6
0x00000030, //MRSRB7 } ;
void mem_init(void)
{
int i=;
unsigned long * p=(unsigned long *)MEM_CTL_BASE;
for(:i<(MEM_CTL_END-MEM_CTL_BASE)/;i++)
p[i]=mem_cfg_val[i]; }
(三)内存 SDRAM 驱动实验 (杨铸 130 页)(勉强能懂个大概)的更多相关文章
- 【转】S3C2440存储系统-SDRAM驱动
SDRAM(Synchronous Dynamic Random Access Memory,同步动态随机存储器)也就是通常所说的内存.内存的工作原理.控制时序.及相关控制器的配置方法一直是嵌入式系统 ...
- 【转】android 电容屏(三):驱动调试之驱动程序分析篇
关键词:android 电容屏 tp 工作队列 中断 坐点计算 电容屏主要参数平台信息:内核:linux2.6/linux3.0系统:android/android4.0 平台:S5PV310( ...
- 故意使用free掉的内存的一个实验( 常量区/栈)
故意使用free掉的内存的一个实验 考虑一下两种声明 struct stuff{ char home[10]; int num; char name[10]; }; struct stuff{ cha ...
- 10-8位7段数码管驱动实验——小梅哥FPGA设计思想与验证方法视频教程配套文档
芯航线--普利斯队长精心奉献 实验目的: 1.实现FPGA驱动数码管动态显示: 2.使用In system sources and probes editor工具,输入需要显示在数码管上的的数据, ...
- (一)keil4 MDK 开发环境下编写裸机程序 (参考杨铸 北航) (开发板只需要连接JLNK 就行了)
首先用的是 keil4 位与 ( F:\ARM+LINUX\MDK-ARM_v4.10.exe ) 1. 新建工程名project 为 led circle ,放在 我的文档\ l ...
- Linux内存初始化(三) 内存布局
一.前言 同样的,本文是内存初始化文章的一份补充文档,希望能够通过这样的一份文档,细致的展示在初始化阶段,Linux 4.4.6内核如何从device tree中提取信息,完成内存布局的任务.具体的c ...
- 2019寒假训练营第三次作业part2 - 实验题
热身题 服务器正在运转着,也不知道这个技术可不可用,万一服务器被弄崩了,那损失可不小. 所以, 决定在虚拟机上试验一下,不小心弄坏了也没关系.需要在的电脑上装上虚拟机和linux系统 安装虚拟机(可参 ...
- LTDC_DMA2D驱动实验
STM32F429芯片使用LTDC.DMA2D.及RAM存储器,构成了一个完整的液晶控制器.LTDC负责不断刷新液晶屏(将数据从显存搬运到液晶屏),DMA2D用于图像数据搬运.混合及格式转换(将数据搬 ...
- 深入理解Java虚拟机之读书笔记三 内存分配策略
一般的内存分配是指堆上的分配,但也可能经过JIT编译后被拆散为标量类型并间接地在栈上分配.对象主要分配在新生代的Eden区上,如果启动了本地线程分配缓冲,将按线程优先在TLAB上分配,少数情况下直接分 ...
随机推荐
- 1.2 Quartz 2D 内存管理
本文并非最终版本,如有更新或更正会第一时间置顶,联系方式详见文末 如果觉得本文内容过长,请前往本人 “简书” 通过 Product -> Analyze 来进行静态分析 可以使用Quar ...
- 【原】iOS学习之UIStoryboardSegue解析
在 Storyboard 的可视化编程中,跳转界面就是按住 Ctrl 使用鼠标头一条连线就可以解决,相当的简单!本篇博客主要就是介绍这条连线,在iOS中,这条连线也是一个对象,也有其自己的初始化方法和 ...
- Linux 计划任务
实例: 每5分钟定时访问一个url # crontab -e #*/5 * * * * /usr/bin/curl http://aa.com:8080/tools/sitemap.php >& ...
- 修改Windows Server 2008密码策略,设置简单密码
最长使用期限为0表示密码永不过期. 如果是VBOX虚拟机安装,在使用共享文件夹功能时候,需要打开控制面板--网络和共享中心--共享设置--启动网络发现.然后才能映射共享文件夹
- Qt中新建类构造函数的初始化参数列表
使用Qt-creator自动生成一个窗体应用程序时会自动创建一个新的类,我的程序中名为MyDialog,类的定义为: #ifndef MYDIALOG_H #define MYDIALOG_H #in ...
- STM32之EXTI——外部中断
互联网的广大网友,大家早上中午晚上好.EXTI...故名思义..EX表外,出..I表示Intrrupt..所以合起来就是外部中断...说到这..我觉得我最近的六级水平(背单词)又进了一步,稍微自夸了下 ...
- Android:Activity生命周期
Android是使用任务(Task)来管理活动的,一个任务就是一组存放在栈里的活动的集合,这个栈也被称作返回栈(Back Stack). 栈是一种后进先出的数据结构,在默认情况下,每当我们启动了一个新 ...
- JAVA中的TreeSet
TreeSet简介 TreeSet是一个有序的集合,它的作用是提供一个有序的Set集合,它继承于AbstractSet抽象类实现了NavigableSet<E>, Cloneable, j ...
- Struts2+jQuery+Json零配置实现ajax
(一)Jsp页面代码 <%@ page language="java" import="java.util.*" pageEncoding="U ...
- 【iCore3双核心板】发布 iCore3 应用开发平台硬件原理图
原理图PDF下载地址:http://pan.baidu.com/s/1jHY0hNK iCore3应用开发平台购买地址:https://item.taobao.com/item.htm?spm=a1 ...