历史上的今天
返回首页

历史上的今天

今天是:2025年04月07日(星期一)

正在发生

2020年04月07日 | SDRAM-MEMORY CONTROLLER

2020-04-07 来源:eefocus

重点分析s3c2410复位后的内存映射,及其应用。


一、基本配置

    EDUKIT-III采用核心子板加扩展板的设计方式,我学习ARM9,所以采用s3c2410的核心子板。核心子板资源如下:

 

    MCU      : S3C2410A

    SDRAM    : 两片HY57V561620CT-H

    NOR FLASH: AM29LV160DB-90EC

 

    扩展板资源:

 

    NAND FLASH: K9F5608UOC

二、nand flash boot分析

 

    S3C2410支持从nor/nand flash、eeprom等rom类型的介质启动。现在我想做的是从外部nand flash启动,首先看datasheet第一部分:

 

NAND Flash Boot Loader

· Supports booting from NAND flash memory

· 4KB internal buffer for booting

· Supports storage memory for NAND flash memory after booting


 

    可以明确,首先,s3c2410支持从nand flash存储介质启动,其次,在硬件上,s3c2410除了提供相应的逻辑外,还提供了一个4K的sram作为buffer用于nand启动。最后,s3c2410支持从nand flash启动之后的内存分配形式(也就是说,从nand flash启动之后和从nor flash启动之后的内存分配形式是不同的。s3c2410支持这两种形式,可以说是相对于其他的MCU不同的地方。)

 

    然后看datasheet的第六部分:nand flash controller。overview中首先讲述了用nand flash代替nor flash作为启动介质的原因(成本低)。

 

    S3C2410X boot code can be executed on an external NAND flash memory. In order to support NAND flash boot loader, the S3C2410X is equipped with an internal SRAM buffer called ‘Steppingstone’. When booting, the first 4

KBytes of the NAND flash memory will be loaded into Steppingstone and the boot code loaded into Steppingstone will be executed.


    Generally, the boot code will copy NAND flash content to SDRAM. Using hardware ECC, the NAND flash data validity will be checked. Upon the completion of the copy, the main program will be executed on the SDRAM.


    可以很明显的看出,s3c2410x启动代码从外部nand flash启动的流程:上电复位后,s3c2410自动读取nand flash的前4KBytes的数据到内部sram buffer中,这个硬件的sram buffer被称为“Steppingstone”。然后执行下载到steppingstone的代码,这部分代码完成将nand flash的内容复制到sdram中,在复制时,利用硬件的ECC验证数据有效性。完成复制后,主程序就开始从sdram执行。

 

    过程应该是很清晰。但是首先怀疑的是,s3c2410如何实现自动读取nand flash的前4KBytes数据到内部sram buffer当中。网上为什么没人就这点产生疑问,并深入分析呢?我分析可能有两种方法:一是像at91rm9200一样,内部集成一个小的rom,固化代码,这部分代码的作用就是完成自动读取功能;二是完全用硬件实现。仔细看了框图,发现s3c2410只有internal sram buffer,并没有rom,所以最大可能就是硬件实现。看一下硬件框图figure6-1,可以发现hardware ECC编解码器,可以看到internal buffer(4KB),另外注意的一个地方是,存在着control state machine和buffer control,而且之间有粗体线链接。也就是说明了用一个控制状态机实现了自动读取4KB数据的过程,完全的硬件实现。如下图所示:

 

    明确了这个问题之后,对从硬件上电到nand flash启动就比较清晰了。而且,也就理解为什么vivi的stage1的head.S必须要小于4KB,因为internal sram buffer只有4KB。如果要完成一个比较复杂的bootloader,那也应该尽量简化stage1,完成基本的初始化之后,把剩余的工作量都放到将nand flash的代码搬移到sdram之后进行。


三 memory controller分析

 

    看datasheet第五部分。s3c2410比较特殊,支持1G的内存空间,分为8个bank,每个bank128MBytes,128MB×8=1GB。但是在这8个bank中,又有所不同,并且nand flash不对应任何bank,它是通过一组寄存器来访问的(nand flash的地址不在8个bank中,所以它不对应任何一个bank,它一般由处于高端地址的SFR区也就是特殊功能寄存器区来访问,地址一般在0x48000000以上),可看上面框图的register bank。

 

