/****************************************************************************** Copyright (C), 2001-2011, DCN Co., Ltd. ******************************************************************************
File Name : nand.c
Version : Initial Draft
Author : oucaijun
Created : 2014/5/9
Last Modified :
Description : K9F2G08 nandflash 底层读写、控制驱动程序
当前的程序可以对nand进行随机读写,随机读写的时候数据正确,但没有正确实现ecc算法。
当前程序可以实现对nand普通的页读写,并实现ecc算法。
因随机读写ecc不正确,因此不能和普通的带ecc的读写方式配套使用。
页内地址: 2048 = 2 ^ 11 , 使用A0-A11表示页内地址 见K9F2G08手册
Function List :
CheckBadBlk
CheckNandflash
EraseBlock
getBlockNum
getPageNum
InitNandCfg
MarkBadBlk
MY_ReadPage
MY_WritePage
nandNew
NF_Reset
RandomRead
RandomWrite
ReadBlock
ReadChipId
ReadPage
ReadPageAll
ReadStatus
WaitNFBusy
WriteBlock
WritePage
History :
1.Date : 2014/5/9
Author : ocj
Modification: Created file ******************************************************************************/
/*----------------------------------------------*
* routines' implementations *
*----------------------------------------------*/
#include "Common.h"
#include <string.h>
#include "nand.h"
#include "nfarea.h"
/*----------------------------------------------*
* macros *
*----------------------------------------------*/ /*----------------------------------------------*
* external routine prototypes *
*----------------------------------------------*/ /*----------------------------------------------*
* internal routine prototypes *
*----------------------------------------------*/ /*----------------------------------------------*
* project-wide global variables *
*----------------------------------------------*/ /*----------------------------------------------*
* module-wide global variables *
*----------------------------------------------*/ /*----------------------------------------------*
*external variables *
*----------------------------------------------*/ /*----------------------------------------------*
* constants *
*----------------------------------------------*/
#define NF_WAIT_RB() {while(!(rNFSTAT &(1<<0)));} //this bit is ReadOnly
#define NF_CLEAR_RB() {rNFSTAT |=(1<<2);} //清除RnB信号 //this bit is RW
#define NF_DETECT_RB() {while(!(rNFSTAT &(1<<2))) ;} /*
R/B: When low, it indicates that a program, erase or
random read operation is in process
and returns to high state upon completion.
*/
void NF_Reset(void)
{
NFChipEn();
NF_CLEAR_RB();
WrNFCmd(RESET_CMD);
NF_DETECT_RB();
NFChipDs();
}
/*------------------------------------------------------------/
函数名称: InitNandCfg
功能描述: 配置flash
传 参: 无
返 回 值: 无
-------------------------------------------------------------*/
static void InitNandCfg(void)
{
rNFCONF = (TACLS<<)|(TWRPH0<<)|(TWRPH1<<)|(<<);//初始化时序参数
rNFCONT = (<<)|(<<)|(<<)|(<<)|(<<)|(<<)|(<<)|(<<)|(<<)|(<<);
//非锁定,屏蔽nandflash中断,初始化ECC及锁定main区和spare区ECC,使能nandflash片选及控制器
NF_Reset();
} /*------------------------------------------------------------/
函数名称: WaitNFBusy
功能描述: Read Status Register , I/O = RdNFDat();
RdNFDat() until(I/O 6 = 1 or R/B = 1 ) ;
if(I/O 0 = 0 ) program/erase/ success ;
传 参: 无
返 回 值: I/O bit0 , 表示了命令的执行状况。若为0,表示success
-------------------------------------------------------------*/
static U32 WaitNFBusy(void) //
{
U8 stat; WrNFCmd(QUERYCMD);
do
{
stat = RdNFDat();
}
while (!(stat&0x40));
WrNFCmd(READCMD0);
return stat&; //注意0为操作成功
} /*------------------------------------------------------------/
函数名称: ReadChipId
功能描述: 读flash ID
传 参: 无
返 回 值: static U32 id
-------------------------------------------------------------*/
U32 ReadChipId(void)
{
U8 MID , PID , cyc3,cyc4,cyc5 ;
NFChipEn();
WrNFCmd(RdIDCMD);
WrNFAddr();
while(NFIsBusy()); MID = RdNFDat();
PID = RdNFDat();
cyc3 = RdNFDat();
cyc4 = RdNFDat();
cyc5 = RdNFDat();
NFChipDs(); return (MID<<)|(PID<<)|(cyc3<<)|(cyc4);
} /*------------------------------------------------------------/
函数名称: ReadStatus
功能描述: 读FLASH状态
传 参: 无
返 回 值: static U16 stat
-------------------------------------------------------------*/
static U16 ReadStatus(void)
{
U16 stat; NFChipEn();
WrNFCmd(QUERYCMD);
stat = RdNFDat();
NFChipDs(); return stat; } //CheckNandflash(int info) ret =0,没有flash或者不支持的flash。
int CheckNandflash(int info)
{
U32 i;
int have_nandflash ;
InitNandCfg();
i = ReadChipId();
if(info)
debugk("NAND ID is 0x%04x \n", i); if((i==0xecda) || (i==0xadda)) {
have_nandflash = ;
}
else if(i==0xecf1) {
have_nandflash = ;
}
else {
have_nandflash = ;
debugk("unsupported nandflash id \n");
} if(info)
debugk("Nand flash status = %x\n", ReadStatus());
return have_nandflash ;
} /*------------------------------------------------------------/
函数名称: EraseBlock
功能描述: 擦除 FLASH
传 参: U32 addr
返 回 值: U32 ~stat
-------------------------------------------------------------*/
U32 EraseBlock(U32 addr)// if( stat & 0x1 == 1),erase success
{
U8 stat;
addr &= ~0x3f; // page_addr 的低六位清零
//addr(page_addr) : row_addr A12-A28 not need cloumn addr A0-A11
//64*2048(row_addr : one nand 64*2048 pages) * 2048(cloumn_addr : one page 2048 bytes)
NFChipEn();
WrNFCmd(ERASECMD0);
WrNFAddr(addr); //行地址A18~A19
WrNFAddr(addr>>);//行地址A20~A27
WrNFAddr(addr>>);//行地址A28
WrNFCmd(ERASECMD1);
stat = WaitNFBusy();
NFChipDs(); return ~stat; //最后一位等于0,success
} /*------------------------------------------------------------/
函数名称: ReadPage
功能描述:
传 参: U32 addr, U8 *buf
返 回 值: 无
-------------------------------------------------------------*/
void ReadPage(U32 addr, U8 *buf)
{
U16 i; NFChipEn();
WrNFCmd(READCMD0);
WrNFAddr();
WrNFAddr();
WrNFAddr(addr);
WrNFAddr(addr>>);
WrNFAddr(addr>>);
WrNFCmd(READCMD1);
InitEcc();
WaitNFBusy();
for(i=; i<; i++)
buf[i] = RdNFDat();
NFChipDs();
}
void ReadPageAll(U32 addr, U8 *buf)
{
U16 i; NFChipEn();
WrNFCmd(READCMD0);
WrNFAddr();
WrNFAddr();
WrNFAddr(addr);
WrNFAddr(addr>>);
WrNFAddr(addr>>);
WrNFCmd(READCMD1);
InitEcc();
WaitNFBusy();
for(i=; i<+; i++)
buf[i] = RdNFDat();
NFChipDs();
} /*------------------------------------------------------------/
函数名称: WritePage
功能描述:
传 参: U32 addr, U8 *buf
返 回 值: ret若为0xff,表示success
-------------------------------------------------------------*/
U32 WritePage(U32 addr, U8 *buf)
{
U32 i, mecc;
U8 stat, tmp[]; NFChipEn();
WrNFCmd(PROGCMD0);
WrNFAddr();
WrNFAddr();
WrNFAddr(addr);
WrNFAddr(addr>>);
WrNFAddr(addr>>);
InitEcc(); //reset mecc and secc
MEccUnlock();
for(i=; i<; i++)
WrNFDat(buf[i]);
MEccLock();
//因为K9F2G08U0A是8位IO口,因此S3C2440共产生4个字节的main区ECC码和2个字节的spare区ECC码
//在这里我们规定,在每一页的spare区的第0个地址到第3个地址存储main区ECC,第4个地址和第5个地址存储spare区ECC。
//在下次读取这一页数据的时候,同样我们也计算ECC校验码,然后与spare区中的ECC校验码比较,如果一致则说明读取的数据正确,如果不一致则不正确 //读取rNFMECC0 -- Main的ECC校验码
//for 8 bit nand flash, only use NFMECC0
mecc = RdNFMEcc() ;
tmp[] = mecc&0xff;
tmp[] = (mecc>>)&0xff;
tmp[] = (mecc>>)&0xff;
tmp[] = (mecc>>)&0xff; WrNFDat(0xff);//2048,坏块标志
SEccUnlock();
WrNFDat(tmp[]);//ECC校验码
WrNFDat(tmp[]);
WrNFDat(tmp[]);
WrNFDat(tmp[]);
SEccLock(); WrNFCmd(PROGCMD1);
stat = WaitNFBusy();//stat若为0,表示success
NFChipDs(); return ~stat;////ret若为0xff,表示success
} // RandomWrite 随机写
// 不直接改写spare区域
// addr_in_page 0-2047
U32 RandomWrite(int page_num, int addr_in_page ,U8 *buf,int len)
{
U8 stat ;
U32 mecc , secc ;
if( len+addr_in_page> ){
debugs("RandomWrite :do not allow to write spare_section directly!\n");
}
if(buf==NULL){
debugs("RandomWrite :wrong data pointer!\n");
}
//cs
NFChipEn();
WrNFCmd(PROGCMD0);
WrNFAddr();
WrNFAddr();
WrNFAddr(page_num&0xff);
WrNFAddr((page_num>>) &0xff);
WrNFAddr((page_num>>) &0xff); WrNFCmd(RANDOM_PROGRAMCMD); //85h
WrNFAddr( (addr_in_page&0xff) ); //页内A0~A7
WrNFAddr( ((addr_in_page>>)&0x0f) ); //页内地址A8~A11
while(len--){
WrNFDat(*buf++);
}
WrNFCmd(PROGCMD1);//
stat = WaitNFBusy();
//ncs
NFChipDs();
return ~stat;
} //MY_WritePage 写块 ,并将ecc写入spare区域 。
//完全同 WritePage
U32 MY_WritePage(U32 addr, U8 *buf)
{
U32 mecc ,secc ;
int i ,ret ;
U8 stat;
InitEcc(); //复位ECC
MEccUnlock(); //解锁main区的ECC
NFChipEn(); //打开nandflash片选
// NF_CLEAR_RB(); //清RnB信号 没有用这个判断busy而是直接读的query_nand ,没必要。 WrNFCmd(PROGCMD0);//页写命令周期1
//写入5个地址周期
WrNFAddr(0x00); //列地址A0~A7
WrNFAddr(0x00); //列地址A8~A11 列地址就是页内的地址,不能超过2048,要注意传入的值的有效性。
WrNFAddr((addr) & 0xff); //行地址A12~A19
WrNFAddr((addr >> ) & 0xff); //行地址A20~A27
WrNFAddr((addr >> ) & 0xff); //行地址A28
for (i = ; i < ; i++)//写入一页数据
{
WrNFDat( buf[i] );
}
MEccLock(); //锁定main区的ECC值 //读取main区的ECC校验码
//for 8 bit nand flash, only use NFMECC0
mecc = rNFMECC0 ;
SEccUnlock();//解锁spare区的ECC
WrNFDat(0xff);//先写入0XFF非坏块标志到2048
WrNFDat32(mecc);//把main区的ECC值写入到spare区的前2-5字节地址内,即第2049~2052地址
SEccLock();//锁定spare区的ECC值 secc = rNFSECC ;//读取spare区的ECC校验码
WrNFDat8(secc & 0xff);//写入secc校验码到spare区第6-7个字节
WrNFDat8((secc>>) & 0xff); WrNFCmd(PROGCMD1); WrNFCmd(QUERYCMD);
do {
stat = RdNFDat();
} while(!(stat & 0x40)); NFChipDs();
if (stat & 0x1) {//fail
debugs("fail to write nand!\n");
} return ~(stat & 0x1); //if ok,ret = 0xff
} /*------------------------------------------------------------/
函数名称: ReadBlock
功能描述:
传 参: U32 addr, U8 *buf
返 回 值: 无
-------------------------------------------------------------*/
void ReadBlock(U32 addr, U8 buf[N_PAGES_NAND_BLOCK][N_BYTES_NAND_PAGE]) //addr :pages ,64的整数倍
{
int i;
int start ;
start = addr ;
for(i=; i<; i++) {
ReadPage( start+i,buf[i] );
}
} /*------------------------------------------------------------/
函数名称: WriteBlock
功能描述:
传 参: U32 addr, U8 *buf
返 回 值: 无
-------------------------------------------------------------*/
void WriteBlock(U32 addr, U8 buf[][])
{
int i ;
int start = addr ; for(i=; i<; i++) {
WritePage( start+i ,buf[i] );
} } int getPageNum(u32 addr ,u32 PageNum[])
{
PageNum[] = addr/ ;
return PageNum[] ;
} int getBlockNum(u32 addr ,u32 BlockNum[])
{
BlockNum[] = addr// ;
return BlockNum[] ;
} ////////////////////////////////////////////
////////////////////////////////////////////
//CheckBadBlk
//addr : pageaddr{A12--A28}
//ret == 0 : badblk
//在该块的第一页 第2048bytes查询是否为non-FFh,是则为badblk 。
int CheckBadBlk(U32 addr)
{
U8 dat;
addr &= ~0x3f;
/*
Samsung makes sure that either the 1st or 2nd page of
everyinitial invalid block has non-FFh data
at the column address of 2048.
*/
NFChipEn();
WrNFCmd(READCMD0);
WrNFAddr(); //
WrNFAddr(); // A11=1 该地址值为2048
WrNFAddr(addr & 0xff);
WrNFAddr((addr>>) & 0xff);
WrNFAddr((addr>>) & 0xff);//in a page [offset == 2048] : read the 2048th bytes of page(addr) .
WrNFCmd(READCMD1);
WaitNFBusy();
dat = RdNFDat(); NFChipDs();
if(dat!=0xff) {
debugs("Blk % 4d is NG! page_addr=%d\n" ,addr>> , addr );
}
return (dat != 0xff);
} //MarkBadBlk 标记坏块
//addr : pageaddr{A12--A28}
//在该块的第一页 第2048bytes 写入non-FFh。
void MarkBadBlk(U32 addr)
{
addr &= ~0x3f;
NFChipEn();
WrNFCmd(PROGCMD0); //mark offset 2048
WrNFAddr(); //
WrNFAddr(); // A11=1 2048
WrNFAddr(addr & 0xff);
WrNFAddr((addr>>) & 0xff);
WrNFAddr((addr>>) & 0xff);//in a page [offset == 2048] : read the 2048th bytes of page(addr) . WrNFDat(); //mark with 0 == “badblk”
WrNFCmd(PROGCMD1);
WaitNFBusy(); //needn't check return status NFChipDs();
} //MY_ReadPage
//ret ==0 ok
//ret ==1 ecc error
int MY_ReadPage(U32 addr, U8 *buf)
{
int i ; U32 mecc ,secc ;
char ch;
InitEcc();
MEccUnlock(); NFChipEn();
NF_CLEAR_RB(); WrNFCmd(READCMD0);
WrNFAddr();
WrNFAddr();
WrNFAddr(addr&0xff);
WrNFAddr((addr>>)&0xff);
WrNFAddr((addr>>)&0xff);
WrNFCmd(READCMD1); NF_DETECT_RB(); for(i=; i<; i++) {
buf[i] = RdNFDat();
}
MEccLock(); SEccUnlock();
ch = RdNFDat();//跳过0XFF坏块标志 2048
//PREFERENCE :DATASHEET--ECC MODULE FEATURES
//读spare区的前4个地址内容,即第 2049 - 2052地址,这4个字节为main区的ECC
//把读取到的main区的ECC校验码放入NFMECCD0/1的相应位置内
mecc = RdNFDat32();
rNFMECCD0 = ((mecc&0xff00)<<) | (mecc&0xff) ;
rNFMECCD1 = ((mecc&0xff000000)>>) | ((mecc&0xff0000)>>) ;
SEccLock();//这之前计算的secc仅仅包括bit2048 2049 2050 2051 2052 的计算结果????? 应该是吧 secc = RdNFDat32();
//继续读spare区的4个地址内容,即第 2052--2055地址
//把读取到的spare区的ECC校验码放入NFSECCD的相应位置内
rNFSECCD = ((secc&0xff00)<<) | (secc&0xff);
NFChipDs(); if((rNFESTAT0&0xf)==0x0) { //查看ECC状态寄存器
return ;
} else {
debugs("rNFESTAT0 = %0xh \n" ,rNFESTAT0 );
return ;
}
} //
int RandomRead(U32 page_number, U32 addr_in_page , U8 *bufr ,int len )
{
if( len+addr_in_page>+ ){
debugs("RandomRead error : read out of spare_section!\n");
return ;
}
if(bufr==NULL){
debugs("RandomRead error : wrong data pointer!\n");
return ;
}
NFChipEn(); //打开Nand Flash片选
NF_CLEAR_RB(); //清RnB信号
WrNFCmd(READCMD0); //页读命令周期1
//写入5个地址周期
WrNFAddr(0x00); //列地址A0~A7
WrNFAddr(0x00); //列地址A8~A11
WrNFAddr((page_number) & 0xff); //行地址A12~A19
WrNFAddr((page_number >> ) & 0xff); //行地址A20~A27
WrNFAddr((page_number >> ) & 0xff); //行地址A28
WrNFCmd(READCMD1); //页读命令周期2
NF_DETECT_RB(); //等待RnB信号变高,即不忙
WrNFCmd(RANDOM_READCMD0); //随意读命令周期1
//页内地址
WrNFAddr( addr_in_page&0xff ); //列地址A0~A7
WrNFAddr( (addr_in_page>>)&0x0f ); //列地址A8~A11
WrNFCmd(RANDOM_READCMD1); //随意读命令周期2
while(len--){
*bufr++ = RdNFDat(); //读取数据
}
NFChipDs();
return ;
} //http://www.cnblogs.com/idle_man/archive/2010/12/23/1915303.html
#define getnum(i) {\
mygetstring(string) ;\
i = myatoi(string ) ;\
}
void nandNew(void)
{
int ret , n ,i , j ,k;
U32 nID;
U8 MID , PID , cyc3,cyc4,cyc5 ;
char dat ;
char ch ;
U8 uch;
char string[] = {};
char bufw[] = { , , };
char bufr[+] = {};
memset(bufw , 0xaa , ); while() { debugs("\n------------------------------------------------\n");
debugs("nand menu\n");
debugs("input num to select:\n");
debugs("now will operate block %d,its addr is %x\n",AppParaBpageS,AppParaBaseNF);//page num = 34816
debugs("0 sysHardwareReset\n");
debugs("1 nand EraseBlock\n");
debugs("2 nand MY_WritePage caculate ecc\n");
debugs("3 nand ReadPageAll\n");
debugs("4 nand my_cop\n");
debugs("5 nand CheckBadBlk\n");
debugs("6 nand MY_ReadPage check ecc\n");
debugs("------------------------------------------------\n");
ch = mygetc();
switch ( ch - '' )
{
case :
sysHardwareReset();
break;
case :
ret = EraseBlock(AppParaBpageS );
if(ret&0x1 == ) {
debugs("EraseBlock ok!\n");
} else {
debugs("EraseBlock fail!\n");
}
break;
case :
ret = MY_WritePage(AppParaBpageS, bufw);
if(ret&0x1 == ) {
debugs("WritePage ok!\n");
} else {
debugs("WritePage fail!\n");
}
break;
case :
if(){
int j ;
int i = ;
char buf[] = {,,,,,,,,};
buf[] = ;
buf[] = ;
buf[] = ;
memset(bufr, , sizeof(bufr));
ReadPageAll(i , bufr);
ret = memcmp(buf , bufr+ , );
debugs("ret of memcmp %x\n" , ret);
arryprintfs("ReadPage+0" ,bufr , );
arryprintfs("ReadPage+2048" ,bufr+ , );
}
break;
case :
if(){
int time = ;
int nPage = , nAddr = ;
char rbufw[] = {, , , , , , , , ,};
ret = RandomWrite(nPage , nAddr, rbufw , );
if(ret&0x1 == ) {
debugs("WritePage ok!\n");
} else {
debugs("WritePage fail!\n");
} for(time = ; time< + ; time++){
ret = 0x11;
ret = RandomRead(nPage ,nAddr , bufr , +);
debugs("RamdomRead(page %d, in_page_addr%d ) ,ret = 0x%x\n" ,nPage , nAddr, ret);
arryprintfs("RamdomRead bufr" ,bufr ,+ ) ;
nAddr++;
} }
/*
----------------prints---------------------------
WritePage ok!
RamdomRead(page 34816, in_page_addr1 ) ,uch = 0x1
RamdomRead(page 34816, in_page_addr2 ) ,uch = 0x2
RamdomRead(page 34816, in_page_addr3 ) ,uch = 0x3
RamdomRead(page 34816, in_page_addr4 ) ,uch = 0x4
RamdomRead(page 34816, in_page_addr5 ) ,uch = 0x5
RamdomRead(page 34816, in_page_addr6 ) ,uch = 0x6
RamdomRead(page 34816, in_page_addr7 ) ,uch = 0x7
RamdomRead(page 34816, in_page_addr8 ) ,uch = 0x8
RamdomRead(page 34816, in_page_addr9 ) ,uch = 0x9
RamdomRead(page 34816, in_page_addr10 ) ,uch = 0xa
----------------prints---------------------------
*/
break;
case : //CheckBadBlk from blk0~blk2047
for(ret= ; ret<; ret++) {
CheckBadBlk(ret<<); //ret<<6 : page_addr
}
break;
case : //
if(){
memset(bufr, , sizeof(bufr));
ret = MY_ReadPage(, bufr);
debugs("MY_ReadPage ret==%d\n" , ret);
arryprintfs("ReadPage+0" ,bufr , );
}
break; case : //
if(){
T_ecc() ;
}
break;
}
}
}
#ifndef _NAND_H_
#define _NAND_H_ #include "common.h" #define N_BYTES_NAND_PAGE 2048
#define N_PAGES_NAND_BLOCK 64
#define N_BYTES_NAND_BLOCK (N_PAGES_NAND_BLOCK*N_BYTES_NAND_PAGE) #define EnNandFlash() (rNFCONT |= 1)
#define DsNandFlash() (rNFCONT &= ~1)
#define NFChipEn() (rNFCONT &= ~(1<<1))
#define NFChipDs() (rNFCONT |= (1<<1))
#define InitEcc() (rNFCONT |= (1<<4))
#define MEccUnlock() (rNFCONT &= ~(1<<5))
#define MEccLock() (rNFCONT |= (1<<5))
#define SEccUnlock() (rNFCONT &= ~(1<<6))
#define SEccLock() (rNFCONT |= (1<<6)) #define WrNFDat8(dat) (rNFDATA8 = (dat))
#define WrNFDat32(dat) (rNFDATA = (dat))
#define RdNFDat8() (rNFDATA8) //byte access
#define RdNFDat32() (rNFDATA) //word access #define WrNFCmd(cmd) (rNFCMD = (cmd))
#define WrNFAddr(addr) (rNFADDR = (addr))
#define WrNFDat(dat) WrNFDat8(dat)
#define RdNFDat() RdNFDat8() //for 8 bit nand flash, use byte access #define RdNFMEcc() (rNFMECC0) //for 8 bit nand flash, only use NFMECC0
#define RdNFSEcc() (rNFSECC) //for 8 bit nand flash, only use low 16 bits #define RdNFStat() (rNFSTAT)
#define NFIsBusy() (!(rNFSTAT&1))
#define NFIsReady() (rNFSTAT&1) #define READCMD0 0
#define READCMD1 0x30
#define ERASECMD0 0x60
#define ERASECMD1 0xd0
#define PROGCMD0 0x80
#define PROGCMD1 0x10
#define QUERYCMD 0x70
#define RdIDCMD 0x90 #define RESET_CMD 0xff
#define RANDOM_READCMD0 0x05
#define RANDOM_READCMD1 0xe0
#define RANDOM_PROGRAMCMD 0x85 #define TACLS 1//7 // 1-clk(0ns)
#define TWRPH0 4//7 // 3-clk(25ns)
#define TWRPH1 1//7 // 1-clk(10ns) //TACLS+TWRPH0+TWRPH1>=50ns //func
extern void ReadBlock(U32 addr, U8 buf[][]) ; //pgaddr
extern U32 EraseBlock(U32 addr) ; //pgaddr
extern void WriteBlock(U32 addr, U8 buf[][]); //pgaddr
extern void ReadPage(U32 addr, U8 *buf); //pgaddr
extern U32 WritePage(U32 addr, U8 *buf); //pgaddr
extern int getBlockNum(u32 addr ,u32 BlockNum[]); //0x_addr
extern int getPageNum(u32 addr ,u32 PageNum[]); //0x_addr
extern U32 ReadChipId(void);
extern int CheckNandflash(int info);
#endif
外设:K9F2G08 nandflash 底层读写、控制驱动程序,可随机读写的更多相关文章
-
ElasticSearch(六)底层索引控制
相似度算法 涉及到了ES的底层,首先讲一下ES的底层核心,相似度模型,ES的查询和传统的数据库查询最大的差别就在相似度查询(之前讲过,索引存储的最大差别就是讲非结构化数据转化为结构化),ES里面会给文 ...
-
痞子衡嵌入式:i.MXRT1010, 1170型号上不一样的SNVS GPR寄存器读写控制设计
大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家介绍的是i.MXRT1010, 1170型号上不一样的SNVS GPR寄存器读写控制设计. 痞子衡之前两篇文章 <在SBL项目实战中妙用i ...
-
重新想象 Windows 8.1 Store Apps (90) - 通信的新特性: 通过 HttpBaseProtocolFilter 实现 http 请求的缓存控制,以及 cookie 读写; 自定义 HttpFilter; 其他
[源码下载] 重新想象 Windows 8.1 Store Apps (90) - 通信的新特性: 通过 HttpBaseProtocolFilter 实现 http 请求的缓存控制,以及 cooki ...
-
谁能在同一文件序列化多个对象并随机读写(反序列化)?BinaryFormatter、SoapFormatter、XmlSerializer还是BinaryReader
谁能在同一文件序列化多个对象并随机读写(反序列化)?BinaryFormatter.SoapFormatter.XmlSerializer还是BinaryReader 随机反序列化器 +BIT祝威+悄 ...
-
Perl IO:随机读写文件
随机读写 如果一个文件句柄是指向一个实体文件的,那么就可以对它进行随机数据的访问(包括随机读.写),随机访问表示可以读取文件中的任何一部分数据或者向文件中的任何一个位置处写入数据.实现这种随机读写的功 ...
-
计算机程序的思维逻辑 (60) - 随机读写文件及其应用 - 实现一个简单的KV数据库
57节介绍了字节流, 58节介绍了字符流,它们都是以流的方式读写文件,流的方式有几个限制: 要么读,要么写,不能同时读和写 不能随机读写,只能从头读到尾,且不能重复读,虽然通过缓冲可以实现部分重读,但 ...
-
Java基础之读文件——使用通道随机读写文件(RandomReadWrite)
控制台程序,使用通道随机读写primes_backup.bin文件. import static java.nio.file.StandardOpenOption.*; import java.nio ...
-
从零开始学C++之IO流类库(三):文件的读写、二进制文件的读写、文件随机读写
一.文件的读写 如前面所提,流的读写主要有<<, >>, get, put, read, write 等操作,ofstream 继承自ostream, ifstream 继承自 ...
-
Java IO流之普通文件流和随机读写流区别
普通文件流和随机读写流区别 普通文件流:http://blog.csdn.net/baidu_37107022/article/details/71056011 FileInputStream和Fil ...
随机推荐
-
js基础篇——localStorage使用要点
localStorage主要用来替代cookie,解决cookie(可参考cookie使用要点)读写困难.容量有限的问题.localStorage有以下几个特点 1.localStorage是一个普通 ...
-
java动态生成excel打包下载
@SuppressWarnings("unchecked") public String batchExport() throws DBException{ @SuppressWa ...
-
JS案例之5——移动端触屏滑动
移动端触屏滑动的效果其实就是图片轮播,在PC的页面上很好实现,绑定click和mouseover等事件来完成.但是在移动设备上,要实现这种轮播的效果,就需要用到核心的touch事件.处理touch事件 ...
-
手机变为电脑的摄像头,使像素高清起来-使用DroidCam
你是不是已经在嫌弃电脑自带的摄像头的渣渣像素呢? 今天给大家安利一个方法:将手机摄像头设置为电脑的摄像头,让像素高清起来,对于搞图像的同志们真是福音啊,尤其是做人脸识别的时候. 方法有很多种,我推荐我 ...
-
CentOS环境下,gdb调试中出现:Missing separate debuginfos, use: debuginfo-install.....的问题
在gdb调试时segmentation fault问题时,遇到下面的了问题: Program received signal SIGABRT, Aborted.0x00007ffff73eb925 i ...
-
基于visual Studio2013解决C语言竞赛题之0614递归大元素
题目 解决代码及点评 /************************************************************************/ /* 14. 编一个程 ...
-
UVA 11490 - Just Another Problem(数论)
11490 - Just Another Problem option=com_onlinejudge&Itemid=8&page=show_problem&category= ...
-
【RL-TCPnet网络教程】第21章 RL-TCPnet之高效的事件触发框架
第21章 RL-TCPnet之高效的事件触发框架 本章节为大家讲解高效的事件触发框架实现方法,BSD Socket编程和后面章节要讲解到的FTP.TFTP和HTTP等都非常适合使用这种方式 ...
-
python小程序打包
1.首先先要安装 pip install pywin32 pip install pyinstaller 没有越狱安装不了加个国内镜像地址: pip install pyinstaller -i ht ...
-
JS模块化写法(转)
一.原始写法 模块就是实现特定功能的一组方法. 只要把不同的函数(以及记录状态的变量)简单地放在一起,就算是一个模块. function m1(){ //... } function m2(){ // ...