首頁>技術>

重要結構體

nand_chip

struct nand_chip {	void  __iomem	*IO_ADDR_R;	void  __iomem	*IO_ADDR_W;	uint8_t		(*read_byte)(struct mtd_info *mtd);	u16		(*read_word)(struct mtd_info *mtd);	void		(*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);	void		(*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len);	int		(*verify_buf)(struct mtd_info *mtd, const uint8_t *buf, int len);	void		(*select_chip)(struct mtd_info *mtd, int chip);	int		(*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip);	int		(*block_markbad)(struct mtd_info *mtd, loff_t ofs);	void		(*cmd_ctrl)(struct mtd_info *mtd, int dat,				    unsigned int ctrl);	int		(*dev_ready)(struct mtd_info *mtd);	void		(*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr);	int		(*waitfunc)(struct mtd_info *mtd, struct nand_chip *this);	void		(*erase_cmd)(struct mtd_info *mtd, int page);	int		(*scan_bbt)(struct mtd_info *mtd);	int		(*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page);	int		(*write_page)(struct mtd_info *mtd, struct nand_chip *chip,				      const uint8_t *buf, int page, int cached, int raw);	int		chip_delay;	unsigned int	options;	int		page_shift;	int		phys_erase_shift;	int		bbt_erase_shift;	int		chip_shift;	int		numchips;	unsigned long	chipsize;	int		pagemask;	int		pagebuf;	int		subpagesize;	uint8_t		cellinfo;	int		badblockpos;	nand_state_t	state;	uint8_t		*oob_poi;	struct nand_hw_control  *controller;	struct nand_ecclayout	*ecclayout;	struct nand_ecc_ctrl ecc;	struct nand_buffers *buffers;	struct nand_hw_control hwcontrol;	struct mtd_oob_ops ops;	uint8_t		*bbt;	struct nand_bbt_descr	*bbt_td;	struct nand_bbt_descr	*bbt_md;	struct nand_bbt_descr	*badblock_pattern;	void		*priv;};

重要函式呼叫過程

1,int nand_scan(struct mtd_info *mtd, int maxchips)2,int nand_scan_ident(struct mtd_info *mtd, int maxchips)3,nand_set_defaults4,static struct nand_flash_dev *nand_get_flash_type(struct mtd_info *mtd,						  struct nand_chip *chip,						  int busw, int *maf_id)5,int nand_scan_tail(struct mtd_info *mtd)
驅動程式編寫思路(1)分配一個nand_chip和mtd_info結構體(2)根據自己的需要,構造nand_chip結構體。以及一些硬體相關的設定(3)最後就是呼叫nand_scan()和add_mtd_partitions()函式

程式原始碼:

