ARM------ 存储控制器
初入领悟:
1、?bank、L-bank的概念 2、 s3c2440内部管理SDRAM寄存器配置 ? Frist part:原理分析 S3c2440为32位微处理器,其可访问空间为4G;但其中提供1G外设访问空间,这1G空间有8个bank组成;及平均每个bank有128M的访问空间;其中8bank的特性为: 1、?bank0~bank5支持外接SRAM、ROM等,bank6、bank7支持外接SRAM、ROM与SDRAM等; 2、?bank0~bank6的起始地址是固定 3、?bank7的起始地址可编程设定 4、?bank6、bank7大小可编程确定 5、?每个bank访问周期均可编程设定 6、?外接SDRAM是支持自刷新与省电模式 ? S3c2440向外引出27根地址线,可实现128M的寻找空间;那他怎么实现1G的空间范围访问呢?这就涉及到了nGCSx片选信号,由控制这几根信号线实现bank的切换,如下图所示: 左边为nor flash下;右边为nand flash; 说到此又想起一概念,就是有关于nor flash与nand flash启动方式; 一、norflash启动 简而言之,既是nor flash启动模式下cpu启动会执行地址0x00000000的指令此指令在使能了nor flash下是就是nor flash的首地址;其中原因为nor flash支持一种名为XIP的执行机制; 二、nandflash启动 nand flash下不支持XIP因此在执行nandflash的程序是,系统将会把nandflash的头4K(最大)启动代码拷贝至系统SRAM中既s3c2440中的steppingstone; ? 我使用的是GT2440开发板从原理图中可知: Bank6外接2片H57V2562GTR芯片; 在使用SDRAM时要设置到如下13个寄存器的操作: 各个寄存器值的设置参考开发板每一个bank所接的外设进行设置; 此设置参考示例程序: ? ??.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 (.long 汇编中词法,既long数据型) ? Second part:程序编写 现在开始编写代码,如我上诉一样启动时CPU将会报前4K程序拷贝至steppingstone中运行;现在编写的代码任务为将steppingstone中的代码拷贝回SDRAM中,并程序从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中 ??? ldr pc,=on_sdram?????????????????? @ 跳到SDRAM中继续执行 on_sdram: ??? ldr sp,=0x34000000???????????????? @ 设置堆栈 ??? bl? main halt_loop: ??? b?? halt_loop ? disable_watch_dog: @ 往WATCHDOG寄存器写0即可 ??? movr1,???? #0x53000000 ??? movr2,???? #0x0 ??? strr2,???? [r1] ??? movpc,???? lr????? ??????????????? @返回 ? copy_steppingstone_to_sdram: ??? @ 将Steppingstone的4K数据全部复制到SDRAM中去 ??? @Steppingstone起始地址为0x00000000,SDRAM中起始地址为0x30000000 ??? ??? mov r1,#0 ??? ldr r2,=SDRAM_BASE ??? mov r3,#4*1024 1:? ??? ldr r4,[r1],#4???? @ 从Steppingstone读取4字节的数据,并让源地址加4 ??? str r4,[r2],#4???? @ 将此4字节的数据复制到SDRAM中,并让目地地址加4 ??? cmp r1,r3????????? @ 判断是否完成:源地址等于Steppingstone的未地址? ??? bne1b????????????? @ 若没有复制完,继续 ??? movpc,???? lr????? @ 返回 ? memsetup: ??? @ 设置存储控制器以便使用SDRAM等外设 ? ??? movr1,???? #MEM_CTL_BASE?????? @ 存储控制器的13个寄存器的开始地址 ??? adrl??? r2,mem_cfg_val? ???????@ 这13个值的起始存储地址 ??? addr3,???? r1,#52???????????? @ 13*4 = 54 1:? ??? ldrr4,???? [r2],#4??????????? @ 读取设置值,并让r2加4 ??? strr4,???? [r1],#4??????????? @ 将此值写入寄存器,并让r1加4 ??? cmpr1,???? r3????????????????? @ 判断是否设置完所有13个寄存器 ??? bne1b??????????? ??????????????@ 若没有写成,继续 ??? movpc,???? lr????????????????? @ 返回 ? ? .align 4??????????????????????????? @ARM地址指针对齐伪指令 mem_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 ? C函数部分: #define GPFCON (*(volatile unsigned long *)0x56000050) #define GPFDAT (*(volatile unsigned long *)0x56000054) #define GPF4_out (1<<(4*2)) #define GPF5_out (1<<(5*2)) #define GPF6_out (1<<(6*2)) void wait(volatile unsigned long dly) { for(; dly > 0; dly--); } int main(void) { unsigned long i = 0; GPFCON = GPF4_out|GPF5_out|GPF6_out; // 将LED1,2,4对应的GPF4/5/ //6三个引脚设为输出 while(1) { wait(30000); GPFDAT = (~(i<<4)); // 根据i的值,点亮LED1,4 if(++i == 8) i = 0; } return 0; } 最后一步:Makefile sdram.bin : head.S?leds.c ??? arm-linux-gcc? -c -o head.o head.S ??? arm-linux-gcc -c -oleds.o leds.c ??? arm-linux-ld -Ttext0x30000000 head.o leds.o -o sdram_elf ??? arm-linux-objcopy -Obinary -S sdram_elf sdram.bin ??? arm-linux-objdump -D-m arm? sdram_elf > sdram.dis clean: ??? rm-f?? sdram.dis sdram.bin sdram_elf *.o 原理概念纯属个人见解,可能存在一定的不严谨性。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |