NAND Flash裸板编程

nand flash按照我的理解,在开发板上就类似我们所用的电脑中的硬盘,用来保存系统运行的操作系统,应用程序,数据等,掉电之后还可以永久得保存数据(不包括临时数据)。通过控制或配置NAND Flash的控制器寄存器,即可完成对nand的操作:包括读、写、擦除等。

而控制、配置这些寄存器是根据板子的原理图、用户手册以及nand flash芯片手册上的说明来配置的。

通过原理图,可见nand flash与cpu之间的数据传输主要是通过LDDATA0~7这8根引脚线,其中传输的“数据”可以是地址、数据,也可以是命令,这就要靠CLE、ALE引脚的状态进行选择。

对于命令的传输,主要是对NFCMD寄存器写以上相对应的命令值,但这个命令是分两个周期进行的。

而对于数据的传输,在数据传输模式下,传输数据也是要根据以上的格式去进行传输,分5个周期,每一个周期传输的数据都十分讲究,这就要求要有一个符合这种格式的巧妙算法(在接下来的代码中体现)。

了解了这些命令、数据的传输格式之后,就是要对具体的寄存器进行相应的配置了。首先要介绍这些寄存器的作用(数据手册上对各寄存器都有说明):

(1)NFCONF:用来设置时序参数,设置位宽。

(2)NFCMD:命令寄存器。

(3)NFADDR:地址寄存器。

(4)NFDATA:数据寄存器,用于读写数据。

(5)NFSTAT:状态寄存器,只用到最低1位,表示是否忙碌。

编程举例

实现从nand flash中拷贝程序到sdram中运行,其中涉及到启动代码的编程,初始化内存控制器,读取并拷贝nand flash上的数据。(只展示部分核心代码)

head.S

.text
.global    _start
_start:
    ldr sp,=4096            @设置堆栈
    bl disable_watch_dog    @关闭看门狗
    bl set_mem                @设置内存控制器
    bl nand_init            @nand初始化

    ldr r0,=0x30000000
    ldr r1,=4096
    ldr r2,=4096             @传递参数
    bl nand_read            @从nand中拷贝

    ldr sp,=0x38000000
    ldr lr, =halt          @设置返回地址
    ldr pc, =main  
halt:
    b halt

nand.c

typedef struct s3c2440_nand  
{
    unsigned int NFCONF;
    unsigned int NFCONT;
    unsigned int NFCMMD;
    unsigned int NFADDR;
    unsigned int NFDATA;
    unsigned int NFMECCD0;
    unsigned int NFMECCD1;
    unsigned int NFSECCD;
    unsigned int NFSTAT;
    unsigned int NFESTAT0;
    unsigned int NFESTAT1;
    unsigned int NFMECC0;
    unsigned int NFMECC1;
    unsigned int NFSECC;
    unsigned int NFSBLK;
    unsigned int NFEBLK;
}s3c2440_nand;
//定义nandflash控制器的起始地址
static s3c2440_nand* nand_base = (s3c2440_nand*)0x4E000000;

//片选
void select_chip_or_not(int flag)//0不片选,1片选
{
    if(flag == 1)
    {
        nand_base->NFCONT |= (0x1<<1);
    }
    if(flag == 0)
    {
        nand_base->NFCONT &= ~(0x1<<1);
    }
}
void write_command(unsigned char cmd)
{
     volatile unsigned char *p = (volatile unsigned char *)&nand_base->NFCMMD;
    *p = cmd;
}
void write_addr(unsigned int addr)
{
    int i;
    volatile unsigned char* p = (volatile unsigned char *)nand_base->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++);
}
//等待nand flash就绪
void wait_ldle(void)
{
    volatile unsigned char* p = (volatile unsigned char*)nand_base->NFSTAT;
    int flag = *p & 1;
    while(!flag)
    {
        int i;
        for(i=0;i<20;i++);
    }

}
unsigned char read_data(void)
{
    volatile unsigned char *p= (volatile unsigned char*)nand_base->NFDATA;
    return *p;
}
void nand_read(unsigned char* buf,unsigned char base_addr,unsigned int size)
{
    int i,j;
    //片选
    select_chip_or_not(1);
    //复制数据
    for(i=base_addr;i<base_addr+size;)
    {
        write_command(0);//发送读命令
        write_addr(i);   //发送地址
        write_command(0x30);
        wait_ldle();
        for(j=0;j<512;j++,i++)
        {
            *buf = read_data(); //读取数据,一次读取一页(512个字节)
            buf++;
        }
    }
    select_chip_or_not(0);//取消片选

}
void nand_reset(void)
{
    select_chip_or_not(1);//片选
    write_command(0xff);
    wait_ldle();
    select_chip_or_not(0);
}
void nand_init(void)
{
    
    nand_base->NFCONF = (0<<12)|(3<<8)|(0<<4);
    nand_base->NFCONT = (1<<4)|(1<<1)|(1<<0);
    nand_reset();
}

还要说下Makefile

objs := head.o init.o nand.o main.o
nand.bin : $(objs)
    arm-linux-ld -Tnand.lds $^ -o nand_elf
    arm-linux-objcopy -O binary -S nand_elf  [email protected]
%.o : %.S
    arm-linux-gcc -c $< -o [email protected]
%.o : %.c
    arm-linux-gcc -c $< -o [email protected]
clean :
    rm -f nand.bin *.o nand_elf

平时写的Makefile不一样,这里使用了一个名为nand.lds的链接脚本,这样做主要是为了试验让编译好的程序在链接时存放的地址和理论运行地址都不同且不在同一个存储设备上,方便看试验效果。

nand.lds

