FS2410 开发板上 Nand Flash 到内存的代码搬移

发布者:心灵舞动最新更新时间:2016-07-20 来源: eefocus关键字:FS2410  Nand  Flash  内存 手机看文章 扫描二维码
随时随地手机看文章
一、目的

   前面做过一个实验,搬移 Nand Flash 里的前 4k 代码到内存指定位置,这其实是把

SRAM 从 0x40000000 开始的 4K 代码复制到 SDRAM 的指定位置,并没有涉及到对 Nand

Flash 的操作。究其原因,开发板上电后,Nand Flash 开始的前 4K 数据会被自动复制到

SRAM 0x40000000 开始的 4K 区域里,这个区域被称为 "Steppingstone"。那我们这次就来

操作 Nand Flash,读取它 4K 后的代码到 SDRAM 指定位置,并执行 SDRAM 中的代码。

二、代码

   通过前面做的几个实验,我们已经熟悉了 ARM 开发的基本流程,这可以让我们更关注于

代码的逻辑。好,先来分析文件 head.s:

   @ 文件 head.s

   @ 作用:关闭看门狗、SDRAM 的初始化设置、搬移 Nand Flash 4K 以后

   @ 的代码到 SDRAM 的指定位置、执行 SDRAM 中的代码

   .text

   .global _start

   _start:

    ldr r0, =0x53000000 @ Close Watch Dog Timer

    mov r1, #0x0

    str r1, [r0]

  

    bl  memory_setup  @ Initialize memory setting

    bl  flash_to_sdram @ Copy code to sdram

    

    ldr sp, =0x34000000 @ Set stack pointer

    ldr pc, =main              @ execute the code in SDRAM

  

   @ 文件 mem.s

   @ 作用:SDRAM 的初始化设置

   @ 关于初始化的更多细节,请参考我的前一篇随笔

   .global memory_setup         @ 导出 memory_setup, 使其对链接器可见

   memory_setup:

    mov  r1, #0x48000000

    adrl r2, mem_cfg_val

    add  r3, r1, #13*4

   1: 

    @ write initial values to registers

    ldr  r4, [r2], #4

    str  r4, [r1], #4

    cmp  r1, r3

    bne  1b

    mov  pc, lr

    

    .align 4

   mem_cfg_val:

    .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 9bit

    .long 0x008e07a3 @ REFRESH

    .long 0x000000b2 @ BANKSIZE

    .long 0x00000030 @ MRSRB6

    .long 0x00000030 @ MRSRB7

   @ 文件 flash.s

   @ 作用:设置 Nand Flash 的控制寄存器、读取 Nand Flash

   @ 中的代码到 SDRAM 的指定位置

   .equ NFCONF, 0x4e000000

   .equ NFCMD,  0x4e000004

   .equ NFADDR, 0x4e000008

   .equ NFDATA, 0x4e00000c

   .equ NFSTAT, 0x4e000010

   .equ NFECC,  0x4e000014

   .global flash_to_sdram

   flash_to_sdram:

        @ Save return addr

        mov r10,lr

    

        @ Initialize Nand Flash

        mov r0,#NFCONF

        ldr r1,=0xf830

        str r1,[r0]

   

        @ First reset and enable Nand Flash

        ldr r1,[r0]

        bic r1, r1, #0x800

        str r1,[r0]

   

        ldr r2,=NFCMD

        mov r3,#0xff

        str r3,[r2]

    

        @ for delay

        mov r3, #0x0a

   1:

        subs r3, r3, #1

        bne 1b

  

   @ Wait until Nand Flash bit0 is 1

   wait_nfstat:

        ldr r2,=NFSTAT

        ldr r3,[r2]

        tst r3,#0x01

        beq wait_nfstat

          

        @ Disable Nand Flash

        ldr r0,=NFCONF

        ldr r1,[r0]

        orr r1,r1,#0x8000

        str r1,[r0]

   

        @ Initialzie stack

        ldr sp,=4096

  

        @ Set arguments and call 

        @ function nand_read defined in nand_read.c

        ldr r0,=0x30000000

        mov r1,#4096

        mov r2,#1024

        bl nand_read

   

        @ return

        mov pc,r10

   /* 文件 nand_read.c

    * 作用:从 Nand Flash 中读取一块数据到 SDRAM 中的指定位置

    */

   #define NFCONF (*(volatile unsigned long *)0x4e000000)

   #define NFCMD  (*(volatile unsigned long *)0x4e000004)

   #define NFADDR (*(volatile unsigned long *)0x4e000008)

   #define NFDATA (*(volatile unsigned long *)0x4e00000c)

   #define NFSTAT (*(volatile unsigned long *)0x4e000010)

   #define NFECC  (*(volatile unsigned long *)0x4e000014)

  

   #define NAND_SECTOR_SIZE 512

   #define NAND_BLOCK_MASK  0x1ff

  

   void wait_idle() {

     int i;

     for (i = 0; i < 50000; ++i) ;

   }

  

   int nand_read(unsigned char *buf, unsigned long start_addr, int size){

     int i, j;

     /*

      * detect the argument

      */ 

     if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {

       return -1;    

     }

   

     /* chip Enable */

     NFCONF &= ~0x800;

     for (i=0; i<10; i++) {

       ;

     }

   

     for (i=start_addr; i < (start_addr + size); i+=NAND_SECTOR_SIZE) {

       NFCMD = 0;

   

       /* Write Address */

       NFADDR = i & 0xff;

       NFADDR = (i >> 9)  & 0xff;

       NFADDR = (i >> 17) & 0xff;

       NFADDR = (i >> 25) & 0xff;

   

       wait_idle();

   

       for(j=0; j < NAND_SECTOR_SIZE; j++) {

         *buf++ = (NFDATA & 0xff);

       }

     }

   

     NFCONF |= 0x800;    /* chip disable */

     return 0;

   }

