加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

S5PV210的NandFlash应用(二)

发布时间:2020-12-15 18:06:38 所属栏目:百科 来源:网络整理
导读:准备分析 ? ? ? ? 《S5PV210的NandFlash应用(一)》有很多bug,为了文章完整性就不在原文上进行修改了。(一)是在调试nand_cp.c的时候,程序运行过之后,灯立即亮了起来,让我误以为我的NandFlash读操作正常了,最后在往下进行大文件拷贝的时候出现异常,我

准备分析

? ? ? ? 《S5PV210的NandFlash应用(一)》有很多bug,为了文章完整性就不在原文上进行修改了。(一)是在调试nand_cp.c的时候,程序运行过之后,灯立即亮了起来,让我误以为我的NandFlash读操作正常了,最后在往下进行大文件拷贝的时候出现异常,我不得不重新回到这个Nand_cp.c这里来。这次结合Uart打印出NandFlash读出的数据,和210.bin文件进行对比,发现后边错误很多,但是我的程序也能运行。总结出了(一)里边的bug有: 1.nand_cp.c中应该调用board_init_f_nand(),而非copy_uboot_to_ram_nand()。2.board_init_f_nand中的跳转代码uboot = (void *)0xd024010明显有误,为什么能够运行,就是实质都没有调用;3.是在start.S中通过相跳转到了main函数的,而非链接地址跳转的,造成了假象。 用一天冷静下来,重新来理清思路。 1.先把Uart调试通。2.通过Uart打印出NFDATA8_REG寄存器的值。3.和210.bin二进制文件对比。4.自己做二进制文件到210.bin的后边,进行对比。
? ? ? ??

资源工具

? ? ? ? 同《? S5PV210的LED应用(一)》
? ? ? ? NandFlash: K9GAG08U0F (2G)

着手写程序
? ? ? ? (1) void board_init_f_nand ((unsigned long bootflag)),负责调用copy_uboot_to_ram_nand()和uboot = (void *)0xd0024010;
? ? ? ? (2) int copy_uboot_to_ram_nand (void),判断NandFlash类型页的大小。调用int nandll_read_blocks。
? ? ? ? (3)?int nandll_read_blocks (ulong dst_addr,ulong size,int large_block),读一块大小。
? ? ? ? (4) int nandll_read_page (uchar *buf,ulong addr,int large_block),读一页大小,并通过串口打印出NFDATA8_REG寄存器的值。
具体的实现:

void board_init_f_nand(unsigned long bootflag)
{
	__attribute__((noreturn)) void (*uboot)(void);
	copy_uboot_to_ram_nand();

	/* Jump to U-Boot image */
	uboot = (void *)0xd0024010;
	(*uboot)();
	/* Never returns Here */
}

int copy_uboot_to_ram_nand (void)
{
	int large_block = 0;
	int i;
	vu_char id;

	NAND_CONTROL_ENABLE();
  NAND_ENABLE_CE();
  NFCMD_REG = NAND_CMD_READID;
  NFADDR_REG =  0x00;

	/* wait for a while */
  for (i=0; i<200; i++);
	id = NFDATA8_REG;
	id = NFDATA8_REG;

	if (id > 0x80)
		large_block = 1;
		
	if(id == 0xd5)
	{ //page_size = 8k
		large_block = 3;
	}

	/* read NAND Block.
	 * 128KB ->240KB because of U-Boot size increase. by scsuh
	 * So,read 0x3c000 bytes not 0x20000(128KB).
	 */
	//return nandll_read_blocks(CONFIG_SYS_TEXT_BASE,COPY_BL2_SIZE,large_block);
	return nandll_read_blocks(0xd0024000,0x4000,large_block);
}

/*
 * Read data from NAND.
 */
static int nandll_read_blocks (ulong dst_addr,int large_block)
{
	uchar *buf = (uchar *)dst_addr;
	int i;
	uint page_shift = 9;

	if (1 == large_block)
	{
		page_shift = 11;
	
		/* Read pages */
		for (i = (0x6000>>page_shift); i < (size>>page_shift); i++,buf+=(1<<page_shift)) 
		{
			nandll_read_page(buf,i,large_block);
		}
	}
	else if(3 == large_block)
	{
		page_shift = 13;
		
		for (i = 0; i < 4; i++,buf+=(1<<(page_shift-1))) 
		{
		        nandll_read_page(buf,large_block-1);
		}
	}
        
	return 0;
}

/*
 * address format
 *              17 16         9 8            0
 * --------------------------------------------
 * | block(12bit) | page(5bit) | offset(9bit) |
 * --------------------------------------------
 */

static int nandll_read_page (uchar *buf,int large_block)
{
	int i;
	volatile char c;
	int page_size = 512;

	if (1 == large_block)
		page_size = 2048;
		
	else if (2 == large_block)
		page_size = 4096;
	
	else if (3 == large_block)
		page_size = 8192;

	NAND_ENABLE_CE();

	NFCMD_REG = NAND_CMD_READ0;

	/* Write Address */
	NFADDR_REG = 0;

	if (large_block)
		NFADDR_REG = 0;

	NFADDR_REG = (addr) & 0xff;
	NFADDR_REG = (addr >> 8) & 0xff;
	NFADDR_REG = (addr >> 16) & 0xff;

	if (large_block)
		NFCMD_REG = NAND_CMD_READSTART;

        NF_TRANSRnB();

	/* for compatibility(2460). u32 cannot be used. by scsuh */
	for(i=0; i < page_size; i++) 
	{
		c = NFDATA8_REG; 
		*buf++ = c;
		puthex(c);
		putc(' ');
                
  }

	NAND_DISABLE_CE();
	return 0;
}

下载运行

? ? ? ? 同《? S5PV210的LED应用(一)》

运行调试
? ? ? ?
? ? ? ? 对比如图所示:




? ? ? ? 得到结论,前16k代码在NandFlash存储方式如下:
? ? ? ? ?


遗留问题
??
? ? ? ? 1.无

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读