当前位置:首页 > 单片机 > 单片机
[导读]它包含7个文件:head.Sinit.cmain.cMakefilenand.cnand.lds我们之前的程序都是在nandflash的前4k放代码,上电后自动拷贝到SRAM中,之后将SRAM中的代码拷贝到SDRAM中。可是当我们的程序太大超过4k的时候就不行了,因为

它包含7个文件:

head.S

init.c

main.c

Makefile

nand.c

nand.lds

我们之前的程序都是在nandflash的前4k放代码,上电后自动拷贝到SRAM中,之后将SRAM中的代码拷贝到SDRAM中。可是当我们的程序太大超过4k的时候就不行了,因为无法将nandflash的代码完全拷贝到SRAM中去,这时就需要从nandflash中拷贝代码了。

本程序里面我们要实现的就是:将一部分代码放在nandflash的4096之后,上电后,前面一部分代码自动拷贝到SRAM中,在这段代码里面将nandflash的4096之后的程序拷贝到SDRAM中。

我们从入口函数开始分析:

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

@ 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,主要是设置控制SDRAM的13个寄存器

bl nand_init @初始化NAND Flas,见注释1


@将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,见注释2


ldr sp, =0x34000000 @设置栈

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

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

halt_loop:

b halt_loop


注释1:

void nand_init(void)

{

#define TACLS 0

#define TWRPH0 3

#define TWRPH1 0

/* 判断是S3C2410还是S3C2440 */

if ((GSTATUS1 == 0x32410000) || (GSTATUS1 == 0x32410002))//这里表示是2410

{

nand_chip.nand_reset = s3c2410_nand_reset;

nand_chip.wait_idle = s3c2410_wait_idle;

nand_chip.nand_select_chip = s3c2410_nand_select_chip;

nand_chip.nand_deselect_chip = s3c2410_nand_deselect_chip;

nand_chip.write_cmd = s3c2410_write_cmd;

nand_chip.write_addr = s3c2410_write_addr;

nand_chip.read_data = s3c2410_read_data;

/* 使能NAND Flash控制器, 初始化ECC, 禁止片选, 设置时序 */

s3c2410nand->NFCONF = (1<<15)|(1<<12)|(1<<11)|(TACLS<<8)|(TWRPH0<<4)|(TWRPH1<<0);

}

else

{ /* 定义了各种操作函数 */

nand_chip.nand_reset = s3c2440_nand_reset;//见注释1-1

nand_chip.wait_idle = s3c2440_wait_idle; //见注释1-2

nand_chip.nand_select_chip = s3c2440_nand_select_chip;//见注释1-3

nand_chip.nand_deselect_chip = s3c2440_nand_deselect_chip;//见注释1-4

nand_chip.write_cmd = s3c2440_write_cmd;//见注释1-5

#ifdef LARGER_NAND_PAGE

nand_chip.write_addr = s3c2440_write_addr_lp;//大页写地址,见注释1-6

#else

nand_chip.write_addr = s3c2440_write_addr;//小页写地址,见注释1-7

#endif

nand_chip.read_data = s3c2440_read_data;//读数据,见注释1-8

/* 设置时序 */

s3c2440nand->NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);//这个东东在linux编程里面说过了,不再重复

/* 使能NAND Flash控制器, 初始化ECC, 禁止片选 */

s3c2440nand->NFCONT = (1<<4)|(1<<1)|(1<<0);

}

/* 复位NAND Flash */

nand_reset();//见注释1-9

}

注释1-1:

/* 复位 */

static void s3c2440_nand_reset(void)

{

s3c2440_nand_select_chip(); //选中芯片

s3c2440_write_cmd(0xff); // ffh是复位命令,将这个命令写入命令寄存器即可

s3c2440_wait_idle(); //等待就绪

s3c2440_nand_deselect_chip(); //不选中芯片

}


注释1-2:

/* 等待NAND Flash就绪 */

static void s3c2440_wait_idle(void)

{

int i;

volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFSTAT;

while(!(*p & BUSY))//根据NFSTAT第0位判断是否就绪,1表示就绪

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

}

注释1-3:

/* 发出片选信号 */

static void s3c2440_nand_select_chip(void)

{

int i;

s3c2440nand->NFCONT &= ~(1<<1);//NFCONT寄存器的第1位用于选中芯片,0表示选中

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

}


见注释1-4:

/* 取消片选信号 */

static void s3c2440_nand_deselect_chip(void)

{

s3c2440nand->NFCONT |= (1<<1);//参考注释1-3

}


注释1-5:

/* 发出命令 */

static void s3c2440_write_cmd(int cmd)

{

volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFCMD;

*p = cmd;//就是将命令写到命令寄存器里面,很简单

}


注释1-6:

/* 大页写地址,分5个周期写入 */

static void s3c2440_write_addr_lp(unsigned int addr)

{

int i;

volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFADDR;

int col, page;

//#define NAND_SECTOR_SIZE_LP 2048

//#define NAND_BLOCK_MASK_LP (NAND_SECTOR_SIZE_LP - 1)

col = addr & NAND_BLOCK_MASK_LP; //收下地址前11位,屏蔽高位

page = addr / NAND_SECTOR_SIZE_LP;//屏蔽地址前11位,收下高位

/* 分5个周期将地址写到地址寄存器里面 */

*p = col & 0xff; /* Column Address A0~A7 */

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

*p = (col >> 8) & 0x0f; /* Column Address A8~A11 */

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

*p = page & 0xff; /* Row Address A12~A19 */

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

*p = (page >> 8) & 0xff; /* Row Address A20~A27 */

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

*p = (page >> 16) & 0x03;/* Row Address A28~A29 */

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

}

注释1-7:

/*小页写地址,分4个周期写入*/

static void s3c2440_write_addr(unsigned int addr)

{

int i;

volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->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++);

}


注释1-8:

/* 读取数据 */

static unsigned char s3c2440_read_data(void)

{

/* 很简单,就是将数据从数据寄存器里面读出来 */

volatile unsigned char *p = (volatile unsigned char *)&s3c2440nand->NFDATA;

return *p;

}


注释1-

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

9月2日消息,不造车的华为或将催生出更大的独角兽公司,随着阿维塔和赛力斯的入局,华为引望愈发显得引人瞩目。

关键字: 阿维塔 塞力斯 华为

加利福尼亚州圣克拉拉县2024年8月30日 /美通社/ -- 数字化转型技术解决方案公司Trianz今天宣布,该公司与Amazon Web Services (AWS)签订了...

关键字: AWS AN BSP 数字化

伦敦2024年8月29日 /美通社/ -- 英国汽车技术公司SODA.Auto推出其旗舰产品SODA V,这是全球首款涵盖汽车工程师从创意到认证的所有需求的工具,可用于创建软件定义汽车。 SODA V工具的开发耗时1.5...

关键字: 汽车 人工智能 智能驱动 BSP

北京2024年8月28日 /美通社/ -- 越来越多用户希望企业业务能7×24不间断运行,同时企业却面临越来越多业务中断的风险,如企业系统复杂性的增加,频繁的功能更新和发布等。如何确保业务连续性,提升韧性,成...

关键字: 亚马逊 解密 控制平面 BSP

8月30日消息,据媒体报道,腾讯和网易近期正在缩减他们对日本游戏市场的投资。

关键字: 腾讯 编码器 CPU

8月28日消息,今天上午,2024中国国际大数据产业博览会开幕式在贵阳举行,华为董事、质量流程IT总裁陶景文发表了演讲。

关键字: 华为 12nm EDA 半导体

8月28日消息,在2024中国国际大数据产业博览会上,华为常务董事、华为云CEO张平安发表演讲称,数字世界的话语权最终是由生态的繁荣决定的。

关键字: 华为 12nm 手机 卫星通信

要点: 有效应对环境变化,经营业绩稳中有升 落实提质增效举措,毛利润率延续升势 战略布局成效显著,战新业务引领增长 以科技创新为引领,提升企业核心竞争力 坚持高质量发展策略,塑强核心竞争优势...

关键字: 通信 BSP 电信运营商 数字经济

北京2024年8月27日 /美通社/ -- 8月21日,由中央广播电视总台与中国电影电视技术学会联合牵头组建的NVI技术创新联盟在BIRTV2024超高清全产业链发展研讨会上宣布正式成立。 活动现场 NVI技术创新联...

关键字: VI 传输协议 音频 BSP

北京2024年8月27日 /美通社/ -- 在8月23日举办的2024年长三角生态绿色一体化发展示范区联合招商会上,软通动力信息技术(集团)股份有限公司(以下简称"软通动力")与长三角投资(上海)有限...

关键字: BSP 信息技术
关闭
关闭