注:Nand Flash 的设置和读取数据的主要流程简单介绍如下:

   1. NFCONF = 0xf830

   2. 在第一次操作NAND Flash前,通常复位一下:

      NFCONF &= ~0x800 (使能NAND Flash)

      NFCMD = 0xff (reset命令)

      循环查询NFSTAT位0,直到它等于1

   3. NFCMD = 0 (读命令)

   4. 这步得稍微注意一下,请打开K9F1208U0M数据手册第7页,那个表格列出了在地址操

      作的4个步骤对应的地址线,A8没用到:

      NFADDR = addr & 0xff

      NFADDR = (addr>>9) & 0xff (注意了,左移9位,不是8位)

      NFADDR = (addr>>17) & 0xff (左移17位,不是16位)

      NFADDR = (addr>>25) & 0xff (左移25位,不是24位)

   5. 循环查询NFSTAT位0,直到它等于1

   6. 连续读NFDATA寄存器512次,得到一页数据(512字节)

   7. NFCONF |= 0x800 (禁止NAND Flash)

   /* 文件 sdram.c

    * 作用:循环点 FS2410 开发板上的 D9、D10、D11、D12

    * 四个发光二极管。

    */

   #define GPFCON (*(volatile unsigned long *)0x56000050)

   #define GPFDAT (*(volatile unsigned long *)0x56000054)

  

   int main()

   {

     int i,j;

     while(1) {

       for (i = 0; i <4; ++i) {

         GPFCON = 0x1<<(8+i*2);

         GPFDAT = 0x0;

  

         // for delay

         for(j=0;j<50000;++j) ;

       }

     }

   }

   /*

    * 文件 nand.lds (lds 文件是连接脚本)

    */

   SECTIONS {

       first  0x00000000 : { head.o mem.o flash.o nand_read.o }

       second 0x30000000 : AT(4096) { sdram.o }

   }

  

注:这个链接脚本是用来传给链接器的,其作用如下:

  1. 将 head.o 放在 0x00000000 开始的地址处, mem.o、flash.o、and_read.o

     依次放在 head.o 后面, 它们的运行地址是 0x00000000

  2. 将 sdram.o 放在地址 4096 开始处, 但它的运行地址是 0x30000000, 运行前需要

     从 4096 处复制到 SDRAM 的 0x300000000 处

完整的连接脚本文件形式如下:

SECTIONS {

...

secname start BLOCK(align) (NOLOAD) : AT(ldadr) {contents} >region :phdr =fill

...

}

并非每个选项都是必须的,仅从 nand.lds 用到的来看:

(1) secname: 段名,对于 nand.lds, 段名为 first 和 second

(2) start: 本段的运行时地址,如果没有 AT(xxx),则本段的存储地址也是 start