— Total 8 memory banks

   Six memory banks for ROM, SRAM, etc.

   Remaining two memory banks for ROM, SRAM, SDRAM, etc .

— Seven fixed memory bank start address

— One flexible memory bank start address and programmable bank size


    可以推断出,sdram应该在bank6,起始地址固定为128M*6=0x30000000,在此之后,就要根据sdram的大小和位宽来决定了,而且有个注意的地方是,bank7必须和bank6一样大小。参考figure5-1和table 5-1就非常清晰了。现在EDUKIT-III上用了两片SDRAM,型号是HY57V561620CT-H,查看datasheet,它是4banks×4M×16bit=256Mbits=32Mbytes,那么两片组合起来就是64MBytes,位宽是32bit,所以bank6的地址范围是[0x30000000-0x33ffffff],bank7的地址范围是[0x34000000-0x37ffffff],所以bank6的起始地址是固定的为0x30000000 ,但是bank6的大小事不固定的取决于板子上面实际的SDRAM的位宽和大小,而bank7因为是紧挨着bank6所以bank7的起始地址也是不固定的,大小同样也是不固定的。查看s3c2410 table 5-2,可以知道bank选择地址线为A[25:24]--->BA[1:0]。


   S3C2410提供了外接ROM、 SRAM、 SDRAM、 NOR  Flash、 NAND  Flash的接口。 S3C2410外接存储器的空间被分为8 个BANKS,每BANK容量为128M:当访问BANKx(x从0到7,对应的地址范围(x*128M到(x+1)*128M-1,BANK6、7有稍微差别)时,片选信号nGCSx有效。本文所用的开发板,使了64M的NAND Flash和64M的SDRAM,NAND Flash不对应任何BANK,它是通过几组寄存器来访问的,在上电后,NAND  Flash开始的4k数据被自动地复制到芯片内部一个被称为“Steppingstone”的RAM上。Steppingstone被映射为地址0,上面的4k程序完成必要的初始化;SDRAM使用BANK6,它的物理起始地址6*128M=0x30000000。

 

    关于sdram,还应该知道刷新频率和列宽度。HY57V561620CT-H datasheet中,有:

 

· Auto refresh and self refresh

· 8192 refresh cycles / 64ms

· Programmable Burst Length and Burst Type

  - 1, 2, 4, 8 or Full page for Sequential Burst

  - 1, 2, 4 or 8 for Interleave Burst

· Programmable CAS Latency ; 2, 3 Clocks


    所以刷新频率为64ms/8192=7.8125us。

 

    查看PIN DESCRIPTION,可以看出A0-A12为地址,其中ROW Address为RA[0:12],Column Address为CA[0-8],显然CAS的位数为9bits。


四、实验内容分析

 

    实验内容很简单,就是完成基本的初始化之后,把steppingstone的4K数据搬移到sdram中。然后在sdram中执行灯循环点亮程序。结合这个实验,也可以很清晰的明白,前面几个基本实验,从nand flash启动后,所有代码搬移到了steppingstone中,实际执行时也是在steppingstone中,也就是boot internal sram(4KB)中执行的,所以运行时域和加载时域都是0x00000000,设置的堆栈可以是1024,也可以是4096,但是注意一是最大为4096,二是保证不与可执行代码发生冲突。在这个程序中,运行时域和加载时域是不相同的。加载时域是0x00000000,但是运行时域是0x30000000。《s3c2410完全开发》对这个地方讲解不是太详细。经过实验,和王老师的帮助,弄清楚了到底怎么回事。现在关于运行时域和加载时域的具体分析如下:

 

    根据nand flash的特点,初始代码的加载时域为0x00000000,也就是当前PC的值为0x00000000,两种跳转指令b(l)等只能相对寻址,最大范围是+/-32MBytes,所以如果不改变PC的话,不可能能利用b或者bl跳转到sdram的空间中。跳转指令ldr则不受此寻址空间的限制,可以进行绝对寻址。需要了解的一个细节就是,链接后所有的标号都是基于运行地址的,比如运行地址为0x30000000,那么第一个标号_start地址就是0x30000000,所以可以利用ldr的绝对寻址来完成到sdram的跳转。下面根据编写的sdram的反汇编来进行分析:

先来分析这个工程中主Makefile的语法和含义:

CFLAGS := -I./include //gcc的编译选项,表示要在当前目录的include目录下查找相对应的头文件

LDFLAGS := -Ttext 0x30000000 //ld的链接选项,表示在链接时将整个工程的代码段也就是Text段加载到0x30000000

OBJS := $(patsubst %.s, %.o, $(wildcard arch/*.s)) //两个Makefile中函数的运用,在规则中,通配符会被自动展开。但在变量的定义和函数引用时,通配符将失效。这种情况下如果需要通配符有效,就需要使用函数“wildcard”,它的用法是:$(wildcard PATTERN...) 。在Makefile中,它被展开为已经存在的、使用空格分开的、匹配此模式的所有文件列表,而patsubst函数则是替换函数,上面的意思也就是将arch文件夹下面所有以.s结尾的文件全部展开,然后将这些以.s结尾的文件全部替换为以.o结尾

OBJS += $(patsubst %.c, %.o, $(wildcard init/*.c))

all: sdram

sdram: $(OBJS)

 $(LD) $(LDFLAGS) $^ -o $@.o  //将所有的.o文件也就是目标文件全部链接到sdram.o文件中

 $(OBJDUMP) -D $@.o >$@_s   //将链接成的目标文件sdram.o中的符号地址全部输出到sdram_s中

 $(OBJCOPY) -O binary -S $@.o $@  //利用objcopy将目标文件sdram.o转化为二进制的格式sdram


clean:

 find . -name "*.o" | xargs rm -f

 $(RM) sdram*

debug:

 @echo "OBJS: $(OBJS)"

# compile rules

%.o: %.s

 $(CC) $(CFLAGS) -c $< -o $@

%.o: %.c

 $(CC) $(CFLAGS) -c $< -o $@


在来分析在使用SDRAM之前需要初始化多个寄存器,这些寄存器很多都是类似的,并且由于我们只是使用BANK6所以大部分寄存器不用理会。一般我们将初始化的一些代码,主要是对寄存器操作的代码利用汇编代码来编写:

@ WDT Register

.equ WDTCON,  0x53000000

@ Memory Control Register Base Address

.equ MEM_CTL_BASE, 0x48000000

@ Sdram Base Address

.equ SDRAM_BASE, 0x30000000

@ Stack top address

.equ stack_top,  0x34000000

@

@ start

@

.text

.global _start

_start:

 @ disable watch dog timer

 mov r0, #WDTCON

 mov r1, #0x0

 str r1, [r0]

 @ memory setup 初始化SDRAM寄存器

 bl memsetup 

 @ copy the 4K code from steppingstone 将steppingstone的4KB的数据复制到sdram的起始处

 bl copy_steppingston_to_sdram

 @ jump to sdram space

 ldr pc, =setup_stack //为什么将setup_stack标号的地址赋给pc,就能跳转到SDRAM中执行,因为在前面利用copy_steppingston_to_sdram已经将程序从steppingstone复制到了SDRAM中来,所以当前语句的下一句也就是在SDRAM中要执行的下一句

setup_stack:

 ldr sp, =stack_top //设置堆栈,一般将堆栈设置在BANK7中最大只能为4K

 bl main //跳转到主函数去执行,此时main函数也已经复制到SDRAM中来

stop:

 b stop

@

@ sub routines

@

@ r1: src base address

@ r2: dst base address

@ r3: data block length

copy_steppingston_to_sdram: //将steppingstone中4KB的内容复制到sdram中

 mov r1, #0x00000000 //基地址也就是steppingstone的地址

 ldr r2, =SDRAM_BASE //目的地址也就是sdram的地址

 mov r3, #4096 //复制的字节数也就是4KB

1:

 @ auto-indexing

 @ first transfer, and then write back to the base register r1

 ldr r4, [r1], #4 //每次复制4个字节

 str r4, [r2], #4

 @ r1 is equal to counter

 cmp r1, r3

 bne 1b

 mov pc, lr

@ r1: memory control register base address

@ r2: memory control register table address

@ r3: r1+13 words(because there is 13 registers)

memsetup: //SDRAM寄存器设置初始化

 mov     r1, #MEM_CTL_BASE //与SDRAM相关的寄存器是从0x48000000地址开始的,每个寄存器占4个字节

 adrl    r2, mem_cfg_val //adrl中等范围的地址读取,将mem_cfg_val标号表示的地址值读取到r2寄存器中来

 add     r3, r1, #13*4 //因为总共有13个寄存器,每个寄存器占4个字节,r3作为循环的结束条件

1:

 @ write initial values to registers

 ldr     r4, [r2], #4 //取出r2寄存器中的地址值对应的值赋给r4,然后r2加上4,指向下一个初始值

 str     r4, [r1], #4 //将r4的值赋值给r1对应的寄存器,然后将r1加上4,指向下一个寄存器

 cmp     r1, r3

 bne     1b

        mov     pc, lr //返回到调用处

.align 4

mem_cfg_val://相当于定义一个寄存器初值表,将每个寄存器的初始值通过一个标号全部定义在一起,因为每个寄存器的地址是规律的也就是相差4个字节所以可以很方便的通过查表来赋值

 .long 0x22111110 @ 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 0x008e07a3 @ REFRESH

 .long 0x000000b2 @ BANKSIZE

 .long 0x00000030 @ MRSRB6

 .long 0x00000030 @ MRSRB7

.end


现在来分析这13个寄存器的初始值,寄存器每位分别表示什么含义:


1.BWSCON:对应BANK0-BANK7,每BANK使用4位。这4位分别表示:

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

SRAM,此位为1。

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

c.DWx:使用两位来设置存储器的位宽:00-8位,01-16位,10-32位,

11-保留。

d.比较特殊的是BANK0对应的4位,它们由硬件跳线决定,只读。 对于本开发板,使用两片容量为32Mbyte、位宽为16的SDRAM组成容量为64Mbyte、位宽为32的存储器,所以其BWSCON相应位为:0010。对于本开发板,BWSCON可设为0x22111110:其实我们只需要将BANK6对应的4位设为0010即可,其它的是什么值没什么影响,这个值是参考手册上给出的。


2.BANKCON0-BANKCON5:我们没用到,使用默认值0x00000700即可 


3.BANKCON6-BANKCON7:设为0x00018005 ,在8个BANK中,只有BANK6和BANK7可以使用SRAM或SDRAM,所以BANKCON6-7与BANKCON0-5有点不同:

a.MT([16:15]):用于设置本BANK外接的是SRAM还是SDRAM:SRAM-00,SDRAM-11

b.当MT=11时,还需要设置两个参数:

Trcd([3:2]):RAS to CAS delay,设为推荐值01,因为在这里我们知道RAS是0:12也就是13位,而CAS是0:8也就是9位,所以delay就是3

SCAN([1:0]):SDRAM的列地址位数,对于本开发板使用的SDRAM HY57V561620CT-H,列地址位数为9,所以SCAN=01。如果使用其他型号的SDRAM,您需要查看它的数据手册来决定SCAN的取值:00-8位,01-9位,10-10位。


4.REFRESH(SDRAM refresh control register):设为0x008e0000+ R_CNT ,其中R_CNT用于控制SDRAM的刷新周期,占用REFRESH寄存器的[10:0]位,23位为SDRAM Refresh Enable一般为1允许自动和自我刷新,22位为SDRAM刷新的模式,是auto还是self,一般我们选择auto.

它的取值可如下计算(SDRAM时钟频率就是HCLK): 

R_CNT = 2^11 + 1 – SDRAM时钟频率(MHz) * SDRAM刷新周期(uS)

在未使用PLL时,SDRAM时钟频率等于晶振频率12MHz;SDRAM的刷新周期在SDRAM的数据手册上有标明,在本开发板使用的SDRAM HY57V561620CT-H的数据手册上,可看见这么一行“8192 refresh cycles / 64ms”:所以,刷新周期=64ms/8192 = 7.8125 uS。 对于本实验,R_CNT = 2^11 + 1 – 12 * 7.8125 = 1955,  REFRESH=0x008e0000 + 1955 = 0x008e07a3.


5.BANKSIZE:0x000000b2

推荐阅读

史海拾趣

Emerging Display Technolgies公司的发展小趣事

某新兴显示技术公司,将量子点技术应用于显示屏中,成功提升了显示效果和色彩表现。量子点技术通过精确控制发光材料的尺寸和组成,实现了更广的色域覆盖和更高的色彩准确性。这一技术的应用,使得显示屏在色彩还原、对比度等方面有了显著提升,为用户带来了更加真实、生动的视觉享受。

ETI Systems公司的发展小趣事

ETI Systems深知人才是企业发展的核心竞争力。因此,公司一直注重人才培养和引进工作。通过建立完善的人才培养机制和激励机制,ETI Systems吸引了一批具有丰富经验和专业技能的优秀人才加入公司。同时,公司也积极为员工提供广阔的发展空间和良好的工作环境,让员工能够充分发挥自己的才能和创造力。这种重视人才的企业文化,为ETI Systems的长期发展提供了有力的人才保障。

Adaptive Networks Inc公司的发展小趣事

随着公司业务的不断发展壮大,ETI Systems开始将目光投向国际市场。公司积极参加国际电子产品展览和技术交流活动,与来自世界各地的客户和合作伙伴建立了紧密的联系。同时,ETI Systems也加大了在海外市场的投入力度,通过设立分公司和办事处等方式,进一步拓宽了国际市场渠道。这种国际化战略的实施,为ETI Systems的持续发展注入了新的活力。

B&K Precision公司的发展小趣事

随着业务的不断发展,科恩和班意识到电子测试和测量领域的巨大潜力。1951年,他们将公司更名为B&K Precision,并开始扩展业务,涉足其他电子测试和测量领域。工程师们凭借在电视测试设备领域的丰富经验,不断研发新产品,获得了多项专利,并推动公司迅速成为全球电子测量领域的领导者。

GREEGOO公司的发展小趣事
在需要时钟分路的地方,使用专用的时钟分路、放大、整形的芯片,以确保时钟信号的无衰减传输。
Acmelux Taiwan Inc公司的发展小趣事

Acmelux Taiwan Inc公司深知人才是企业发展的根本。因此,公司高度重视人才培养和团队建设。通过设立完善的培训体系、提供广阔的发展平台以及实施激励机制,Acmelux吸引了大批优秀人才的加入。这些人才在公司的发展过程中发挥了重要作用,为公司创造了巨大的价值。同时,公司还注重团队建设,通过定期的团建活动、培训等方式,增强员工的凝聚力和向心力,为公司的发展提供了有力的保障。

问答坊 | AI 解惑

嵌入式TCP/IP的优化设计与硬件实现

摘要 提出一种嵌入式系统中实现TCP/IP的解决方案。通过优化设计清晰的TCP/IP和应用层接口、防止多余的内存拷贝和实现数据包整序重发及窗口控制,分析在嵌入式系统上实现TCP/IP的速度、程序大小、内存大小以及编译嚣等特点,并针对这些特,最提 ...…

查看全部问答>

模电数电仿真软件练习

经典模数电仿真软件multism9仿真试验…

查看全部问答>

逻辑电平接口设计规范

逻辑电平接口设计规范…

查看全部问答>

介绍鑫迈的晶体管

本帖最后由 jameswangsynnex 于 2015-3-3 19:58 编辑 最近和一些做新能源行业,特别是做节能灯的朋友沟通。一些晶体管有很好的应用。 …

查看全部问答>

谁给推荐一个AT9200 带WINCE系统的开发板

找了半天,都只有LINUX系统。没有CE。 谁用过9200CPU的WINCE的板子? …

查看全部问答>

竞赛抢答器的汇编语言解释

有关竞赛抢答器的汇编语言解释 有部分看不懂 麻烦高手给我解释下. rr: shr al, l     inc cl     jnc rr     mov al,cl     xlat     mov dx,io8255c     out dx,al   ...…

查看全部问答>

现在家用cpu是32bit,也就是一次寻址的数据是32bit的,那么大小字节序是还有意义?

如题? 最近想到这个问题,拿出来讨论一下。 大小字节序是字节上的问题。 假如说我一次读写的位宽超为32bit 那么是否说就没有大小字节序的问题了?…

查看全部问答>

linux学习内容顺序的困惑

在网上看了些学习指导的。 大概就是先学好c语言,然后是数据结构。 但是接下来我就有点困惑了,是先学操作系统原理和ARM呢, 还是先学鸟哥的私房菜和UNIX环境高级编程。 我感觉操作系统和ARM貌似是学linux内核时才要用到~ 还有个单片机,也不知 ...…

查看全部问答>

检测IGBT模块是否损坏的方法

谁能告诉我检测IGBT模块是否损坏的简单方法是什么?非常感谢…

查看全部问答>