新一期ARM作业(七)----Nand Flash

目录

描述

解答


描述

  • 1

实现 nand 测试菜单中的  [r]Read nand flash 

 

  • 2

OOB 检测坏块, 改进 nand_read 实现碰到坏块就跳过

 

  • 3

改进 nand_write 实现碰到坏块就跳过

 

  • 4

百度了解一下 NAND ECC

 

解答

  • 1

switch函数 中调用函数 do_read_nand_flash()

switch (c)		 
		{
			case 'q':
			case 'Q':
				return;
				break;
				
			case 's':
			case 'S':
				nand_chip_id();
				break;

			case 'e':
			case 'E':
				do_erase_nand_flash();
				break;

			case 'w':
			case 'W':
				do_write_nand_flash();
				break;

			case 'r':
			case 'R':
				do_read_nand_flash();
				break;
			default:
				break;
		}
void do_read_nand_flash(void)
{
	unsigned int addr;
	volatile unsigned char *p;
	int i, j;
	unsigned char c;
	unsigned char str[16];
	unsigned char buf[64];
	
	/* 获得地址 */
	printf("Enter the address to read: ");
	addr = get_uint();

	nand_read(addr, buf, 64);
	p = (volatile unsigned char *)buf;

	printf("Data : \n\r");
	/* 长度固定为64 */
	for (i = 0; i < 4; i++)
	{
		/* 每行打印16个数据 */
		for (j = 0; j < 16; j++)
		{
			/* 先打印数值 */
			c = *p++;
			str[j] = c;
			printf("%02x ", c);
		}

		printf("   ; ");

		for (j = 0; j < 16; j++)
		{
			/* 后打印字符 */
			if (str[j] < 0x20 || str[j] > 0x7e)  /* 不可视字符 */
				putchar('.');
			else
				putchar(str[j]);
		}
		printf("\n\r");
	}
}

 

  • 2

检测坏块函数 nand_bad()

int nand_bad(unsigned int addr)
{
	unsigned int col  = 2048;
	unsigned int page = addr / 2048;
	unsigned char val;

	/* 1. 选中 */
	nand_select();
	
	/* 2. 发出读命令00h */
	nand_cmd(0x00);
	
	/* 3. 发出地址(分5步发出) */
	nand_col(col);
	nand_page(page);
	
	/* 4. 发出读命令30h */
	nand_cmd(0x30);
	
	/* 5. 判断状态 */
	nand_wait_ready();

	/* 6. 读数据 */
	val = nand_data();
	
	/* 7. 取消选中 */		
	nand_deselect();


	if (val != 0xff)
		return 1;  /* bad blcok */
	else
		return 0;
}

 

nand_read() 读之前,检测坏块,碰到就跳过

void nand_read(unsigned int addr, unsigned char *buf, unsigned int len)
{
	int col = addr % 2048;
	int i = 0;
		
	while (i < len)
	{

		if (!(addr & 0x1FFFF) && nand_bad(addr)) /* 一个block只判断一次 */
		{
			addr += (128*1024);  /* 跳过当前block */
			continue;
		}

		/* 1. 选中 */
		nand_select();
				
		/* 2. 发出读命令00h */
		nand_cmd(0x00);

		/* 3. 发出地址(分5步发出) */
		nand_addr(addr);

		/* 4. 发出读命令30h */
		nand_cmd(0x30);

		/* 5. 判断状态 */
		nand_wait_ready();

		/* 6. 读数据 */
		for (; (col < 2048) && (i < len); col++)
		{
			buf[i] = nand_data();
			i++;
			addr++;
		}	
		col = 0;

		/* 7. 取消选中 */		
		nand_deselect();
	}
}

 

  • 3

检测坏块函数 nand_bad()

int nand_bad(unsigned int addr)
{
	unsigned int col  = 2048;
	unsigned int page = addr / 2048;
	unsigned char val;

	/* 1. 选中 */
	nand_select();
	
	/* 2. 发出读命令00h */
	nand_cmd(0x00);
	
	/* 3. 发出地址(分5步发出) */
	nand_col(col);
	nand_page(page);
	
	/* 4. 发出读命令30h */
	nand_cmd(0x30);
	
	/* 5. 判断状态 */
	nand_wait_ready();

	/* 6. 读数据 */
	val = nand_data();
	
	/* 7. 取消选中 */		
	nand_deselect();


	if (val != 0xff)
		return 1;  /* bad blcok */
	else
		return 0;
}

nand_write() 写之前,检测坏块,碰到就跳过

void nand_write(unsigned int addr, unsigned char *buf, unsigned int len)
{
    unsigned int page = addr / PAGE_SIZE;
    unsigned int col = addr & (PAGE_SIZE-1);
    unsigned int i = 0;

    while(1)
    {
        if(!(addr & 0x1ffff) && nand_bad(addr))
        {
            addr += (128* 1024);
            continue;
        }

        nand_select();
        nand_cmd(CMD_WRITE_1);
        nand_col(col);
        nand_page(page);

        while((col < PAGE_SIZE) && (i<len))
        {
            nand_write_data_byte(buf[i++]);
        }
        nand_cmd(CMD_WRITE_2);
        nand_wait_ready();
        nand_deselect();

        if(i==len)
            break;
        else
        {
            col = 0;
            page++;
        }
    }
}

 

  • 4

ECC 的全称是 Error Checking and Correction ,是一种用于Nand的差错检测和修正算法。如果操作时序和电路稳定性不存在问题的话,NAND Flash出错的时候一般不会造成整个Block或是Page不能读取或是全部出错,而是整个Page(例如512Bytes)中只有一个或几个bit出错。ECC能纠正1个比特错误和检测2个比特错误,而且计算速度很快,但对1比特以上的错误无法纠正,对2比特以上的错误不保证能检测。

 

校验码生成算法:ECC校验每次对256字节的数据进行操作,包含列校验和行校验。对每个待校验的Bit位求异或,若结果为0,则表明含有偶数个1;若结果为1,则表明含有奇数个1。列校验规则如表1所示。256字节数据形成256行、8列的矩阵,矩阵每个元素表示一个Bit位。

其中CP0 ~ CP5 为六个Bit位,表示Column Parity(列极性),

CP0为第0、2、4、6列的极性,CP1为第1、3、5、7列的极性,

CP2为第0、1、4、5列的极性,CP3为第2、3、6、7列的极性,

CP4为第0、1、2、3列的极性,CP5为第4、5、6、7列的极性。

 

用公式表示就是:CP0=Bit0^Bit2^Bit4^Bit6, 表示第0列内部256个Bit位异或之后再跟第2列256个Bit位异或,再跟第4列、第6列的每个Bit位异或,这样,CP0其实是256*4=1024个Bit位异或的结果。CP1 ~ CP5 依此类推。行校验如下图所示

 

综上所述,对256字节的数据共生成了6个Bit的列校验结果,16个Bit的行校验结果,共22个Bit。在Nand中使用3个字节存放校验结果,多余的两个Bit位置1。存放次序如下表所示:

资料参考自 https://www.cnblogs.com/losing-1216/p/4895604.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值