⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nand_test.c

📁 SMDK2440 boot code, base on vivi
💻 C
字号:
#include <config.h>#include <types.h>#include <mtd/mtd.h>#include <vstring.h>#include <command.h>#include <vmalloc.h>#define	PATTERN1		0xaa55aa55#define PATTERN2		0x55aa55aa#define NPAGE_SIZE		(512)#define NOOB_SIZE		(16)#define NPAGES			(32)#define NBLOCK_SIZE		(NPAGE_SIZE*NPAGES)unsigned char *data;static int erase_block(struct mtd_info *mtd, ulong ofs){	struct erase_info erase;	erase.addr = ofs;	erase.len = mtd->erasesize;	if (mtd->erase(mtd, &erase))		return 1;	return 0;}static int is_bad_block(struct mtd_info *mtd, ulong ofs){	size_t retlen;	char buf[NOOB_SIZE];	if (mtd->read_oob(mtd, ofs, NOOB_SIZE, &retlen, buf))		return 1;	if (retlen != NOOB_SIZE)		return 1;	if (buf[5] != 0xff)		return 1;	return 0;}static int backup_data(struct mtd_info *mtd, unsigned long ofs){	int i;	unsigned char *b = data;	size_t retlen;	for (i = 0; i < NPAGES; i++) {		if (mtd->read(mtd, ofs, NPAGE_SIZE, &retlen, b))			return 1;		if (retlen != NPAGE_SIZE)			return 1;		b += NPAGE_SIZE;		if (mtd->read_oob(mtd, ofs, NOOB_SIZE, &retlen, b))			return 1;		if (retlen != NOOB_SIZE)			return 1;		b += NOOB_SIZE;		ofs += NPAGE_SIZE;	}	return 0;}static int test_block(struct mtd_info *mtd, ulong ofs){	int i;	ulong tofs;	u_char ob[NPAGE_SIZE];	u_char rb[NPAGE_SIZE];	memset(ob, 0xaa, NPAGE_SIZE);	tofs = ofs;	for (i = 0; i < NPAGES; i++) {		if (mtd->write(mtd, tofs, NPAGE_SIZE, NULL, ob))			return 1;		tofs +=  NPAGE_SIZE;	}	tofs = ofs;	for (i = 0; i < NPAGES; i++) {		if (mtd->read(mtd, tofs, NPAGE_SIZE, NULL, rb))			return 1;		if (memcmp(ob, rb, NPAGE_SIZE)) {			return 1;		}		tofs += NPAGE_SIZE;	}	erase_block(mtd, ofs);	memset(ob, 0x55, NPAGE_SIZE);	tofs = ofs;	for (i = 0; i < NPAGES; i++) {		if (mtd->write(mtd, tofs, NPAGE_SIZE, NULL, ob))			return 1;		tofs +=  NPAGE_SIZE;	}	tofs = ofs;	for (i = 0; i < NPAGES; i++) {		if (mtd->read(mtd, tofs, NPAGE_SIZE, NULL, rb))			return 1;		if (memcmp(ob, rb, NPAGE_SIZE)) {			return 1;		}		tofs += NPAGE_SIZE;	}	return 0;}static int restore_data(struct mtd_info *mtd, unsigned long ofs){	int i;	u_char *b = data;	size_t retlen;	for (i = 0; i < NPAGES; i++) {		if (mtd->write(mtd, ofs, NPAGE_SIZE, &retlen, b))			return 1;		if (retlen != NPAGE_SIZE)			return 1;		b += NPAGE_SIZE;		if (mtd->write_oob(mtd, ofs, NOOB_SIZE, &retlen, b))			return 1;		if (retlen != NOOB_SIZE)			return 1;		b += NOOB_SIZE;		ofs += NPAGE_SIZE;	}	return 0;}void nand_test(unsigned long ofs, unsigned long size){	struct mtd_info *mtd = mymtd;	if (!mymtd) {		printk("There is not MTD\n");		return;	}	if (ofs % NBLOCK_SIZE) {		printk("bad alignment: offset (offset shold be %d times)\n",			NBLOCK_SIZE);		return;	}	if (size % NBLOCK_SIZE) {		printk("bad alignment: size (size shold be %d times)\n",			NBLOCK_SIZE);		return;	}	data = vmalloc((NPAGE_SIZE+NOOB_SIZE)*NPAGES);	if (!data) {		printk("unable to malloc\n");		return;	}	while (size > 0) {		printk("Testing %d(0x%x) block...\n", ofs/NBLOCK_SIZE, ofs);		if (backup_data(mtd, ofs)) {			printk("\tfailed backup data\n");			return;		} else			printk("\tbackup data\n");		if (is_bad_block(mtd, ofs)) {			printk("\tfound BAD mark\n");		}		if (erase_block(mtd, ofs)) {			printk("\tIt's BAD block\n");			printk("\t==> BAD BLOCK\n");			size -= NBLOCK_SIZE;			ofs += NBLOCK_SIZE;			continue;		} else {			printk("\terase block\n");		}		if (test_block(mtd, ofs)) {			printk("\t==> INVLAID BLOCK\n");		} else {			printk("\t==> GOOD BLOCK\n");		}		if (erase_block(mtd, ofs)) {			printk("\tIt's BAD block\n");			printk("\t==> BAD BLOCK\n");			size -= NBLOCK_SIZE;			ofs += NBLOCK_SIZE;			continue;		} else {			printk("\terase block\n");		}		if (restore_data(mtd, ofs)) {			printk("\tfailed restore data\n");			return;		} else			printk("\trestore data\n");		size -= NBLOCK_SIZE;		ofs += NBLOCK_SIZE;	}	free(data);}void cmd_nand_test(int argc, const char **argv){	int i;	unsigned long offset, size;	if ((argc == 1) || (strncmp(argv[1], "help", 4) == 0)) {		printk("ntst offset=<offset> size=<sizeM>\n"			"   test nand flash memeory\n");	}	offset = size = 0;	i = 0;	while (argv[i] != NULL) {		if (strncmp(argv[i], "offset", 6) == 0) {			offset = simple_strtoul((char *)(argv[i] + 7), NULL, 0);		}		if (strncmp(argv[i], "size", 4) == 0) {			size = simple_hstrtoul((char *)(argv[i] + 5));		}		i++;	}	nand_test(offset, size);}user_command_t nandtst_cmd = {	"ntst",	cmd_nand_test,	NULL};

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -