NAND Flash 在嵌入式系统中的地位与PC上的硬盘类似,用于保护系统运行所必须的操作系统、应用程序、用户数据、运行过程中产生的各类数据。与内存掉电后数据丢失不同,NAND Flash中的数据在掉电后仍可永久保存。
Flash 的介绍 它的类型有2种:NOR Flash 和 NAND Flash 。分别是188年Intel公司和1989年Toshiba公司发明。
说说他们的优缺点:NOR做的容量比NAND的小从1M到32M,但支持XIP,擦除比较慢需耗时5s,写比较慢,但读的速度可以。可靠高,可擦写次数一万到十万次比NAND的十万到一百万次低很多,而且价格高,接口与RAM相同,可随即访问数据,常用于保存代码和关键数据,而NAND接口为I\O顺序访问数据,常用于保存数据。
嵌入式系统Linux对NOR、NAND Flash 的软件支持都很成熟。在NOR Flash 上常用jffs2文件系统,而在NAND Flash上常用yaffs文件系统。在更底层,有MTD驱动程序实现对它们的读写擦除操作,它也实现了EDC/ECC校验。(我会写一个关于EDC/ECC的算法)
硬件连接级结构就不介绍了。
现在只说一个用VIVI启动关于初始化NAND Flash 的问题。
本问题讲得就是vivi启动时NAND Flash把前4096字节的代码制动复制到起步时”steppingstone“中,vivi中Head.S不干寂寞,它调用BL Reset 关闭了WATCH DOG、interrupts,初始化系统时钟 代码如下:
Reset:
@ disable watch dog timer
mov r1, #0x53000000//看门狗地址
mov r2, #0x0//寄存器R2赋值为0
str r2, [r1]//关闭看门狗
@ disable all interrupts//所有中断
mov r1, #INT_CTL_BASE
mov r2, #0xffffffff
str r2, [r1, #oINTMSK]
ldr r2, =0x7ff
str r2, [r1, #oINTSUBMSK]
@ initialise system clocks//系统时钟
mov r1, #CLK_CTL_BASE
mvn r2, #0xff000000
str r2, [r1, #oLOCKTIME]
mov r1, #CLK_CTL_BASE
ldr r2, clkdivn_value
str r2, [r1, #oCLKDIVN]
mrc p15, 0, r1, c1, c0, 0 @ read ctrl register
orr r1, r1, #0xc0000000 @ Asynchronous
mcr p15, 0, r1, c1, c0, 0 @ write ctrl register
mov r1, #CLK_CTL_BASE
@ldr r2, mpll_value @ clock default
ldr r2, =0x7f021 @mpll_value_USER @ clock user set
str r2, [r1, #oMPLLCON] @405mhz
bl memsetup//初始化堆栈
然后初始化NAND汇编代码如下:
mov r10,lr
@ reset NAND
mov r1, #NAND_CTL_BASE
ldr r2, =( (7<<12)|(7<<8)|(7<<4)|(0<<0) )
str r2, [r1, #oNFCONF]
ldr r2, [r1, #oNFCONF]
ldr r2, =( (1<<4)|(0<<1)|(1<<0) ) @ Active low CE Control
str r2, [r1, #oNFCONT]
ldr r2, [r1, #oNFCONT]
ldr r2, =(0x6) @ RnB Clear
str r2, [r1, #oNFSTAT]
ldr r2, [r1, #oNFSTAT]
mov r2, #0xff @ RESET command
strb r2, [r1, #oNFCMD]
mov r3, #0 @ wait
1: add r3, r3, #0x1
cmp r3, #0xa
blt 1b
2: ldr r2, [r1, #oNFSTAT] @ wait ready
tst r2, #0x4
beq 2b
ldr r2, [r1, #oNFCONT]
orr r2, r2, #0x2 @ Flash Memory Chip Disable
str r2, [r1, #oNFCONT]
mov r0,#0x0
ldr r1,=VIVI_RAM_BASE
mov r2,#0x20000
4:
ldr r3,[r0],#4
str r3,[r1],#4
subs r2,r2,#1
bne 4b
mov pc,r10
@
@ copy_myself: copy vivi to ram
@
copy_myself:
mov r10, lr
@ reset NAND
mov r1, #NAND_CTL_BASE
ldr r2, =( (7<<12)|(7<<8)|(7<<4)|(0<<0) )
str r2, [r1, #oNFCONF]
ldr r2, [r1, #oNFCONF]
ldr r2, =( (1<<4)|(0<<1)|(1<<0) ) @ Active low CE Control
str r2, [r1, #oNFCONT]
ldr r2, [r1, #oNFCONT]
ldr r2, =(0x6) @ RnB Clear
str r2, [r1, #oNFSTAT]
ldr r2, [r1, #oNFSTAT]
mov r2, #0xff @ RESET command
strb r2, [r1, #oNFCMD]
mov r3, #0 @ wait
1: add r3, r3, #0x1
cmp r3, #0xa
blt 1b
2: ldr r2, [r1, #oNFSTAT] @ wait ready
tst r2, #0x4
beq 2b
ldr r2, [r1, #oNFCONT]
orr r2, r2, #0x2 @ Flash Memory Chip Disable
str r2, [r1, #oNFCONT]
@ get read to call C functions (for nand_read())
ldr sp, DW_STACK_START @ setup stack pointer
mov fp, #0 @ no previous frame, so fp=0
mov r1, #GPIO_CTL_BASE
add r1, r1, #oGPIO_F
mov r2, #0xe0
str r2, [r1, #oGPIO_DAT]
@ copy vivi to RAM
ldr r0, =VIVI_RAM_BASE
mov r1, #0x0
mov r2, #0x20000
bl nand_read_ll//读nand flash
从这开始就会将nand flash的代码全部读到内存中开始执行全部的vivi。