嵌入式存储控制器

本文围绕S3C2410/S3C2440存储控制器展开,介绍了其访问外设的原理,包括地址空间布局、与外设的关系及寄存器使用方法。还给出使用SDRAM的操作实例,说明了代码设置存储控制器、复制程序到SDRAM并执行的过程,解决了程序大于4KB时的运行问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  • 了解 S3C2410/S3C2440 地址空间的布局
  • 掌握如何通过总线形式访问扩展的外设,比如内存、NOR Flash、网卡等

现在特别想搞清楚内存的布局是如何的?

总线的使用方法是嵌入式底层开发的基础,了解它之后,再根据外设的具体特性,就可以驱动该外设了。

使用总线去和外设交互,而不是通过引脚,引脚还是太底层了,操作起来可能也比较麻烦吧。

使用存储控制器访问外设的原理

妈了个鸡的,写错了,写成了存储器访问外设,应该是存储控制器访问外设的原理。

所以什么是 “存储控制器” 呢?

S3C2410/S3C2440 的地址空间

S3C2410/S3C2440 的 “存储控制器” 提供了访问外部设备所需的信号,它有如下特性:

  • 支持小字节序、大字节序(通过软件选择);
  • 每个 BANK 的地址空间为 128MB,总共 1GB(8 BANKs);(BANK 是啥?)
  • 可编程控制的总线位宽(8/16/32-bit),不过 BANK0 只能选择两种位宽(16/32-bit);
  • 总共 8 个 BANK,BANK0~BANK5 可以支持外接 ROM、SRAM 等,BANK6~BANK7 除可以支持 ROM、SRAM 外,还支持 SDRAM 等;
  • BANK0~BANK6 共 7 个 BANK 的起始地址是固定的;
  • BANK7 的起始地址可编程选择;
  • BANK6、BANK7 的地址空间大小是可编程控制的;
  • 每个 BANK 的访问周期均可编程控制;
  • 可以通过外部的“wait”信号延长总线的访问周期;
  • 在外接 SDRAM 时,支持自刷新(self-refresh)和省电模式(power down mode)。

S3C2410/S3C2440 对外引出的 27 根地址线 ADDR0~ADDR26 的访问范围只有 128MB,那么如何达到上面所说的 1GB 的访问空间呢?

CPU 对外还引出了 8 根片选信号 nGCS0~nGCS7,对应于 BANK0~BANK7,当访问 BANKx 的地址空间时,nGCSx 引脚输出低电平用来选中外接的设备。

这样,每个 nGCSx 对应 128MB 地址空间,8 个 nGCSx 信号总共就对应了 1GB 的地址空间。

这 8 个 BANK 的地址空间如下图所示:

左边对应不使用 NAND Flash 作为启动设备(单板上不接 NAND_BOOT 跳线)时的地址空间布局;

右边对应使用 NAND Flash 作为启动设备(单板上不接 NAND_BOOT 跳线)时的地址空间布局。

S3C2410/S3C2440 作为 32 位的 CPU,可以使用的地址范围理论上达到 4GB。

我知道了 NAND Flash 启动的话会先把 NAND Flash 的前 4KB 拷贝到 SRAM 中去执行。

除去上述用于连接外设的 1GB 地址空间外,还有一部分是 CPU 内部寄存器的地址,剩下的地址空间没有使用。

注意:这里说的是物理地址。

没太看懂啥叫 使用/不使用 NAND Flash?

刚才说的是外设地址物理地址空间是在:0x00000000~0x40000000,下面讲的就是寄存器的地址了。

卧槽,寄存器有这么多吗?

S3C2410/S3C2440 的寄存器地址范围都处于 0x48000000~0x5FFFFFFF,各功能部件的寄存器大体相同,如下表所示:

存储控制器与外设的关系

