nuc900 nand flash mtd 驱动
nuc900 nand flash mtd 驱动,请参考!
/*
* Copyright © 2009 Nuvoton technology corporation.
*
* Wan ZongShun <mcuos.com@gmail.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation;version 2 of the License.
*
*/ #include <linux/slab.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/clk.h>
#include <linux/err.h>
#include <linux/blkdev.h> #include <linux/mtd/mtd.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/partitions.h>
#include <linux/dma-mapping.h> #include <mach/map.h>
#include <mach/regs-clock.h>
#include <mach/regs-fmi.h>
#include <mach/gnand/GNAND.h>
#include <mach/nuc900_nand.h>
#define REG_MFSEL (W90X900_VA_GCR + 0xC)
/*
#define REG_FMICSR 0x00
#define REG_SMCSR 0xa0
#define REG_SMISR 0xac
#define REG_SMCMD 0xb0
#define REG_SMADDR 0xb4
#define REG_SMDATA 0xb8
*/
#define RESET_FMI 0x01
#define NAND_EN 0x08
#define READYBUSY (0x01 << 18) #define SWRST 0x01
#define PSIZE (0x01 << 3)
#define DMARWEN (0x03 << 1)
#define BUSWID (0x01 << 4)
#define ECC4EN (0x01 << 5)
#define WP (0x01 << 24)
#define NANDCS (0x03 << 25)
#define ENDADDR (0x01 << 31) #define NANDCS1 (0x01 << 25)
#define ECCBYTE512 3
#define ECCBYTE2K 3 /* DMAC Control and Status Register (DMACCSR) */
#define DMACCSR_DMACEN (1)
#define DMACCSR_SW_RST (1<<1)
#define DMACCSR_SG_EN1 (1<<2)
#define DMACCSR_SG_EN2 (1<<3)
#define DMACCSR_ATA_BUSY (1<<8)
#define DMACCSR_FMI_BUSY (1<<9) /******************************************/
#define FMI_ERR_ID 0xFFFF0100 #define FMI_TIMEOUT (FMI_ERR_ID|0x01)
/* NAND error */
#define FMI_SM_INIT_ERROR (FMI_ERR_ID|0x20)
#define FMI_SM_RB_ERR (FMI_ERR_ID|0x21)
#define FMI_SM_STATE_ERROR (FMI_ERR_ID|0x22)
#define FMI_SM_ECC_ERROR (FMI_ERR_ID|0x23)
#define FMI_SM_STATUS_ERR (FMI_ERR_ID|0x24)
#define FMI_SM_ID_ERR (FMI_ERR_ID|0x25)
#define FMI_SM_INVALID_BLOCK (FMI_ERR_ID|0x26) bool volatile _fmi_bIsSMDataReady=;
//#define DEBUG_NAND
//#define nuc900_nand_debug(fmt,args...) printk(fmt,##args)
#define nuc900_nand_debug(fmt,args...) #define read_data_reg(dev) \
__raw_readl(REG_SMDATA) #define write_data_reg(dev, val) \
__raw_writel((val), REG_SMDATA) #define write_cmd_reg(dev, val) \
__raw_writel((val), REG_SMCMD) #define write_addr_reg(dev, val) \
__raw_writel((val), REG_SMADDR)
#define nuc900_nand_read(reg) __raw_readl(reg) struct nuc900_nand {
struct mtd_info mtd;
struct nand_chip chip;
void __iomem *reg;
struct clk *clk;
spinlock_t lock;
};
extern struct semaphore fmi_sem;
extern struct semaphore dmac_sem; #define NUM_PARTITIONS 4 /*请保证分区的总和数和nandflash的实际大小一致,目前开发板上的nandflash是128M*/
#define UBOOT_SIZE SZ_1M*1
#define KERNEL_SIZE SZ_1M*5
#define ROOT_SIZE SZ_1M*44
#define USER_SIZE SZ_1M*78 /*vitual addr and phy addr for dma */
static unsigned char * nand_vaddr = NULL;
static unsigned char * nand_phyaddr = NULL; static const struct mtd_partition partitions[] = {
{ .name = "U-boot",
.offset = ,
.size = UBOOT_SIZE
},
{ .name = "linux 2.6.35 kernel",
.offset = UBOOT_SIZE,
.size = KERNEL_SIZE
},
{ .name = "root",
.offset = UBOOT_SIZE+KERNEL_SIZE,
.size = ROOT_SIZE
},
{ .name = "user",
.offset = UBOOT_SIZE+KERNEL_SIZE+ROOT_SIZE,
.size = USER_SIZE
}
}; static unsigned char nuc900_nand_read_byte(struct mtd_info *mtd)
{
unsigned char ret;
struct nuc900_nand *nand; nand = container_of(mtd, struct nuc900_nand, mtd);
__raw_writel( NAND_EN, REG_FMICSR);
ret = (unsigned char)read_data_reg(nand); return ret;
} static void nuc900_nand_read_buf(struct mtd_info *mtd,
unsigned char *buf, int len)
{
int i;
struct nand_chip *chip = mtd->priv;
//nuc900_nand_debug("nuc900_nand_read_buf: len=%d\n",len);
__raw_writel( NAND_EN, REG_FMICSR);
if(len==mtd->oobsize){// read oob data
chip->cmdfunc(mtd, NAND_CMD_RNDOUT, mtd->writesize, -);
if(down_interruptible(&fmi_sem)) //jhe+ 2010.12.21
{
printk("nuc900 mtd nand driver read buf sem error\n");
return;
}
for (i = ; i < len; i++)
buf[i] = __raw_readl(REG_SMDATA)& 0xff; #ifdef DEBUG_NAND
nuc900_nand_debug("oob read\n");
for (i = ; i < len; i++)
nuc900_nand_debug(" 0x%02x |",buf[i]);
nuc900_nand_debug("\n");
#endif goto readout1;
}
if(down_interruptible(&fmi_sem)) //jhe+ 2010.12.21
{
printk("nuc900 mtd nand driver read buf sem error\n");
return;
} //normal page read use dma
if (down_interruptible(&dmac_sem))
return ;
while (__raw_readl(REG_DMACCSR)&DMACCSR_FMI_BUSY); //Wait IP finished... for safe
__raw_writel((unsigned long)nand_phyaddr,REG_DMACSAR2);
_fmi_bIsSMDataReady = ;
__raw_writel(__raw_readl(REG_SMCSR) | 0x02,REG_SMCSR); //enable DMA read
while (!_fmi_bIsSMDataReady);
up(&dmac_sem); memcpy(buf,nand_vaddr,len); readout1:
up(&fmi_sem);
} static void nuc900_nand_write_buf(struct mtd_info *mtd,
const unsigned char *buf, int len)
{
int i;
struct nand_chip *chip = mtd->priv;
int length = mtd->oobsize;
int dmanum = ; //nuc900_nand_debug("nuc900nand write buf:len=%d\n",len);
__raw_writel( NAND_EN, REG_FMICSR);
if(len==length){// write for oob
chip->cmdfunc(mtd, NAND_CMD_RNDIN, mtd->writesize, -);
if(down_interruptible(&fmi_sem)) //jhe+ 2010.12.21
{
printk("nuc900 mtd nand driver write buf sem error\n");
return;
}
#ifdef DEBUG_NAND
nuc900_nand_debug("oobdata:len=%d\n",len);
for (i = ; i < len; i++)
nuc900_nand_debug(" 0x%02x |",buf[i]);
nuc900_nand_debug("\n");
#endif i=;
while(i<len){
__raw_writel(buf[i],REG_SMDATA);
i=i+;
} goto write_out;
} if(down_interruptible(&fmi_sem)) //jhe+ 2010.12.21
{
printk("nuc900 mtd nand driver write buf sem error\n");
return;
}
//normal page write use dma
while(dmanum < len)//give the first 512 to the dma space
{
nand_vaddr[dmanum] = buf[dmanum];
dmanum++;
} while(dmanum < )
{
nand_vaddr[dmanum] = 0xff;
dmanum++;
}
#if 0
nuc900_nand_debug("\n");
nuc900_nand_debug(" 0x%02x |",__raw_readl(REG_SMRA_0));
nuc900_nand_debug(" 0x%02x |",__raw_readl(REG_SMRA_1));
nuc900_nand_debug(" 0x%02x |",__raw_readl(REG_SMRA_2));
nuc900_nand_debug(" 0x%02x |",__raw_readl(REG_SMRA_3));
nuc900_nand_debug(" 0x%02x |",__raw_readl(REG_SMRA_4));
nuc900_nand_debug(" 0x%02x |",__raw_readl(REG_SMRA_5));
nuc900_nand_debug(" 0x%02x |",__raw_readl(REG_SMRA_6));
nuc900_nand_debug(" 0x%02x |",__raw_readl(REG_SMRA_7));
nuc900_nand_debug(" 0x%02x |",__raw_readl(REG_SMRA_8));
nuc900_nand_debug(" 0x%02x |",__raw_readl(REG_SMRA_9));
nuc900_nand_debug(" 0x%02x |",__raw_readl(REG_SMRA_10));
nuc900_nand_debug(" 0x%02x |",__raw_readl(REG_SMRA_11));
nuc900_nand_debug(" 0x%02x |",__raw_readl(REG_SMRA_12));
nuc900_nand_debug(" 0x%02x |",__raw_readl(REG_SMRA_13));
nuc900_nand_debug(" 0x%02x |",__raw_readl(REG_SMRA_14));
nuc900_nand_debug(" 0x%02x |",__raw_readl(REG_SMRA_15));
nuc900_nand_debug("\n");
#endif
if (down_interruptible(&dmac_sem))
return ;
//normal page write use dma
while (__raw_readl(REG_DMACCSR)&DMACCSR_FMI_BUSY); //Wait IP finished... for safe
__raw_writel((unsigned long)nand_phyaddr,REG_DMACSAR2);
_fmi_bIsSMDataReady = ;
__raw_writel(__raw_readl(REG_SMCSR) | 0x04,REG_SMCSR); //enable DMA write
while (!_fmi_bIsSMDataReady);//wait for dma finished
//__raw_writel(__raw_readl(REG_SMISR)|0x01,REG_SMISR); //clear DMA finished flag
// __raw_writel(0x11223344,REG_SMRA_15);
up(&dmac_sem);
write_out:
up(&fmi_sem);
return;
} /* select chip */
static void nuc900_nand_select_chip(struct mtd_info *mtd, int chipnr)
{
struct nuc900_nand *nand;
nand = container_of(mtd, struct nuc900_nand, mtd); if(down_interruptible(&fmi_sem)) //jhe+ 2010.12.21
{
printk("nuc900 mtd nand driver select_chip sem error\n");
return ;
}
__raw_writel( NAND_EN, REG_FMICSR);
switch (chipnr) {
case -://no chip selected
__raw_writel(__raw_readl(REG_SMCSR) | NANDCS,
REG_SMCSR);
break;
case ://select nand chip 0
__raw_writel(__raw_readl(REG_SMCSR) & ~NANDCS,
REG_SMCSR);
break;
case ://select nand chip 1
__raw_writel((__raw_readl(REG_SMCSR) & (~NANDCS))| NANDCS1,
REG_SMCSR);
break;
default:
BUG();
} up(&fmi_sem); }
static int nuc900_check_rb(struct nuc900_nand *nand)
{
unsigned int val;
spin_lock(&nand->lock);
__raw_writel( NAND_EN, REG_FMICSR);
val = __raw_readl(REG_SMISR );
val &= READYBUSY;
spin_unlock(&nand->lock); return val;
} static int nuc900_nand_devready(struct mtd_info *mtd)
{
struct nuc900_nand *nand;
int ready; nand = container_of(mtd, struct nuc900_nand, mtd);
__raw_writel( NAND_EN, REG_FMICSR);
ready = (nuc900_check_rb(nand)) ? : ;
return ready;
}
/* functions */
int fmiSMCheckRB(void)
{
__raw_writel( NAND_EN, REG_FMICSR);
while () {
if (__raw_readl(REG_SMISR) & 0x400) {
__raw_writel(0x400,REG_SMISR);
return ;
}
}
return ;
}
static void nuc900_nand_command_lp(struct mtd_info *mtd, unsigned int command,
int column, int page_addr)
{
register struct nand_chip *chip = mtd->priv;
struct nuc900_nand *nand;
//nuc900_nand_debug("command=0x%x,column=0x%x,page_addr=0x%x\n",command,column,page_addr);
nand = container_of(mtd, struct nuc900_nand, mtd);
// enable SM
__raw_writel( NAND_EN, REG_FMICSR); if (command == NAND_CMD_READOOB) {
column += mtd->writesize;
command = NAND_CMD_READ0;
}
if((command == NAND_CMD_READ0)||(command ==NAND_CMD_SEQIN)){
//nuc900_nand_debug("clear R/B flag before cmd\n");
/* clear R/B flag */
while (!(__raw_readl(REG_SMISR) & 0x40000));
__raw_writel(0x400, REG_SMISR);
} write_cmd_reg(nand, command & 0xff); if (column != - || page_addr != -) { if (column != -) {
if (chip->options & NAND_BUSWIDTH_16)
column >>= ;
write_addr_reg(nand, column);
write_addr_reg(nand, column >> | ENDADDR);
}
if (page_addr != -) {
write_addr_reg(nand, page_addr); if (chip->chipsize > ( << )) {
write_addr_reg(nand, page_addr >> );
write_addr_reg(nand, page_addr >> | ENDADDR);
} else {
write_addr_reg(nand, page_addr >> | ENDADDR);
}
}
} switch (command) {
case NAND_CMD_CACHEDPROG:
case NAND_CMD_ERASE1:
case NAND_CMD_ERASE2:
case NAND_CMD_SEQIN:
case NAND_CMD_RNDIN: case NAND_CMD_DEPLETE1:
//nuc900_nand_debug("command=0x%x\n",command);
return;
case NAND_CMD_PAGEPROG:
fmiSMCheckRB();
return;
case NAND_CMD_STATUS:
if (__raw_readl(REG_SMDATA) & 0x01) { // 1:fail; 0:pass
// printk("Nand Status error!!\n");
return;
}
return;
case NAND_CMD_STATUS_ERROR:
case NAND_CMD_STATUS_ERROR0:
case NAND_CMD_STATUS_ERROR1:
case NAND_CMD_STATUS_ERROR2:
case NAND_CMD_STATUS_ERROR3:
udelay(chip->chip_delay);
return; case NAND_CMD_RESET:
if (chip->dev_ready)
break;
udelay(chip->chip_delay); write_cmd_reg(nand, NAND_CMD_STATUS);
write_cmd_reg(nand, command); while (!nuc900_check_rb(nand))
; return; case NAND_CMD_RNDOUT:
write_cmd_reg(nand, NAND_CMD_RNDOUTSTART); return; case NAND_CMD_READ0: write_cmd_reg(nand, NAND_CMD_READSTART);
fmiSMCheckRB();
break; default: if (!chip->dev_ready) {
udelay(chip->chip_delay);
return;
}
} /* Apply this short delay always to ensure that we do wait tWB in
* any case on any machine. */
//ndelay(100); while (!chip->dev_ready(mtd))
;
} // SM functions
int fmiSM_Reset(void)
{ u32 volatile i;
__raw_writel( NAND_EN, REG_FMICSR);
__raw_writel(0xff,REG_SMCMD);
for (i=; i>; i--); if (!fmiSMCheckRB())
return -;
return ;
} static void nuc900_nand_enable(struct nuc900_nand *nand)
{ unsigned int val; if(down_interruptible(&fmi_sem)) //jhe+ 2010.12.21
{
printk("nuc900 mtd nand driver nand_enable sem error\n");
return;
}
spin_lock(&nand->lock); // enable SM
__raw_writel( 0x3050b, REG_SMTCR );//set timer control
__raw_writel( NAND_EN, REG_FMICSR); /* init SM interface */
__raw_writel((__raw_readl(REG_SMCSR)&0xf8ffffc0), REG_SMCSR); // disable ecc4
fmiSM_Reset();
__raw_writel((__raw_readl(REG_SMCSR)&0xfffffff0)|0x01000008, REG_SMCSR); // psize:2048; wp# set 1 //
__raw_writel(0x01, REG_SMIER);//enable dma interrupter
spin_unlock(&nand->lock);
up(&fmi_sem);
} static irqreturn_t fmi_interrupt(int irq, void *devid)
{
unsigned int volatile isr;
// SM interrupt status
isr = __raw_readl(REG_SMISR);
///printk("fmi_interrupt\n");
//DMA read/write transfer is done
if (isr & 0x01) {
_fmi_bIsSMDataReady = ;
__raw_writel(0x01,REG_SMISR);
return IRQ_HANDLED;
} else {
return IRQ_NONE;
} } static int __devinit nuc900_nand_probe(struct platform_device *pdev)
{
struct nuc900_nand *nuc900_nand;
struct mtd_info *mtd;
struct nand_chip *chip;
int retval;
struct resource *res;
nuc900_nand_debug("nuc900_nand_probe in\n"); nand_vaddr = (unsigned char *) dma_alloc_coherent(NULL,, (dma_addr_t *) &nand_phyaddr, GFP_KERNEL);
if(nand_vaddr == NULL){
printk(KERN_ERR "NUC900_nand: failed to allocate ram for nand data.\n");
return -ENOMEM;
} retval = ;
/* Allocate memory for the device structure (and zero it) */
nuc900_nand = kzalloc(sizeof(struct nuc900_nand), GFP_KERNEL);
if (!nuc900_nand){
printk(KERN_ERR "NUC900_nand: failed to allocate device structure.\n");
return -ENOMEM;
}
mtd=&nuc900_nand->mtd;
chip = &(nuc900_nand->chip); chip->priv = nuc900_nand; /* link the private data structures */
mtd->priv = chip;
mtd->owner = THIS_MODULE;
spin_lock_init(&nuc900_nand->lock); __raw_writel(__raw_readl(REG_CLKEN) | 0x30,REG_CLKEN);
__raw_writel(((__raw_readl(REG_MFSEL) & 0xFFFFFFF3) | 0x00000004),REG_MFSEL); /* select NAND function pins */ if (request_irq(, fmi_interrupt, IRQF_SHARED, "900_NAND", &pdev->dev)) {
printk("NAND: Request IRQ error\n");
retval = -ENOENT;
goto fail1;
}
if (down_interruptible(&dmac_sem)){
retval = -ENOENT;
goto fail1;
}
while (__raw_readl(REG_DMACCSR)&DMACCSR_FMI_BUSY); //Wait IP finished... for safe
// DMAC Initial
__raw_writel(0x00000003, REG_DMACCSR);
//Enable DMAC
__raw_writel(0x00000001, REG_DMACCSR);
// Enable target abort interrupt generation during DMA transfer.
__raw_writel(0x00000001, REG_DMACIER);
up(&dmac_sem); /* init SM interface */
__raw_writel((__raw_readl(REG_SMCSR)&0xf8ffffc0),REG_SMCSR); // disable ecc4
if (down_interruptible(&dmac_sem)){
retval = -ENOENT;
goto fail1;
}
while (__raw_readl(REG_DMACCSR)&DMACCSR_FMI_BUSY); //Wait IP finished... for safe // enable all
__raw_writel(__raw_readl(REG_DMACCSR) | DMACCSR_DMACEN, REG_DMACCSR); //enable DMAC for FMI /* enable all interrupt */
__raw_writel(DMACIER_TABORT_IE, REG_DMACIER); //Enable target abort interrupt generation during DMA transfer
__raw_writel(FMIIER_DTA_IE, REG_FMIIER); //Enable DMAC READ/WRITE target abort interrupt generation
up(&dmac_sem); chip->cmdfunc = nuc900_nand_command_lp;
chip->dev_ready = nuc900_nand_devready;
chip->read_byte = nuc900_nand_read_byte;
chip->write_buf = nuc900_nand_write_buf;
chip->read_buf = nuc900_nand_read_buf;
chip->select_chip = nuc900_nand_select_chip;
chip->chip_delay = ;
chip->options = ;
chip->ecc.mode = NAND_ECC_SOFT;
chip->ecc.size = ;
chip->ecc.bytes = ; platform_set_drvdata(pdev, nuc900_nand); nuc900_nand_enable(nuc900_nand);
nuc900_nand_debug("REG_SMCSR=0x%x,REG_SMIER=0x%x,SMTCR=0x%x\n",__raw_readl(REG_SMCSR),__raw_readl(REG_SMIER),__raw_readl(REG_SMTCR)); /* first scan to find the device and get the page size */
if (nand_scan_ident(mtd, , NULL)) {
retval = -ENXIO;
goto err_scan_ident;
} //chip->ecc.bytes = CONFIG_SYS_NAND_ECCBYTES;
/* ECC is calculated for the whole page (1 step) */
//chip->ecc.size = mtd->writesize;
/* set ECC page size */
switch (mtd->writesize) {
case :
__raw_writel( __raw_readl(REG_SMCSR) & ( ~PSIZE ), REG_SMCSR ); // psize:512; wp# set 1
//chip->ecc.bytes =ECCBYTE512;
break;
case :
__raw_writel( __raw_readl(REG_SMCSR)|PSIZE , REG_SMCSR ); // psize:2048; wp# set 1
//chip->ecc.bytes =ECCBYTE2K;
break;
default:
/* page size not handled by HW ECC */
/* switching back to soft ECC */
chip->ecc.mode = NAND_ECC_SOFT;
chip->ecc.calculate = NULL;
chip->ecc.correct = NULL;
chip->ecc.hwctl = NULL;
chip->ecc.read_page = NULL;
chip->ecc.postpad = ;
chip->ecc.prepad = ;
chip->ecc.bytes = ;
break;
} /* second phase scan */
if (nand_scan_tail(mtd)) { dma_free_coherent(NULL, , nand_vaddr, (dma_addr_t )nand_phyaddr);
retval = -ENXIO;
goto fail3;
} add_mtd_partitions(mtd, partitions,
ARRAY_SIZE(partitions)); return retval; fail3:
nuc900_nand_debug("nuc900_nand_probe fail3\n");
//iounmap(nuc900_nand->reg);
err_scan_ident:
platform_set_drvdata(pdev, NULL);
fail2:
//nuc900_nand_debug("nuc900_nand_probe fail2\n");
//release_mem_region(res->start, resource_size(res));
fail1:
nuc900_nand_debug("nuc900_nand_probe fail1\n");
kfree(nuc900_nand);
return retval;
} static int __devexit nuc900_nand_remove(struct platform_device *pdev)
{
struct nuc900_nand *nuc900_nand = platform_get_drvdata(pdev);
//struct resource *res;
struct mtd_info *mtd = &nuc900_nand->mtd; nand_release(mtd);
//iounmap(nuc900_nand->reg);
//res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
//release_mem_region(res->start, resource_size(res)); //clk_disable(nuc900_nand->clk);
//clk_put(nuc900_nand->clk);
free_irq(IRQ_FMI, NULL);
kfree(nuc900_nand);
/* Free dma space */
dma_free_coherent(NULL, , nand_vaddr, (dma_addr_t )nand_phyaddr); platform_set_drvdata(pdev, NULL); return ;
} static struct platform_driver nuc900_nand_driver = {
.probe = nuc900_nand_probe,
.remove = __devexit_p(nuc900_nand_remove),
.driver = {
.name = "nuc900-nand",
.owner = THIS_MODULE,
},
}; static int __init nuc900_nand_init(void)
{
return platform_driver_register(&nuc900_nand_driver);
} static void __exit nuc900_nand_exit(void)
{
platform_driver_unregister(&nuc900_nand_driver);
} module_init(nuc900_nand_init);
module_exit(nuc900_nand_exit); MODULE_AUTHOR("Tanshi Li <dolphin96011@gmail.com>");
MODULE_DESCRIPTION("w90p910/NUC9xx nand driver!");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:nuc900-nand");
nuc900 nand flash mtd 驱动的更多相关文章
- nuc950支持nand的mtd驱动的kernel修改
支持nand的mtd驱动的kernel修改 一.更新nanddriver文件 将新的nanddriver文件nuc900_nand.c放到kernel的drivers/mtd/nand目录下 二.修改 ...
- linux2.6.30.4内核移植(2)——Nand Flash驱动移植
内核源码:linux2.6.30.4 交叉编译工具:3.4.5 移植linux内核至:TQ2440 工作基础:http://www.cnblogs.com/nufangrensheng/p/36696 ...
- 【驱动】Flash设备驱动基础·NOR·NAND
Flash存储器 ——>Flash存储器是近几年来发展最快的存储设备,通常也称作闪存.Flash属于EEPROM(电可擦除可编程只读存储器),是一类存取速度很高的存储器. ——>它既有RO ...
- 关于NAND flash的MTD分区与uboot中分区的理解
关于NAND flash的MTD分区与uboot中分区的理解 转自:http://blog.csdn.net/yjp19871013/article/details/6933455?=40085044 ...
- nand flash详解及驱动编写
https://www.crifan.com/files/doc/docbook/linux_nand_driver/release/html/linux_nand_driver.html#nand_ ...
- 如何编写linux下nand flash驱动-4
2. 软件方面 如果想要在Linux下编写Nand Flash驱动,那么就先要搞清楚Linux下,关于此部分的整个框架.弄明白,系统是如何管理你的nand flash的,以及,系统都帮你做 ...
- 十八、Nand Flash驱动和Nor Flash驱动
在读者学习本章之前,最好了解Nand Flash读写过程和操作,可以参考:Nand Flash裸机操作. 一开始想在本章写eMMC框架和设备驱动,但是没有找到关于eMMC设备驱动具体写法,所以本章仍继 ...
- NAND FLASH驱动框架以及程序实现
1.NAND FLASH的硬件连接: 实验用的NAND FLASH芯片为K9F2G08U0C,它是三星公司的存储芯片,它的大小为256M.它的接线图如下所示: 它的每个引脚的分别为LDATA0-LDA ...
- nand flash 扇区的管理以及初始化
(1)首先需要了解NAND FLASH的结构.如图: 以镁光MT29F4G08BxB Nand Flash为例,这款Flash(如上图)以4个扇区(sector)组成1个页(page),64个页(pa ...
随机推荐
- Android实现OCR扫描识别数字图片之图片扫描识别
[Android实例] Android实现OCR扫描识别数字图片之图片扫描识别 Android可以识别和扫描二维码,但是识别字符串呢? google提供了以下解决方案用的是原来HP的相关资料. 可以吧 ...
- TabHost结合RadioButton实现主页的导航效果
布局文件的设置,如下 <?xml version="1.0" encoding="utf-8"?> <TabHost xmlns:androi ...
- enigma机的原理
注:本文修改自三思科学<ENIGMA的兴亡> ENIGMA ENIGMA看起来是一个装满了复杂而精致的元件的盒子.不过要是我们把它打开来,就可以看到它可以被分解成相当 ...
- UML学习之类图
參考链接: http://www.uml.org.cn/oobject/201211231.asp 深入浅出UML http://www.open-open.com/lib/view/open132 ...
- Android 网络技术HTTP
1.XML3种解析方式(DOM.SAX.PULL) 在网络上传输数据时最常用的格式有两种,XML 和JSON 这里首先明白什么是SAX是一个用于处理XML事件驱动的"推"模型,优点 ...
- UVA 11212 IDA*
移动一块连续的区间使得数列递增.问最少次数. 直接IDA*暴搜,只是我没有想到A*函数,所以就随手写了个连续递增块数作为估价函数,WA了,然后除以2,还是WA,除以3,WA,除以4...过了= = # ...
- rpc远程过程协议调用
在linux 5.X以及下的版本你可以通过service portmap status命令查看rpc是否启动.如果提示running,表示正在运行:如果提示stop就是关闭了.如果没有安装,则通过安装 ...
- MySQL的字符编码体系(二)——传输数据编码
MySQL的字符编码体系能够分成两部分:一部分是关于数据库server本身存储数据表时怎样管理字符数据的编码:还有一部分是关于client与数据库server数据传输怎样编码.上一篇MySQL的字符编 ...
- HTTP in iOS你看我就够
HTTP属于老话题了,在项目中我们经常需要往服务端发POST或者GET请求,但是对于HTTP的了解不应只局限于此.千里之行,始于足下.越想走的远,基本原理就应该了解的透彻全面一些,仅仅停留在使用ASI ...
- objective c的注释规范
以前写android程序,每写一个函数或者类就添加对应的注释,后来领导让生成api文档,直接使用了eclipse的到处文档功能,强大又方便,这次换作ios开发,我想肯定也有对应的注释,于是上网查找了一 ...