二、存储管理器--SDRAM

2.1 硬件结构

2.1.1 硬件框图

  CPU 通过存储管理器来读取 SDRAM 网卡 等外部设备,CPU不管外部设备是怎么样的,只是读存储管理器中的地址

  

  CPU从0x30000000地址读取数据。

1 mov R1, #0x30000000
2 ldr    R0, [R1]

  存储管理器会根据配置信息来访问外部的设备。

  配置信息包括:

    • 外部设备的地址
    • 外部设备的数据,数据宽度是多少位(8位/16位/32位)
    • 时钟信号频率
    • 外部设备相关的特性,SDRAM包括行地址,列地址和bank

  SDRAM的存储结构逻辑如下:

  

  SDRAM内部为一个存储阵列。读写原理为,先指定一个行(ROW),再指定一个列(COLUMN),就可以找到所需要的内容。

  一个存储阵列称为一个BANK。

2.SDRAM

2.1 硬件结构

  两个16位的芯片组成32位位宽。

  

  

  

            

  具体参数可以查看SDRAM的芯片手册。

  SDRAM 需要知道的信息:

  • 列地址和行地址的数目:由芯片手册可以知道,行地址为13位,列地址为9位
  • 刷新周期:刷新周期为  64/8192
  • bank 地址
  • 位宽:由原理图可以知道,位宽为32  

  

  由芯片手册可以知道,行地址为13位,列地址为9位

  

  刷新周期为  64/8192

  2440 芯片手册上面写了位宽与PIN脚之间的关系,如下图:

  

  若是8位位宽,只接A0 A1.......,若是16位位宽,则为A1 A2........,若是32位位宽,则为A2 A3........;这些引脚接到SDRAM上都是从 SDRAM的A0开始,32位,即LADDR2接到A0上开始

2.2 编程

  要想使用SDRAM,需要进行以下几步:

  1)配置存储管理器

  2)将SDRAM 的信息写入到寄存器中

  对于存储管理器,涉及到13个寄存器,具体看芯片手册

  • 程序设计思路:

    • 程序烧写进NAND Flash 中后,NAND Flash 中的前4K会拷贝到CPU的SRAM中去,SRAM的起始地址为0x00000000,程序从这里开始执行,SDRAM中的4K内容称为steppingstone
    • 然后在SRAM中执行的时候,会将SRAM中的程序拷贝进SDRAM中去,然后继续在SDRAM中执行
    • 若是程序较大,则前4K执行完后,会将NAND Flash 的中的所有代码一次性拷贝进SDRAM中执行,此章不涉及

  链接地址:运行时,程序应该位于哪里  

  代码 head.S

 1 @******************************************************************************
 2 @ File:head.S
 3 @ 功能:SDRAM 进行初始化
 4 @******************************************************************************
 5
 6 @ .equ 命令用于把常量值设置为可以在文本段中使用的符号
 7 @ 经过设置之后,数据符号值是不能在 程序中改动的。
 8 @  .equ 命令可以出现在数据段中任何位置,但是出于好的代码习惯,最好是在定义其他数据之前或之后集中定义所有数据符号
 9 .equ        MEM_CTL_BASE,       0x48000000          @ 设置内存控制器的基地址,寄存器的起始地址
