微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > ARM·Nand Flash的控制

ARM·Nand Flash的控制

时间:11-24 来源:互联网 点击:

个人觉得这章内容过于复杂,只需要记住如果nand中4096的程序想要被拷贝出来执行,就把这个代码写进去,红色部分是真正的代码,可以复制过去,直接使用,其他就不做了解了。听了一个小时,这个老师讲的也挺乱的,也没有人能记住这么多东西吧。。。

代码详解,这里先把一部分代码存放在NAND Flash 地址4096之后,当程序启动后通过NAND Flash控制器将他们读出来、执行。

注意:以前的代码都小于4096,开发板启动后他们被自动复制进“Steppingstone”;

现在的代码在4096之后,需要控制NAND Flash将他们读出来、执行

SECTIONS {

firtst 0x00000000 : { head.o init.o nand.o}

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

}

对于这里,我是这样理解的 。head.o init.o nand.o都放在Nand flash0地址处,0x0000 0000是他的链接地址,也就是放在0x0000 0000处运行;mian.o存放在Nand flash 4096地址处,0x3000 0000是他的链接地址,也就是放在0x3000 0000处运行

(可能也就是前一阵子看到的链接地址和加载地址的区别)

当开发板启动时,前4k的代码被考进SRAM,所以我们需要在SRAM内完成初始化和跳转

SECTIONS {

firtst 0x00000000 : { head.o init.o nand.o}

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

} @******************************************************************************

@ File:head.s

@ 功能:设置SDRAM,将程序复制到SDRAM,然后跳到SDRAM继续执行

@******************************************************************************

.text

.global _start

_start:

@函数disable_watch_dog, memsetup, init_nand, nand_read_ll在init.c中定义

ldr sp, =4096 @设置堆栈

bl disable_watch_dog @关WATCH DOG

bl memsetup @初始化SDRAM

bl nand_init @初始化NAND Flash

@将NAND Flash中地址4096开始的1024字节代码(main.c编译得到)复制到SDRAM中

@nand_read_ll函数需要3个参数:

ldr r0, =0x30000000 @1. 目标地址=0x30000000,这是SDRAM的起始地址

mov r1, #4096 @2. 源地址 = 4096,连接的时候,main.c中的代码都存在NAND Flash地址4096开始处

mov r2, #2048 @3. 复制长度= 2048(bytes),对于本实验的main.c,这是足够了

bl nand_read @调用C函数nand_read

ldr sp, =0x34000000 @设置栈

ldr lr, =halt_loop @设置返回地址

ldr pc, =main @b指令和bl指令只能前后跳转32M的范围,所以这里使用向pc赋值的方法进行跳转

halt_loop:

b halt_loop

*对于这一串代码,很多都是前面学过的知识,这里我们只关注配置Nand的红色代码

bl nand_init

*目标地址,源地址,目标长度

ldr r0, =0x30000000 @1. 目标地址=0x30000000,这是SDRAM的起始地址

mov r1, #4096 @2. 源地址 = 4096,连接的时候,main.c中的代码都存在NAND Flash地 址4096开始处

mov r2, #2048 @3. 复制长度= 2048(bytes),对于本实验的main.c,这是足够了

bl nand_read @调用C函数nand_read

这里我们可以跳转到nand_read中可以看一下

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

{

int i, j;

#ifdef LARGER_NAND_PAGE

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

return ;

}

#else

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

return ;

}

#endif

nand_select_chip();

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

write_cmd(0);

write_addr(i);

#ifdef LARGER_NAND_PAGE

write_cmd(0x30);

#endif

wait_idle();

#ifdef LARGER_NAND_PAGE

for(j=0; j < NAND_SECTOR_SIZE_LP; j++, i++) {

#else

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

#endif

*buf = read_data();

buf++;

}

}

#define LARGER_NAND_PAGE

#define GSTATUS1 (*(volatile unsigned int *)0x560000B0)

#define BUSY 1

#define NAND_SECTOR_SIZE 512

#define NAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1)

#define NAND_SECTOR_SIZE_LP 2048

#define NAND_BLOCK_MASK_LP (NAND_SECTOR_SIZE_LP - 1)

typedef unsi

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top