(3) AT(ldadr): 定义本段存储(加载)的地址

(4) {contents}: 决定哪些内容放在本段,可以是整个目标文件,也可是目标文件中的某段

   # 文件 Makefile

   # 由代码文件生成目标文件,并依据连接脚本 nand.lds 连接目标文件,

   # 最后将连接生成的目标文件转换成二进制格式

   sdram:head.s flash.s mem.s sdram.c

        arm-linux-gcc -c -o head.o head.s

        arm-linux-gcc -c -o mem.o mem.s

        arm-linux-gcc -c -o flash.o flash.s

        arm-linux-gcc -c -o nand_read.o nand_read.c

        arm-linux-gcc -c -o sdram.o sdram.c

        arm-linux-ld  -Tnand.lds head.o mem.o flash.o nand_read.o sdram.o -o sdram_tmp.o

        arm-linux-objcopy -O binary -S sdram_tmp.o sdram

   clean:

        rm -f *.o

        rm -f sdram

三、编译、烧写、测试

Make 一下就会生成我们要的文件 sdram, 将其通过 JTAG 烧入 Nand Flash ,Reset

一下开发板, 呵呵,欣赏我们的成果吧!

关键字:FS2410  Nand  Flash  内存 引用地址:FS2410 开发板上 Nand Flash 到内存的代码搬移

上一篇:S3C2410串口波特率的计算
下一篇:FS2410 开发板上的内存搬移实验

推荐阅读最新更新时间:2024-03-16 15:01