10 .equ        SDRAM_BASE,         0x30000000          @ 设置SDRAM的基地址,按接在2440的哪个片选上看
11
12 .text
13 .global _start
14 _start:
15     bl      disable_watch_dog               @ 关闭WATCHDOG,否则CPU会不断重启
16     bl      memsetup                        @ 设置存储控制器
17     bl      copy_steppingstone_to_sdram     @ 复制代码到SDRAM中
18     ldr     pc, =on_sdram                   @ 跳到SDRAM中继续执行
19
20 on_sdram:
21     ldr     sp, =0x34000000                 @ 设置堆栈,SDRAM 总共64M,栈指针指向SDRAM的最上端
22     bl      main
23
24 halt_loop:
25     b       halt_loop
26
27 @ 关闭看门狗
28 disable_watch_dog:
29     ldr     r0, =0x53000000                 @ WATCHDOG寄存器地址
30     mov     r1, #0x0
31     str     r1, [r0]                        @ 写入0,禁止WATCHDOG,否则CPU会不断重启
32     mov     pc, lr                          @ 返回
33
34 @ 设置存储控制器,以便使用SDRAM等外设
35 memsetup:
36     mov     r1, #MEM_CTL_BASE               @ 存储控制器的13个寄存器的开始地址
37     adrl    r2, mem_cfg_val                 @ 这13个值的起始存储地址
38     add     r3, r1, #52                     @ 13*4 = 54
39 1:
40     ldr     r4, [r2], #4                    @ 读取设置值,并让r2加4
41     str     r4, [r1], #4                    @ 将此值写入寄存器,并让r1加4
42     cmp     r1, r3                          @ 判断是否设置完所有13个寄存器
43     bne     1b                              @ 若没有写成,继续
44     mov     pc, lr                          @ 返回
45
46
47 copy_steppingstone_to_sdram:
48     @ 将Steppingstone的4K数据全部复制到SDRAM中去
49     @ Steppingstone起始地址为0x00000000,SDRAM中起始地址为0x30000000
50
51     mov     r1, #0                          @ 片内内存的起始地址为 0
52     ldr     r2, =SDRAM_BASE                 @ SDRAM 中的基地址
53     mov     r3, #4*1024                     @ 拷贝的大小为 4K
54 1:
55     ldr     r4, [r1],#4                     @ 从Steppingstone读取4字节的数据,并让源地址加4
56     str     r4, [r2],#4                     @ 将此4字节的数据复制到SDRAM中,并让目地地址加4
57     cmp     r1, r3                          @ 判断是否完成:源地址等于Steppingstone的末地址?
58     bne     1b                              @ 若没有复制完,继续
59     mov     pc,     lr                      @ 返回
60
61
62 .align 4
63 mem_cfg_val:
64     @ 存储控制器13个寄存器的设置值
65     .long   0x22011110      @ BWSCON
66     .long   0x00000700      @ BANKCON0
67     .long   0x00000700      @ BANKCON1
68     .long   0x00000700      @ BANKCON2
69     .long   0x00000700      @ BANKCON3
70     .long   0x00000700      @ BANKCON4
71     .long   0x00000700      @ BANKCON5
72     .long   0x00018005      @ BANKCON6
73     .long   0x00018005      @ BANKCON7
74     .long   0x008C07A3      @ REFRESH
75     .long   0x000000B1      @ BANKSIZE
76     .long   0x00000030      @ MRSRB6
77     .long   0x00000030      @ MRSRB7

  sdram.c

 1 /* GPF */
 2 #define GPFCON      (*(volatile unsigned long *)0x56000050)
 3 #define GPFDAT      (*(volatile unsigned long *)0x56000054)
 4 /* GPG */
 5 #define GPGCON      (*(volatile unsigned long *)0x56000060)
 6 #define GPGDAT      (*(volatile unsigned long *)0x56000064)
 7
 8 /* GPF */
 9 #define GPF4_out    (1<<(4*2))