SECTIONS {
    first    0x00000000 : {head.o init.o nand.o}
    second     0x30000000 : AT(4096) {main.o}
}

链接脚本上的第一段是放head.S init.c nand.c编译出的内容,从0地址开始存放和执行,而main.o则是需要从nand flash手动复制到sdram中去执行。

实现的效果如图:

时间: 2024-10-28 21:52:16

NAND Flash裸板编程的相关文章

【详解】如何编写Linux下Nand Flash驱动

From: http://www.crifan.com/files/doc/docbook/linux_nand_driver/release/html/linux_nand_driver.html 版本:v2.2 Crifan Li 摘要 本文先解释了Nand Flash相关的一些名词,再从Flash硬件机制开始,介绍到Nand Flash的常见的物理特性,且深入介绍了Nand Flash的一些高级功能,然后开始介绍Linux下面和Nand Flash相关的软件架构MTD的相关知识,最后介绍了

Linux学习 : 裸板调试 之 配置使用NAND FLASH

关于NAND FLASH的结构是以页为单位写,以块为单位来擦除: 1Gb     为大页   page=2048Kb    BLOCK=128K 512Mb 为小页   page=512byte    BLOCK=16K PS:一页还有额外64字节OOB块,通常不计入读取范围. 另一个区别就是ECC的验证: ECC是每256个字节生产一个24位的值.NAND FLASH在写的时候会生成一个原始的ECC值保存在页的SPARE区,当要读页时也会生产一个ECC值,会跟SPARE的值进行异或比较,看结果

TQ210裸机编程(13)——NAND FLASH读写

参考<韦东山毕业班视频>第1课第1.1节_自己写bootloader之编写第1阶段 参考<韦东山6410裸板视频>第7章nand flash实验 K9K8G08U0B : (1G + 32M) x 8bit Data Register : (2K + 64) x 8bit Page Program : (2K + 64)Byte Block Erase : (128K + 4K)Byte Page Read: (2K + 64)Byte The K9K8G08U0B has a 8

s5pc100开发板Nand flash移植

相关软件下载地址:http://pan.baidu.com/s/16yo8Y fsc100开发板 交叉编译工具:arm-cortex_a8-linux-gnueabi-gcc ?   添加针对我们平台的Nand flash驱动 拷贝s3c_nand.c到drivers/mtd/nand下 拷贝regs-nand.h到arch/arm/mach-s5pc100/include/mach下 ?   针对平台上的nand flash设备,修改drivers/mtd/nand/nand_base.c第2

用J-LINK烧写Bootloader到ARM开发板的Nand Flash

一.起因和原理 起因:以往电脑烧写bootloader到 nand中是采用jtag以及jflash,jtag是使用并口连接的,目前电脑一般没有并口了,现今一般是使用较便宜入手的J-LINK,使用USB,就不能再使用以往的jflash烧写了.因此需要找到一个J-LINK烧写Nand的方法. 以下说明J-LINK烧写Nand的原理. 以realarm2410开发板为例子说明,该开发板要把跳线设置为Nand Flash启动模式才可以操作Nand,此时的内存映射如下图: 图1   如图1,内存中并没有对

micro/mini 2440 Jlinker 裸板烧录

1. 简要说明 JLink的调试功能.烧写Flash的功能都很强大,但是对于S3C2410.S3C2440的Flash操作有些麻烦:烧写Nor Flash时需要设置SDRAM,否则速率很慢:烧写Nand Flash只是从理论上能够达到,但是还没有人直接实现这点. 本文使用一个间接的方法来实现对S3C2410.S3C2440开发板的Nor.Nand Flash的烧写.原理为:JLink可以很方便地读写内存.启动程序,那么可以把一个特制的程序下载到开发板上的SDRAM去,并运行它,然后使用这个程序来

【嵌入式开发】 嵌入式开发工具简介 (裸板调试示例 | 交叉工具链 | Makefile | 链接器脚本 | eclipse JLink 调试环境)

作者 : 韩曙亮 博客地址 : http://blog.csdn.net/shulianghan/article/details/42239705  参考博客 : [嵌入式开发]嵌入式 开发环境 (远程登录 | 文件共享 | NFS TFTP 服务器 | 串口连接 | Win8.1 + RedHat Enterprise 6.3 + Vmware11) 开发环境 : -- 操作系统 : Vmware11 + RedHat6.3 企业版 + Win8.1; -- 硬件 : OK-6410-A 开发

HI3518E用J-link烧写裸板fastboot u-boot流程

Hi3518E的裸板烧写fastboot是不能像HI3531那样,可以通过FB直接烧写.遵循ARM9的烧写流程.其中一般u-boot的烧写流程可分为几类:第一:通过编程器芯片直接烧写:第二通过RVDS来烧写(海思官方原版的方式):第三通过j-link烧写.这三种方式中,前两种都是很麻烦的事情,需要编程支持比较贵.第二种价格就更加不菲.第三种方式是一般嵌入式工程师能想到也很容易能得到的方式.下面介绍j-link烧写流程,以下演示芯片为海思的HI3518E芯片. 第一.连接j-link打印对应的j-

Tiny6410之NAND FLASH驱动

一.NAND FLASH的特点 S3C6410的NAND FLASH控制器有如下特点 1.自导入模式:复位后,引导代码被送入到8KB的STEPPINGSTONE中,引导代码移动完毕,引导代码将在STEPPINGSTONE中执行.导入期间,NAND FLASH控制器不支持ECC矫正. 2.NAND FLSH 控制器I/F:支持512字节和2KB页 3.软件模式:用户可以直接访问nand flash 控制器,该特性可以用于读/檫/编程nand flash 存储器. 1)写命令寄存器=NAND FLA