ARM开发步步深入之NandFlash 4KB突围

发布者:rho27最新更新时间:2016-11-27 来源: eefocus关键字:ARM开发  NandFlash  4KB 手机看文章 扫描二维码
随时随地手机看文章

实验目的:突破4KB的Steppingstone存储空间限制,读取NandFlash中4KB后的代码实现“点灯大法”,借此掌握NandFlash的操作。

实验环境及说明:恒颐S3C2410开发板H2410。H2410核心板的NandFlash选用的是三星片上(SOP)K9F1208U0M,该NandFlash容量为64MB。

实验思路:开发板上电启动后,自动将NandFlash开始的4K数据复制到SRAM中,然后跳转到0地址开始执行。然后初始化存储控制器SDRAM,调用NandFlash读函数操作把4KB后的点灯代码复制到SDRAM中,跳到点灯代码的入口点实现点灯操作。

知识掌握:NandFlash内部结构、命令字及存储控制器
一、NandFlash内部结构
不同开发板使用的NandFlash的型号可能不一样,本文只是以K9F1208U0M为例做个简单介绍。引脚描述如下所示:

'700')this.width='700';if(this.offsetHeight>'700')this.height='700';" src="http://www.arm79.com/attachment/Mon_1005/73_67_af4843899d603e0.jpg" onclick="if(this.width>=700) window.open('http://www.arm79.com/attachment/Mon_1005/73_67_af4843899d603e0.jpg');" border="0"> 
NandFlash存储单元结构图如下所示:

'700')this.width='700';if(this.offsetHeight>'700')this.height='700';" src="http://www.arm79.com/attachment/Mon_1005/73_67_b53cf1b5e09813b.jpg" onclick="if(this.width>=700) window.open('http://www.arm79.com/attachment/Mon_1005/73_67_b53cf1b5e09813b.jpg');" border="0" width="700"> 
Device、 Block和Page之间的关系---1 Device = 4,096 Blocks = 4096*32 Pages = 128K Pages;1 Block = 32 Page;1 Page = 528 Byte = 512 Byte + 16 Byte。其中1 Page中包含有数据寄存器512 Byte和16 Byte的备用位用于ECC校验存储。所以有528 columns * 128K rows(Pages)。1 Page中的512 Byte的数据寄存器又分为两个部分1st 256 Bytes和 2nd 256 Bytes。用于数据存储的单元有 512 Bytes * 32 Pages * 4096 Blocks = 64 MB,用于ECC校验单元有16 Bytes * 32 Pages * 4096 Blocks = 2MB 。
二、NandFlash命令字
操作NandFlash时,先传输命令,然后传输地址,最后进行数据的读/写。K9F1208U0M的命令字如下所示:

'700')this.width='700';if(this.offsetHeight>'700')this.height='700';" src="http://www.arm79.com/attachment/Mon_1005/73_67_9f90461920e6b01.jpg" onclick="if(this.width>=700) window.open('http://www.arm79.com/attachment/Mon_1005/73_67_9f90461920e6b01.jpg');" border="0" width="700"> 
由于寻址需要26bit的地址,该26bit地址通过四个周期发送到NandFlash,如下图所示:

'700')this.width='700';if(this.offsetHeight>'700')this.height='700';" src="http://www.arm79.com/attachment/Mon_1005/73_67_e8c052eed36f8b9.jpg" onclick="if(this.width>=700) window.open('http://www.arm79.com/attachment/Mon_1005/73_67_e8c052eed36f8b9.jpg');" border="0"> 
Read 1操作:该操作是对512 Bytes * 32 Pages * 4096 Blocks = 64 M的数据寄存器进行寻址。第一个周期发送A7~A0的8bit Column地址,8bit的寻址范围是0~255,只能对1st 256 Bytes部分进行寻址。00h命令是1st 256 Bytes部分寻址。当发送01h命令时,A8将会被置1,此时寻址范围变成了256~511了,所以01h命令是对2nd 256 Bytes部分进行寻址。(*注意:A8在发送00h命令后被清0,在发送01h命令后被置1,并且在发送01h对2nd寻址完毕后,A8会自动清0,指 针会自动地指向1st);第二个周期的A9~A13的5bit是对Page进行寻址(因为1 Block = 32 Pages,5bit的寻址范围是0~31,可以对1 Block里面的所有Page进行寻址)。A14~A25的12bit则是对Block进行寻址,12bit的寻址范围是0~4095,对整个 Device的4096个Blocks进行寻址。Read 2操作:该操作是对16 Bytes * 32 Pages * 4096 Blocks =2MB的备用位(ECC)进行寻址。50h命令为Read2操作,对1 Page里面的后16 Byte寻址。这样,通过四个周期的发送即可对整个Device的所有存储单元进行寻址。
三、NandFlash存储控制器
S3C2410 为简化对NandFlash的操作,提供了一组NandFlash控制器来实现对K9F1208U0M命令字的操作,主要有配置寄存器NFCONF、控制 寄存器NFCONT、命令寄存器NFCMD、地址寄存器NFADDR、数据寄存器NFDATA和状态寄存器NFSTAT。
★NFCONF被用来使 能/禁止NandFlash控制器、使能/禁止控制引脚信号nFCE、初始化ECC、设置NandFlash的时序参数。TACLS、TWRPH0、 TWRPH1---这三个参数控制着NandFlash信号线CLE/ALE与写控制信号new的时序关系。根据NandFlash的Datasheet 中对其最小读/写/控制时间的要求,联系HCLK实际取值一般为100MHz,可以设这三个参数分别为1:3:1个HCLK即可(貌似ViVi中是 1:3:1),这样可以满足其时序要求。
★NandFlash状态寄存器NFSTAT。只用到最低位[0],0:busy;1:ready。
NandFlash 存储控制器根据OM[1:0]位的取值可以工作在①自动启动模式---OM[1:0]=00时,复位之后,NandFlash的最先4KB的代码被复制到 Steppingstone中即内部4KB的SRAM。Steppingstone被映射为Bank0(nGS0),且CPU在此4KB内部SRAM中开 始执行启动代码;②NandFlash模式。

示例代码解析:
★head.S头文件来设置SDRAM,设置SDRAM,将第二部分代码复制到SDRAM,然后跳到SDRAM继续执行。
.equ        MEM_CTL_BASE,       0x48000000

.text
.global _start
_start:
    bl  disable_watch_dog               @关门喂狗
    bl  mem_control_setup               @设置存储控制器
    ldr sp, =4096                                 @设置栈指针,以下C函数调用前需要设好栈
    bl  nand_init                                  @初始化NandFlash
@将NandFlash中地址4096开始的1024字节代码(led.c编译得到)复制到SDRAM中
    ldr  r0, =0x30000000                  @目标地址=0x30000000,SDRAM起始地址
    mov  r1, #4096                            @源地址=4096,连接的时候led代码在4096开始处
    mov  r2, #1024                            @复制长度=1024,对于本实验的led足够
    bl  nand_read                              @调用C函数nand_read
    ldr  lr, =halt_loop                         @设置返回地址
    ldr  sp, =0x34000000                 @重新设置栈    
    ldr  pc, =main                               @使用向pc赋值的方法进行跳转到点灯代码
halt_loop:
    b  halt_loop
★nand.c文件实现NandFlash的初始化和数据读取
#define BUSY  1

typedef unsigned long S3C2410_REG32; //貌似此处定义为unsigned int反汇编结果一样的,也没问题。猜可能是ARM指令直接按32位存储了吧,知道的可以和我说一下!

/* NandFlash结构体 */
typedef struct {
    S3C2410_REG32   NFCONF;
    ......
    S3C2410_REG32   NFECC;
}S3C2410_NAND;

static S3C2410_NAND * s3c2410nand = (S3C2410_NAND *)0x4e000000;

/* 供外部调用的函数声明 */
void nand_init(void);
void nand_read(unsigned char *buf, unsigned long start_addr, int size);

/* S3C2410的NandFlash处理函数声明 */
static void s3c2410_nand_reset(void);
......
static unsigned char s3c2410_read_data();

/* S3C2410的NandFlash操作函数实现 */

/* 复位 */
static void s3c2410_nand_reset(void)
{
    s3c2410_nand_select_chip();
    s3c2410_write_cmd(0xff);  //发命令字0xFF实现复位操作复位
    s3c2410_wait_idle();
    s3c2410_nand_deselect_chip();
}

/* 等待NandFlash就绪 */
static void s3c2410_wait_idle(void)
{
    int i;
    volatile unsigned char *p = (volatile unsigned char *)&s3c2410nand->NFSTAT;
    while(!(*p & BUSY))
        for(i=0; i<10; i++);
}

/* 发出片选信号 */
static void s3c2410_nand_select_chip(void)
{
    int i;
    s3c2410nand->NFCONF &= ~(1<<11);  //对NFCONF的11位写0,激活NandFlash
    for(i=0; i<10; i++);    
}