集邦:西安疫情将影响三星NAND Flash生产部分稼动率
市调机构集邦咨询(TrendForce)在其最新报告中指出,三星目前受到西安疫情封城的影响主要在于人力轮班安排的困难,若疫情未能得到妥善控制,不能排除将冲击近期厂区内的生产稼动率,导致产出小幅下降。 集邦咨询指出,由于人流管制等措施迫使三星必须以有限的人力规模继续生产。目前该公司正积极进行调整以降低对产出的冲击,而当地政府预期会在一到两周内恢复正常,不过不排除疫情未能得到妥善控制的情况发生。 据悉,三星日前发布公告称因疫情原因,将暂时调整中国西安工厂的运营,尽可能保护员工的安全。同时,公司将采取一切必要措施,包括利用自己的全球制造网络,来确保客户不受本次停滞运营的影响。 而后业内消息称收到三星发函,预计NAND产品制造能力可能会受
[手机便携]
Spansion与SK海力士宣布NAND战略合作
2012年4月5日,中国上海 –Spansion公司(纽约证交所代码:CODE)与SK海力士公司近日宣布结成战略同盟,并针对嵌入式应用市场发布4x、3x、2x节点Spansion SLC NAND产品。基于双方合作开发的首款Spansion® SLC NAND产品将于2012年第二季度面世。作为合作的一部分,双方将同时签订专利交互授权协议。 Spansion与SK海力士宣布NAND战略合作 Spansion的NAND产品主要针对诸如汽车电子、工业电子以及通信等嵌入式应用领域,以补充NOR产品供应,并提供完整产品解决方案。Spansion公司的高性能、高可靠性SLC NAND产品系列将提供广受业界认同的客户支持以及产品长期
[嵌入式]
Spansion与SK海力士宣布<font color='red'>NAND</font>战略合作
内存需求增长和消费电子市场均不振,三星一季度业绩不变
据外媒报道,受全球范围内蔓延的疫情影响,三星消费电子产品销售被削弱。同时,在疫情推动下,在家上课、办公需求激增,刺激三星内存芯片需求增长。综合作用下,三星第一季度利润与去年同期相比,可能保持不变。 存储需求的增长是一季度相关厂商的普遍感受。此前就曾有外媒预计,得益于疫情之下的需求增长,存储芯片的合约价格在今年二季度将会有明显上涨,涨幅可能达到两位数。存储器模组大厂威刚2月份营收状况显示,在下游客户备货需求强劲,带动整体需求的情况下,2月份合并营收达新台币24.46亿元,较1月份增加30.07%,较2019年同期增加19.64%。 NH投资与证券分析师曾表示,新冠肺炎致使全球半导体设备投资出现延迟,但另一方面,投资中断将对内存需求产
[手机便携]
51单片机资源扩展:从片内ROM跳转到片外ROM
源于一年前想自己动手给51写个OS,编译选Large模式,调试时整个流程都跑的好好的,可是烧写到片上后得不到预期的效果,后来查书才知道51单片机片上只有4KRom,如果没有扩展片外Rom,当访问4K以外的程序空间,程序指针又会回到最开始执行。参考手册扩展片外Rom后,能访问达64K的程序空间。网上能搜索到的扩展方式都是将EA引脚接地,让MCU上电后从外部ROM开始执行。但查看芯片手册,明明说EA为高时,程序从片内ROM执行,当执行到0x1000以上地址时(标准51单片机),会跳转到片外ROM执行。按网上的做法,为了扩展个片外ROM,片内的基本ROM都不用了,有点浪费了,于是开始找资料如何从片内跳转到片外执行。 射人先射马,发
[单片机]
51单片机资源扩展:从片内<font color='red'>ROM</font>跳转到片外<font color='red'>ROM</font>
迈瑞选择Actel的低功耗Flash FPGA
Actel的 ProASIC3解决方案为便携式监护仪设备提供低功耗操作特性并同时保护宝贵的知识产权   Actel公司宣布中国领先的医疗设备开发和制造商迈瑞医疗国际有限公司(Mindray Medical International Limited) 已选择Actel以 Flash为基础的ProASIC3现场可编程门阵列 (FPGA) 器件,用于其便携式监护仪产品,而此举突显了Actel低功耗及功率有效可编程技术的成功。ProASIC3的60,000门A3P060产品获选的原因在于具备低功耗、高安全性、高性能,以及固件错误免疫力,可以提供最高保密水平的监护数据管理。   继成功部署Actel的ProASIC3后,迈瑞正计划在该
[医疗电子]
加密内存并不是实现数据安全的唯一途径
内存的安全功能并不是新概念, 但随着网络连接成为人们日常生活中必不可少的一部分,再加上大流行引发的远程工作让需求激增,让数据安全性变得更加重要,也更具挑战性。在包括5G在内的通信基础设施共享数据的新应用案例中,有关于网络数据安全的“挑战”也被放大。 然而,安全性功能会为内存设计增添复杂度。 甚至是在边缘运算、物联网(IoT)、连网车辆等市场大幅成长之前,内存中的安全功能就已经激增。例如EEPROM是信用卡、SIM卡和智能钥匙(门禁)系统的首选,而SD卡中的“S”代表“安全”,还有以闪存为基础的固态硬盘(SSD),在设计步骤开始就已默认将加密功能包含在内。 安全已经稳定地嵌入到分布在整个计算系统和网络环境中的内存和网络设
[网络通信]
加密<font color='red'>内存</font>并不是实现数据安全的唯一途径
把面向数字家庭的Adobe Flash引进到MIPS-Based平台
什么是三重播放集成? TPI公司是一家致力于提供数字家庭视频平台解决方案的专业软件服务公司。TPI公司还是官方Adobe 的“Scaling Partner”,为消费电子平台提供Flash Player 10、AIR和舞台美术技术提供优化的端口。我们有25名具有专业的项目管理和质量保障经验的高级工程师团队,平均具有 24 年的工作经验. 你们能够提供什么样的服务? 我们为所有的flash产品提供设备Flash移植、认证服务以及全面维护和支持服务,其中包括Flash Player 10.X、用于电视的AIR 2.5以及针对数字家庭的Flash Lite(FLDH 也被称为“舞台艺术”)。我们还转售Adobe Flash Pla
[家用电子]
嵌入式系统中的Flash存储管理
摘要:以TRI公司的基于NOR Flash的Flash管理软件FMM为例,详细介绍嵌入式系统中如何根据Flash的物理特性来进行Flash存储管理。 关键词:嵌入式系统 Flash FMM 引言 在当前数字信息技术和网络技术高速发展的后PC(Post-PC)时代,嵌入式系统已经广泛地渗透到科学研究、工程设计、军事技术、各类产业和商业文件艺术、娱乐业以及人们的日常生活等方方面面中。随着嵌入式系统越来越广泛的应用,嵌入式系统中的数据存储和数据管理已经成为一个重要的课题摆在设计人员面前。 Flash存储器作为一种安全、快速的存储体,具有体积小、容量大、成本低、掉电数据不丢失等一系列优点。目前已经逐步取代其它半导体存储元件,成为
[应用]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved