NFSTAT寄存器 的RnB的bit4
NFSTAT寄存器
当RnB信号由低电平跳变成高电平时,该bit位会被自动置1(硬件完成),表示Flash可以读,读NFDATA寄存器;
但是,此信号何时变为低电平?手动操作该bit位,使其清0。
有点特殊的是,如果将该bit清0,要向该bit写1.
此方法与以往有区别:
写 0 ,清0
写 1,置1
而该bit位:
写1,清0
自动,置1
案例:读Nand flash的第0页的主数据
2048+64 bytes
u-boot.bin
nand_page.h
#define __NAND_H__
#define __NAND_H__//定义寄存器
#define NFCONF (*((volatile unsigned int*)0xBOE00000));
#define NFCONT (*((volatile unsigned int*)0xBOE00004));
#define NFCMMD (*((volatile unsigned int*)0xBOE00008));
#define NFADDR (*((volatile unsigned int*)0xBOE0000C));
#define NFDATA (*((volatile unsigned int*)0xBOE00010));
#define NFSTAT (*((volatile unsigned int*)0xBOE00028));//声明函数原型
extern void nand_init(void);
extern void nand_read_id(void);
//buf:保存读取页数据的首地址
//page:表示要读的页号
extern void nand_page_read(unsigned int *buf,unsigned int page);#endif
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
nand_page.c
#include "nand.h"
#include "uart.h"
#include "itoa.h"void nand_init(void)
{//nand flash 控制器使用的管脚配置,//因为我们使用的nand flash启动方式,所以关于GPIO管脚功能配置可以不做//如果使用的不是nand flash启动,将需要配置NFCONF = (0xF<<12) | (0xF<<8) |(0xF<<4) | (1<<1); NFCONT = (3<<12) | (3<<8) | 7;
}void nand_read_id(void)
{//1,nand falsh片选信号拉低,使能nand falsh芯片//操作 NFCONT bit[1] = 0;NFCONT &= ~(1<<1);// 1<<1 ==> 10//2,向NFCMMD寄存器写入0x90NFCMMD = 0x90;//3,向NFADDR寄存器写入0x0NFADDR = 0x0;//4,延时int i;for(i = 0;i < 256; i++){;}//5,读NFDATA 寄存器(字)ID//读5个字节的ID号unsigned int id1;unsigned int id2;id1 = NFDATA;id2 = (NFDATA & 0xFF);//只要低八位//6,Nand flash片选信号拉高//操作 NFCONT bit[1] = 1;NFCONT |= (1<<1) ;//7,显示读出来的nand flash的ID号char buf[16];uart0_puts("\n ID1 = ");itoa(buf,id1);//转换(整型无法直接打印,打印前转换成字符串)uart0_puts(buf);//输出uart0_puts("\n ID2 = ");itoa(buf2,id2);//转换uart0_puts(buf2);//输出
}void nand_page_read(unsigned int *buf,unsigned int page)
{//1.Nand Flash 片选信号拉低NFCON &= ~(1<<1);//2。发送第一次读命令 0x0NFCMD = 0x0;//3,发送页内地址,分两个周期//由于读一页,给该页第0个//字节的页内地址,即0NFADDR = 0x0;NFADDR = 0x0;//4,发送页号,分三个周期NFADDR = (page & 0xFF);//低8bit//bit[15:8]NFADDR = ((page >> 8) & 0xFF);//中间的8 bit//bit[18:16]NFADDR = ((page >> 16) & 0xFF);//5,发送第二次读命令 0x30NFCMMD = 0x30//6,清除标志NFSTAT 写1清bit[4]NFSTAT |= (1<<4);//7,等待NFSTAT bit[4]自动置 1 while(!(NFSTAT & (1<<4))){;}//8,读取数据(2048)NFDATA//以字读NFDATAint i;for(i=0;i<512;i++)//512*4 = 2048{buf[i] = NFDATA;}//9, nand flash片选信号拉高NFCONT |= (1<<1) ;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
cmd.c
#include "cmd.h"
#include "led.h"
#include "nand.h"
#include "nand_page.h"void cmd_ledon(void)
{//调用开灯函数led_on();
}void cmd_nid(void)
{//调用读nand flash Id函数nand_read_id();
}void cmd_ledoff(void)
{//调用关灯函数led_off();
}static unsinged int test_buf[512];
void cmd_read(void)
{char itoa_buf[16];uart0_puts("\n nand read...");nand_page_read(test_buf,0);
}void cmd_boot_linux(void)
{//后面实现
}const cmd_t cmd_tb1[] =
{{"ledon",cmd_ledon},{"ledoff",cmd_ledoff},{"nid",cmd_nid},{"nread",cmd_read},{"bootlinux",cmd_boot_linux},//启动内核的命令,后面会用到
};int cmd_tab1_num = sizeof(cmd_tb1)/sizeof(cmd_tb1[0]);cmd_t *find_cmd(const char *name)
{for(int i=0;i<cmd_tab1_num;i++){if(name == cmd_tb1[i].name){return cmd_tb1[i];} }return NULL;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
案例:如何把linux内核读到内存中?
启动TAPD ,烧写Image
tarena# tftp 0x20008000 Image
tarena#nand erase 0x600000 0xC00000 #从6MB的位置开始,擦除12MB
tarena#nand write 0x20008000 0x600000 0xC00000
cmd.c中的cmd_boot_linux函数实现如下:
typedef void (*func_t)(int r0,int r1,int r2);//函数指针,无返回值,三个整型参数void cmd_boot_linux(void)
{//1,从nand falsh的0x600000读取内核Image到内存的//0x20008000,大小0xC00000uart0_puts("\n Loading kerenl");unsigned int *ptr = (unsigned int *)0x200080000//求起始页 6MB(0x600000)//每一页2048字节大小unsigned int page = 0x600000/2048;int i;for(i=0;i<0xC00000/2048;i++){uart0_putc('.');nand_page_read(ptr,page);page++;//读下页ptr += 2048/4;//读过来的起始地址}uart0_puts("\n Run linux...");//2,调用内存0x20008000处的Image(内核)func_t = kernel_start;kernel_start = (func_t)0x20008000;//把这个地址强制转换为一个函数的地址,为了后面执行这个函数kernel_start(0,2456,0);//这里与移植有关,先忽略
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
链接脚本 shell.lds
//1,告诉链接器如何组织可执行文件
//2,描述了程序在内存中执行时的大致内存布局,注意各个段的顺序
SECTIONS
{.= 0x23000000;.text:{main.o(.text);*.o(.text);}.rodata:{*.o(.rodata);}. = ALIGN(4);//4字节对齐.data://数据段{*.o(.data);}.=ALIGN(4);__bss__start = .;.bss :{.o(.bss);}__end =.;}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
将makefile文件中的”-Ttext 0x20008000” 修改为”-T shell.lds”即可,链接过程就会按照链接脚本的方式往下执行。
坏块处理
坏块判断原则:
Nand falsh 8192块
1块=64页
main区:
spare区:
0块
0页
1
2
…
63
读第0页,第2048个字节(spare区第一个字节),
如果不是0xFF,那就是一个坏块,
如果是0xFF,读第一页,第2048个宽限(spare区第一个字节)
如果是0xFF,好块
如果不是0xFF,坏块
好块:
第0页,2048,0xFF
第1页,2048,0xFF
坏块:
1)第0页,2048,不是0xFF
2)第0页,2048,0xFF
第1页,2048,不是0xFF
1块
第64页(绝对页号)
第65页(绝对页号)
2块
第128页
第129页
3块
192页
193页
在nandread.h中增加
//读page的len个字节到buf
extern void nand_page_oob(char *buf,int len,unsigned int page);//判断是否坏块
extern int nand_blk_check(unsigned int page_no);
- 1
- 2
- 3
- 4
- 5
在对应的.c文件中
//读page的len个字节到buf
extern void nand_page_oob(char *buf,int len,unsigned int page)
{//1,Nand flash 的片选信号拉低NFCONT &= ~(1<<1);//2,发送读命令 1: 0x0NFCMMD = 0x0;//3,发送页内地址,2次,2048NFADDR = 0x0;NFADDR = 0x8;//4,发送页号地址,3次NFADDR = (page & 0xFF);NFADDR = (page >>8) & 0xFF);NFADDR = (page >>16) & 0xFF);//5,发送读命令 2:0x30NFADDR = 0x30;//6,清等待标志,清NFSTAT bit[4],写1清0//7,等待NFSTAT bit[4]跳变成1//8,读取一个字节的坏块标志//由于是读一个字节,int i;for(i=0;i<len;i++){// buf[] = ;}//9,nand flash片选信号拉高NFCONT |=(1<<1);
}//判断是否坏块
extern int nand_blk_check(unsigned int page_no)
{unsigned char flag;nand_page_read_oob(&flag,1,page_no);if(flag != 0xFF){return 1;//坏块}nand_page_read_oob(&flag,1,page_no++);if(flag != 0xFF){return 1;//坏块}return 0;
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
cmd.c增加命令nbad
void cmd_nandbad(void)
{int i;char ibuf[16];for(i=0;i<;i++)//循环一次判断一块{if(nand_blk_check(i)) //页号是每块的起始页号{uart0_puts("\n Bad B lock:");itoa(ibuf,i);//将i转成字符uart0_puts(ibuf);}}
}
NFSTAT寄存器 的RnB的bit4相关推荐
- 嵌入式裸机NandFlash和 SD/iNand学习笔记
一. Nandflash 1.1 定义 Nand-flash存储器是flash存储器的一种,其内部采用非线性宏单元模式,为固态大容量内存的实现提供了廉价有效的解决方案.Nand-flash存储器具有容 ...
- Nandflash 驱动移植
前段时间,研究了一下4G的Nandflash驱动.手头上只有飞凌6410BSP自带的Nandflash驱动,该驱动不支持K9GAG08U0D(2G)和K9LBG08U0D(4G)的Nandflash. ...
- S5PV210体系结构与接口11:NandFlash SD卡编程
目录 1. Flash ROM简介 1.1 概述 1.2 Nor & Nand Flash比较 1.2.1 接口对比 1.2.2 容量和成本对比 1.2.3 可靠性对比 1.2.4 使用寿命对 ...
- 嵌入式Linux驱动学习【8】—— Nand Flash
1 Nand Flash 原理图. 引脚: 引脚 功能 IO0~IO7 数据输入输出 CLE 命令锁存 ALE 地址锁存 nCE 芯片使能 nRE 读使能 nWE 写使能 R/nB 就绪/忙 ...
- 7.NAND芯片的读写及ECC检验软硬件实现_上
最近在study ARM,在网上看到一些先行者们总结出来的一些东西,觉得很有参考意义,特收藏起来便于日后查找学习(在此向原帖作者致敬). 第一节概论 nandflash在对大容量的数据存储中发挥着重要 ...
- u-boot 启动代码start.S详解(for mini2440)
u-boot存储器映射图: start.S 代码分析 #include <common.h> #include <config.h>/*#include <config. ...
- fl2440u-boot移植
在移植u-boot之前,可以参考我之前的博客移植操作一遍,理解一下ARM-LINUX的启动流程:bootloader->linux内核->文件系统->应用程序.最重要的一点,移植u- ...
- LED音乐频谱之输出数据处理
转载请注明出处:http://blog.csdn.net/ruoyunliufeng/article/details/38023539 一.PWM调节 1.初始化 void DACInit() {CC ...
- Nandflash 驱动深度分析(基于S3C2410)
NAND Flash在嵌入式系统中的地位与PC机上的硬盘类似,用于保存系统运行所必需的操作系统.应用程序.用户数据.运行过程中产生的各类数据.与内存掉电后数据丢失不同,NAND Flash中的数据在掉 ...
最新文章
- iOS 单例模式全面解析
- 怎样将项目上传到github上
- S3C2410时钟部分总结
- POJ 3461 kmp 应用
- 收集常用的CSS基础面试题
- unity自动生成敌人_Unity 3D做2D坦克大战--敌人自动攻击AI编写
- 大数据分布式工作流任务调度系统DolphinScheduler v1.3.4
- 【3D游戏建模】3D建模师的发展前景
- 第三章:react 应用( 基于 react )
- 双绞线传输距离_一看就懂的网络传输介质介绍
- 计算机是如何启动的?(转载)
- SQL 经典练习题 + 答案
- Mapgis67软件实用操作
- Django技术文档
- html 横屏滚动字幕,手机知识:手机横屏滚动字幕
- 显卡参数详解[原创]
- 计算机进入启动死循环,教你win10重启死循环怎么解决
- autocad2014 菜单栏 闪退_AutoCAD2014闪退解决办法
- MyBatis 大于小于符号表示
- Android Camera使用OpenGL ES 2.0和GLSurfaceView对预览进行实时二次处理(黑白滤镜)