/* 取消片选信号 */
static void s3c2410_nand_deselect_chip(void)
{
    s3c2410nand->NFCONF |= (1<<11);  //对NFCONF的11位写1,使NandFlash不活动
}

/* 发出命令 */
static void s3c2410_write_cmd(int cmd)
{
    volatile unsigned char *p = (volatile unsigned char *)&s3c2410nand->NFCMD;
    *p = cmd;
}

/* 发出地址 */
static void s3c2410_write_addr(unsigned int addr)
{
    int i;
    volatile unsigned char *p = (volatile unsigned char *)&s3c2410nand->NFADDR;
    
    *p = addr & 0xff;
    for(i=0; i<10; i++);
    *p = (addr >> 9) & 0xff;
    for(i=0; i<10; i++);
    *p = (addr >> 17) & 0xff;
    for(i=0; i<10; i++);
    *p = (addr >> 25) & 0xff;
    for(i=0; i<10; i++);
}

/* 读取数据 */
static unsigned char s3c2410_read_data(void)
{
    volatile unsigned char *p = (volatile unsigned char *)&s3c2410nand->NFDATA;
    return *p;
}

//设置TACLS、TWRPH0、TWRPH1三者的值,貌似ViVi等代码中TWRPH0设为3,不知这样的好处,知道的可以告诉我!
#define TACLS   0
#define TWRPH0  2
#define TWRPH1  0
/* 初始化NandFlash */
void nand_init(void)
{
    /* 使能NandFlash控制器, 初始化ECC, 禁止片选, 设置时序 */
    s3c2410nand->NFCONF = (1<<15)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0);
    /* 复位s3c2410 NandFlash */
    s3c2410_nand_reset();
}

#define NAND_SECTOR_SIZE    512
#define NAND_BLOCK_MASK     (NAND_SECTOR_SIZE - 1)
/* 读函数 */
void nand_read(unsigned char *buf, unsigned long start_addr, int size)
{
    int i, j;
    
    if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {
        return ;    /* 地址或长度不对齐 */
    }
    /* 选中芯片 */
    s3c2410_nand_select_chip();
    for(i=start_addr; i < (start_addr + size);) {
      /* 发出READ0命令 */
      s3c2410_write_cmd(0);
      /* 写地址*/
      s3c2410_write_addr(i);
      /*等待*/
      s3c2410_wait_idle();
      for(j=0; j < NAND_SECTOR_SIZE; j++, i++) {
          *buf = s3c2410_read_data();
          buf++;
      }
    }
    /* 取消片选信号 */
    s3c2410_nand_deselect_chip();
    
    return ;
};

关键字:ARM开发  NandFlash  4KB 引用地址:ARM开发步步深入之NandFlash 4KB突围

上一篇:2440下的IIC实验
下一篇:ARM开发步步深入之定时加速

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