/* 參考  * drivers\mtd\nand\s3c2410.c * drivers\mtd\nand\at91_nand.c */#include <linux/module.h>#include <linux/types.h>#include <linux/init.h>#include <linux/kernel.h>#include <linux/string.h>#include <linux/ioport.h>#include <linux/platform_device.h>#include <linux/delay.h>#include <linux/err.h>#include <linux/slab.h>#include <linux/clk.h> #include <linux/mtd/mtd.h>#include <linux/mtd/nand.h>#include <linux/mtd/nand_ecc.h>#include <linux/mtd/partitions.h> #include <asm/io.h> #include <asm/arch/regs-nand.h>#include <asm/arch/nand.h>#define      	NAND_CHIP_NUM        1#define 		TACLS    				0#define 		TWRPH0   			1#define 		TWRPH1   			0	struct s3c_nand_regs {	unsigned long nfconf  ;	unsigned long nfcont  ;	unsigned long nfcmd   ;	unsigned long nfaddr  ;	unsigned long nfdata  ;	unsigned long nfeccd0 ;	unsigned long nfeccd1 ;	unsigned long nfeccd  ;	unsigned long nfstat  ;	unsigned long nfestat0;	unsigned long nfestat1;	unsigned long nfmecc0 ;	unsigned long nfmecc1 ;	unsigned long nfsecc  ;	unsigned long nfsblk  ;	unsigned long nfeblk  ;};static struct s3c_nand_regs    *s3c_nand_regs;static struct nand_chip           * nand_block;static struct mtd_info           * nand_mtd;static struct mtd_partition s3c_nand_parts[] = {	[0] = {        .name   = "bootloader",        .size   = 0x00040000,		.offset	= 0,	},	[1] = {        .name   = "params",        .offset = MTDPART_OFS_APPEND,        .size   = 0x00020000,	},	[2] = {        .name   = "kernel",        .offset = MTDPART_OFS_APPEND,        .size   = 0x00200000,	},	[3] = {        .name   = "root",        .offset = MTDPART_OFS_APPEND,        .size   = MTDPART_SIZ_FULL,	}};static void configurate_nand_chip(void);static int   s3c2440_dev_ready(struct mtd_info *mtd);static void s3c2440_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl);static void nand_select_chip(struct mtd_info *mtd, int chipnr);static int nand_block_init(void){		nand_block = kzalloc(sizeof(struct nand_chip), GFP_KERNEL);		configurate_nand_chip();	nand_mtd = kzalloc(sizeof(struct mtd_info), GFP_KERNEL); 	nand_mtd->owner = THIS_MODULE;	nand_mtd->priv     = nand_block;	nand_scan(nand_mtd,NAND_CHIP_NUM);	add_mtd_partitions(nand_mtd, s3c_nand_parts, 4);	return 0;}static void nand_block_exit(void){	del_mtd_partitions(nand_mtd);	kfree(nand_mtd);	iounmap(s3c_nand_regs);	kfree(nand_block);		}static int s3c2440_dev_ready(struct mtd_info *mtd){	return (s3c_nand_regs->nfstat & (1<<0));}static void s3c2440_cmd_ctrl(struct mtd_info *mtd, int dat, unsigned int ctrl){	if (ctrl & NAND_CLE)	{		s3c_nand_regs->nfcmd = dat;	}	else	{		s3c_nand_regs->nfaddr = dat;	}}static void nand_select_chip(struct mtd_info *mtd, int chipnr){	switch (chipnr) 	{		case -1:			s3c_nand_regs->nfcont |= (1<<1);				break;		case 0:			s3c_nand_regs->nfcont &= ~(1<<1);			break;		default:			BUG();	}}static void configurate_nand_chip(void){	struct clk *clk;		s3c_nand_regs = ioremap(0x4E000000, sizeof(struct s3c_nand_regs));	nand_block->select_chip = nand_select_chip;	nand_block->cmd_ctrl    = s3c2440_cmd_ctrl;	nand_block->IO_ADDR_R   = &s3c_nand_regs->nfdata;	nand_block->IO_ADDR_W   = &s3c_nand_regs->nfdata;	nand_block->dev_ready   = s3c2440_dev_ready;	nand_block->ecc.mode    = NAND_ECC_SOFT;	clk = clk_get(NULL, "nand");	clk_enable(clk);    		s3c_nand_regs->nfconf = (TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4);	s3c_nand_regs->nfcont = (1<<1) | (1<<0);	}module_init(nand_block_init);module_exit(nand_block_exit);MODULE_LICENSE("GPL");

Makefile

#compile regularKERN_DIR = /work/system/linux-2.6.22.6all:	make -C $(KERN_DIR) M=`pwd` modules	rm -rf modules.order Module.symvers .PHONY:clean:	make -C $(KERN_DIR) M=`pwd` modules clean	rm -rf modules.order Module.symversobj-m   += nand_block.o

14
  • BSA-TRITC(10mg/ml) TRITC-BSA 牛血清白蛋白改性標記羅丹明
  • 跟光磊學Python開發-面向物件進階