10 #define GPF5_out    (1<<(5*2))
11 #define GPF6_out    (1<<(6*2))
12
13 #define GPF4_msk    (3<<(4*2))
14 #define GPF5_msk    (3<<(5*2))
15 #define GPF6_msk    (3<<(6*2))
16
17 /*
18  * S2,S3,S4对应GPF0、GPF2、GPG3
19  */
20 #define GPF0_in     (0<<(0*2))
21 #define GPF2_in     (0<<(2*2))
22 #define GPG3_in     (0<<(3*2))
23
24 #define GPF0_msk    (3<<(0*2))
25 #define GPF2_msk    (3<<(2*2))
26 #define GPG3_msk    (3<<(3*2))
27
28 int main()
29 {
30     unsigned long dwDat;
31
32     // LED1,LED2,LED4对应的3根引脚设为输出
33     GPFCON &= ~(GPF4_msk | GPF5_msk | GPF6_msk);
34     GPFCON |= GPF4_out | GPF5_out | GPF6_out;
35
36     // S2,S3对应的2根引脚设为输入
37     GPFCON &= ~(GPF0_msk | GPF2_msk);
38     GPFCON |= GPF0_in | GPF2_in;
39
40     // S4对应的引脚设为输入
41     GPGCON &= ~GPG3_msk;
42     GPGCON |= GPG3_in;
43
44     while(1)
45     {
46         //若Kn为0(表示按下),则令LEDn为0(表示点亮)
47         dwDat = GPFDAT;             // 读取GPF管脚电平状态
48
49         if (dwDat & (1<<0))        // S2没有按下
50             GPFDAT |= (1<<4);       // LED1熄灭
51         else
52             GPFDAT &= ~(1<<4);      // LED1点亮
53
54         if (dwDat & (1<<2))         // S3没有按下
55             GPFDAT |= (1<<5);       // LED2熄灭
56         else
57             GPFDAT &= ~(1<<5);      // LED2点亮
58
59         dwDat = GPGDAT;             // 读取GPG管脚电平状态
60
61         if (dwDat & (1<<3))         // S4没有按下
62             GPFDAT |= (1<<6);       // LED3熄灭
63         else
64             GPFDAT &= ~(1<<6);      // LED3点亮
65     }
66     return 0;
67 }

  Makefile

1 led_on.bin : head.S  sdram.c
2     arm-linux-gcc -g -c -o head.o head.S
3     arm-linux-gcc -g -c -o sdram.o sdram.c
4     arm-linux-ld -Ttext 0x30000000 -g head.o sdram.o -o sdram_elf
5     arm-linux-objcopy -O binary -S sdram_elf sdram.bin
6     arm-linux-objdump -D -m arm  sdram_elf > sdram.dis
7 clean:
8     rm -f sdram.dis sdram.bin sdram_elf *.o

  

原文地址:https://www.cnblogs.com/kele-dad/p/6879959.html

时间: 2024-10-11 17:12:04

二、存储管理器--SDRAM的相关文章

跟着韦老师学Linux学习笔记(二)-存储管理器

(1).CPU操作外设的基本原理图 由图可知,CPU要想访问一个外设,是要通过存储管理器来实现的.本篇中,主要是通过操作SDRAM来实现存储管理器的学习. (2).配置原理和步骤 访问一个芯片需要的配置信息: 1.  片选信号 2.  地址线 3.  数据线,即使数据宽度 4.  时钟\频率 5.  芯片相关的东西:对SDRAM来说 a)         行地址有多少位 b)         列地址有多少位 c)         BANK有多少位 操作一个SDRAM的步骤就是: a.  首先通过

【学神-RHEL7】1-17-ssm存储管理器和磁盘配额

本节所讲内容:       LVM 创建的基本步骤 pvcreate    vgcreate   lvcreate   LVM查看 pvs     pvscan     pvdisplay vgs     vgscan        vgdisplay lvs      lvscan       lvdisplay   LVM缩减 1)首先创建lv [[email protected] ~]#vgcreate vg1 /dev/sdb{1,2} [[email protected] ~]# lv

使用ssm(系统存储管理器)进行逻辑管

逻辑卷管理器(LVM)是一种极其灵活的磁盘管理工具,它让用户可以从多个物理硬驱创建 逻辑磁盘卷,并调整大小,根本没有停机时间.最新版本的CentOS/RHEL 7 现在随带系统存 储管理器(又叫 ssm),这是一种统一的命令行界面,由红帽公司开发,用于管理各种各样 的存储设备.目前,有三种可供 ssm 使用的卷管理后端:LVM.Btrfs 和Crypt 准备ssm,在CentOS/RHEL 7 上,你需要首先安装系统存储管理器.可以通过 rpm 或yum 工 具安装 首先我们来检查关于可用硬盘和