ARM裸机开发笔记1(指令简介)
1.非常简单的ARM程序: arm.s文件内容 AREA Example,CODE,READONLY ;声明代码段 AREA:定义代码段 Example是代码段名称CODE:代码段关键字READONLY:只读关键字 ENTRY ;相当于C程序中的main函数,标识程序的入口 CODE32 ;使用32位指令集 START MOV R0,#1 ;具体的汇编指令 MOV R0,#0
[单片机]
ARM应用系统开发详解:第1章 ARM微处理器概述
1.1 ARM-Advanced RISC Machines ARM(Advanced RISC Machines),既可以认为是一个公司的名字,也可以认为是对一类微处理器的通称,还可以认为是一种技术的名字。 1991年ARM公司成立于英国剑桥,主要出售芯片设计技术的授权。目前,采用ARM技术知识产权(IP)核的微处理器,即我们通常所说的ARM微处理器,已遍及工业控制、消费类电子产品、通信系统、网络系统、无线系统等各类产品市场,基于ARM技术的微处理器应用约占据了32位RISC微处理器75%以上的市场份额,ARM技术正在逐步渗入到我们生活的各个方面。 ARM公司是专门从事基于RISC技术芯片设计开发的公司,作为知识产权供应
[单片机]
嵌入式ARM开发板学习方法步骤
嵌入式开发就是指在嵌入式操作系统下进行开发,一般常用的系统有linux,android。 平台:Cortex-A9开发板 嵌入式技术学习如何入手,从何学起呢, 以下内容简单介绍嵌入式开发的学习步骤及如何成为一位合格的嵌入式工程师, 一、首先要掌握基础架构 嵌入式Linux系统从软件角度看可以分为四个部分:引导加载程序(Bootloader),Linux内核,文件系统,应用程序。 开发编译环境的搭建,源代码的编译和烧写,应用和驱动的建立等等都是围绕这几个文件展开的。 二、搭建开发编译环境 在64位WIN7系统下安装虚拟机, 在虚拟机下安装Ubuntu. 三、linux应用程序的设计 学会系统文件的编译和烧写后,
[单片机]
嵌入式<font color='red'>ARM</font><font color='red'>开发</font>板学习方法步骤
s3c2440硬件篇之四:NandFlash(1)介绍
如上图所示:小页Nand容量=528B * 32页 * 4096块 = 528M bits.可用512M bits.即64M. 下图为英文原文pdf资料截图。 注:NandFlash的命令,数据,地址都通过8个I/O口输出。 (1)小页Nand。 ,一页大小为(512+16)528字节(byte).将一页分为3个区:A区为0~255字节,B区为256~511字节,C区为512~527字节。访问某页时,需要选定特定的区:命令00h让地址指针指向A区,01h指向B区,50h指向C区。 Nand Flash的写操作是以页为单位的,但是可以写一页中的一部分。发出命令80h后,紧接着发出4个地址序列,然后向Flash发送数据,然
[单片机]
s3c2440硬件篇之四:<font color='red'>NandFlash</font>(1)介绍
ARM 系列 -- FS2410 开发板上通过串口实现 printf
一、目的 到目前为止我们所编写的程序都是直接烧到裸板(FS2410)上运行,没有借助操作系统,如果哪个环节出错了,就只能揣测代码的逻辑,无法借助 GDB 调试,这无形增加了编写代码的难度,如果任意时刻我们能把某个变量的值打印出来多好啊...呵呵, 你也许有同样的困惑,上一个实验我们对 UART 串口编程实现了对超级终端接收和发送数据,也许我们可以编写一个类似 C 语言里的 printf,作用就是向上位机的超级终端发送我们指定的任何数据。怀着这样美好的愿望,随我一起踏上征程吧。 二、代码 很多代码是在前面几个实验的基础上进行整理复用之,更多细节请参考前面随笔,这里 仅附简略注解。 @ 文件 head.s @ 作用:关闭看
[单片机]
opencv2.2 交叉编译 及在arm开发板测试
环境:arm开发板是 ok6410,主机是Ubuntu10.04 1,准备工作:交叉编译工具用光盘自带的arm-linux-4.4.1.tar.gz,解压到/usr/local/arm目录下(将/usr/local/arm/bin加入环境变量);下载opencv2.2的源码;安装cmake build-essential;安装必要的库: libgtk2.0-dev libavcodec-dev libavformat-dev libswscale-dev libjpeg62-dev libtiff4-dev libjasper-dev 2,用到的主要目录说明: 交叉编译工具链所在 /usr/local/arm 编译好的opencv
[单片机]
arm-linux之为开发板写上电自启动程序之方法
开发环境 开发板:AM335 虚拟机:ubuntu 14.04 编译器:gcc-linaro-5.3-2016.02-x86_64_arm-linux-gnueabihf 开发板内核:linux 4.4.12 首先开发板的文件使用的是systemd 并没有/etc/rc.local文件 所以要想修改rc.local这一简单的操作已经不存在 但是也是可以用systemd和initd两种方式解决这个问题 1.systemd 我这里是修改自带的service root@am335x-evm:/etc/rc5.d# ls /lib/systemd/system/rc-local.service /lib/systemd/sy
[单片机]
用GNU工具开发基于ARM的嵌入式系统
摘要:介绍如何利用GNU的工具开发基于ARM的嵌入式系统,以及使用编译器、连接器和调试工具的具体方法,为广大嵌入式系统开发人员提供一种低成本的开发手段。 关键词:ARM GNU MC928MX1 gcc gdb gdbserver 当前,ARM公司的32位RISC处理器,以其内核耗电少、成本低、功能强、特有16/32位双指令集,已成为移动通信、手持计算、多媒体数字消费等嵌入式解决方案的RISC标准,市场占有率超过了75 %。多家公司都推出了自己的基于ARM内核的处理器产品,越来越多的开发人员开始了针对ARM平台的开发。通常开发人员需要购买芯片厂商或第三方提供的开发板,还需要购买开发软件,如C编译器或者集成了实时操作系统的开
[应用]
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

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

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

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