本书所用开发板使用了存储控制器的 BANK0~BANK6,分别外接了如下设备:

  • NOR Flash
  • IDE 接口
  • 10M 网卡 CS8900A
  • 100M 网卡 DM9000
  • 扩展串口芯片 16C2550
  • SDRAM

连线方式如下图所示:

选一个相对复杂的 BANK —— 扩展串口作为例子。

(1)它使用 nGCS5,起始地址为 0x28000000(见图 6.1,nGCS5 是片选信号)。

(2)nCSA = ADDR24 || nGCS5,nCSB = !ADDR24 || nGCS5。当 ADDR24 和 nGCS5 均为低电平时选中扩展串口A;当 ADDR24 为高电平、nGCS5 为低电平时选中扩展串口 B。(nGCS5 要为低电平,才去选择扩展串口,然后根据 ADDR24 的高低电平选择对应的扩展串口

(3)CPU 的 ADDR0~ADDR2 连接到扩展串口的 A0~A2,所以访问空间为 8 字节。(怎么他妈就所以出来了?我咋没看出来呢?

我知道了,基础地址是 0x28000000,那么还有 A0~A2 组合起来可以有 8 个不同的字节地址,就是这样的

综上所述,扩展串口 A 的访问地址空间为:0x28000000~0x28000007;扩展串口 B 的访问空间为:0x29000000~0x29000007(bit24 为 1)。

BANK0~BANK5 的连接方式都是相似的,BANK6 连接 SDRAM 时复杂一点,CPU 提供了一组用于 SDRAM 的信号。(还要专门的信号)

  • SDRAM 时钟有效信号 SCKE;
  • SDRAM 时钟信号 SCLK0/SCLK1;
  • 数据掩码信号 DQM0/DQM1/DQM2/DQM3;
  • SDRAM 片选信号 nSCS0(它与 nGCS6 是同一引脚的两个功能);
  • SDRAM 行地址选通脉冲信号 nSRAS;
  • SDRAM 列地址选通脉冲信号 nSCAS;
  • 写允许信号 nWE(它不是专用于 SDRAM 的)。

SDRAM 的内部是一个存储阵列,阵列就如同表格一样,将数据 “填” 进去。

和表格检索的原理一样,先指定一个行(Row),再指定一个列(Column),就可以准确地找到所需要的单元格,这就是 SDRAM 寻址的基本原理。

这个单元格被称为存储单元,这个表格(存储阵列)就是逻辑 Bank(Logical Bank,下文简称 L-Bank),SDRAM 一般含有 4 个 L-Bank。SDRAM 的逻辑结构如下图:

可以想象,对 SDRAM 的访问可以分为如下 4 个步骤。

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

(2)SDRAM 中有 4 个 L-Bank,需要两根地址信号来选中其中一个,从图 6.2 可知使用 ADDR24、ADDR25 作为 L-Bank 的选择信号。

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

根据 SDRAM 芯片的列地址线数目设置 CPU 的相关寄存器后,CPU 就会从 32 位的地址中自动分出 L-Bank 选择信号、行地址信号、列地址信号,然后先后发出行地址信号、列地址信号。L-Bank 选择信号在发出行地址信号的同时发出,并维持到列地址信号结束。

在图 6.2 中,行地址、列地址共用地址线 ADDR2~ADDR14(BANK6 位宽为 32,ADDR0/1 没有使用),使用 nSRAS,nSCAS 两个信号来区分它们。

比如在本开发板中,使用两根地址线 ADDR24、ADDR25 作为 L-Bank 的选择信号;SDRAM 芯片 K4S561632 的行地址数为 13,列地址数为 9,所以当 nSRAS 信号有效时,ADDR2~ADDR14 上发出的是行地址信号,它对应 32 位地址空间的 bit[23:11];当 nSCAS 信号有效时,ADDR2~ADDR10 上发出的是列地址信号,它对应的 32 位地址空间的 bit[10:2];由于图中 BANK6 以 32 位的宽度外接 SDRAM,ADDR0、ADDR1 恒为 0,不参与译码。

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

开发板中使用了两片 16 位的 SDRAM 芯片并联组成 32 位的位宽,与 CPU 的 32 根数据线(DATA0~DATA31)相连。

(两个 16 位的 SDRAM 组成 32 位的位宽)

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

(这个所以又是怎么来的?23:11,然后 10:2,则 23:2,一共 22 位)

(11 1111 1111 1111 1111 1111,就是 3 F F F F F,组合起来就是 33FFFFF,嘻嘻)

对图 6.2 中连接的外设,它们的访问地址(物理地址)如下表所示:

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

(也就是说,还是通过配置寄存器的方法来选择不同的 BANK)

存储控制器共有 13 个寄存器,BANK0~BANK5 只需要设置 BWSCON 和 BANKCONx(x 为 0~5)两个寄存器;

BANK6、BANK7 外接 SDRAM 时,除了 BWSCON 和 BANKCONx(x 为 6、7)外,还要设置 REFRESH、BANKSIZE、MRSRB6、MRSRB7 等 4 个寄存器。

(这他妈的,存储控制器的地址空间是 0x48000000~0x48000030,这个和寄存器有关系吗?)

下面分类说明(“[y:x]”表示占据了寄存器的位 x、x+1、...、y):

1. 位宽和等待控制寄存器 BWSCON(BUS WIDTH & WAIT CONTROL REGISTER)

BWSCON 中每 4 位控制一个 BANK,最高 4 位对应 BANK7、接下来 4 位对应 BANK6,依次类推。

2. BANK 控制寄存器 BANKCONx(BANK CONTROL REGISTER,x 为 0~5)

这几个寄存器用来控制 BANK0~BANK5 外接设备的访问时序,使用默认的 0x0700 即可满足本开发板所接各外设的要求。

3. BANK 控制寄存器 BANKCONx(BANK CONTROL REGISTER,x 为 6~7)

在 8 各 BANK 中,只有 BANK6 和 BANK7 可以外接 SRAM 或 SDRAM,所以 BANKCON6~BANKCON7 与 BANKCON0~BANK5 有点不同。

4. 刷新控制寄存器 REFRESH(REFRESH CONTROL REGISTER):设为 0x008C0000 + R_CNT

5. BANKSIZE 寄存器 RERESH(BANKSIZE REGISTER)

6. SDRAM 模式设置寄存器 MRSRBx(SDRAM MODE REGISTER SET REGISTER,x 为 0~7)

(写的太细了,就不继续往下了,先留着吧)

存储控制器操作实例:使用 SDRAM

代码详解及程序的复制、跳转过程

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

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

源代码中包含两个文件:head.S、leds.c。

leds.c 是讲 GPIO 时的那个程序,让 4 各 LED 从 0~15 轮流计数。

重点在 head.S,它的作用是设置 SDRAM,将程序复制到 SDRAM,然后跳转到 SDRAM 继续执行。

【程序】

【解释】

执行 make 指令生成可执行文件 sdram.bin 后,下载到板子上运行。

可以发现与 leds 程序相比,LED 闪烁得更慢,原因是外部 SDRAM 的新能比内部 SRAM 差一些。

把程序从性能更好的内部 SRAM 移到外部 SDRAM 中去,是否多次一举呢?

内部 SRAM 只有 4KB 大小,如果程序大于 4KB,那么就不能指望完全利用内部 SRAM 来运行了,得想办法把存储在 NAND Flash 中的代码复制到 SDRAM 中去。对于 NAND Flash 中的前 4KB,芯片自动把它复制到内部 SRAM 中,可以很轻松地再把它复制到 SDRAM 中(实验代码的 copy_steppingstone_to_sdram 就有此功能),要复制 4KB 后面的代码需要使用 NAND Flash 控制器来读取 NAND Flash,这是后面的内容。

转载于:https://www.cnblogs.com/tuhooo/p/11174025.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值