RHEL7/CentOS7新功能SSM存储管理器 操作实战

系统存储管理器的使用 SSM:系统存储管理器,是RHEL7/CentOS7 新增的功能,是一种统一的命令界面, 最新版本的CentOS/RHEL 7现在随带系统存储管理器(又叫ssm),这是一种统一的命令行界面,由红帽公司开发,用于管理各种各样的存储设备.目前,有三种可供ssm使用的卷管理后端:LVM.Btrfs和Crypt. [[email protected] ~]# date Mon Aug 22 23:11:31 CST 2016 [[email protected] ~]# yum i

深入理解Java虚拟机之读书笔记二 垃圾收集器

1.对象已死? a.引用计数算法:缺点是它很难解决对象之间的相互循环引用的问题,Java语言中没有选用它. b.根搜索算法(GC Roots Tracing):通过一系列的名为"GC Roots"的对象作为起始点,开始向下搜索,走过的路径称为引用链,当一个对象没有任何引用链相连,表面此对象不可达.在Java语言中,可作为GC Roots的对象包括: 虚拟机栈(栈帧中的本地变量表)中的引用的对象. 方法区中的类静态属性引用的对象. 方法区中的常量引用的对象. 本地方法栈中JNI的引用的对

存储管理器

一.汇编初始化部分(liubo.S) 1 .equ mem_control_address, 0x48000000 @宏定义,存储控制器起始地址 2 .equ sdram_address, 0x30000000 @宏定义,SDRAM的起始地址 3 4 @********************************** 5 .text @以下语句都属于代码段 6 .global _start @全局声明,表示_start是全局函数 7 8 @**************************

JZ2440开发板之存储管理器

2440可以外接8个设备,(8条片选信号), 要使用SDRAM,就要先进行设置,包括:数据位宽,行 列数,刷新周期,bank SRAM SDRAM DDR是三种存储设备,SRAM操作简单,直接给出地址信号就可以读取相应位的数据:SDRAM需要给出行列地址,操作复杂:2440不支持DDR SRAM , 网卡,NOR都是 RAM like 设备.可以接到0~5这6个片选信号上, 但是,SDRAM必须接到6~7 这两个片选信号上,因为这两个的寄存器针对SDRAM做了更好的处理

jvm系列 (二) ---垃圾收集器与内存分配策略

回顾 上文介绍了jvm的内存区域以及介绍了内存的溢出情况. jvm区域分为5个,线程独有:虚拟机栈,本地方法栈,程序计数器.线程共享:方法区,堆 两种溢出:栈溢出(StackOverflowError),OutOfMemoryError(OOM) 为什么学习垃圾收集 看起来jvm好像一切帮你做好,但是当垃圾收集成为系统达到更高并发量的瓶颈时,我们就需要对这种自动化的技术进行监控和调节. 根据实际应用需求,选择最优的收集方式才能更高的性能. 垃圾收集的区域 虚拟机栈,本地方法栈,程序计数器是线程私

浅谈设计模式(二):装饰器模式|中介模式|原型模式

装饰器模式(Decorator Pattern) 装饰器模式可用来给一个类动态添加功能,将其装饰成一个新的类.这就是装饰器的概念.看到这里我们可能会想,要达到这种效果,我们用子类继承父类不就可以了吗? 没错装饰器模式,本身是一种继承的替代方案.那既然是替代方案,那么自然就有它不一样的地方. 具体区别在哪里呢? 请看 装饰器模式更灵活:继承时父子类的关系是静态的,而装饰器模式是动态的,装饰类和被装饰类的关系是运行时候确认的 装饰类和被装饰类的耦合关系是松散的,各自可以独立变化 下面看看具体的代码.