Chinaunix首页 | 论坛 | 博客
  • 博客访问: 381134
  • 博文数量: 87
  • 博客积分: 983
  • 博客等级: 准尉
  • 技术积分: 685
  • 用 户 组: 普通用户
  • 注册时间: 2012-06-25 07:20
文章分类

全部博文(87)

文章存档

2016年(1)

2015年(3)

2014年(55)

2013年(13)

2012年(15)

分类: 嵌入式

2014-02-22 21:34:45

为什么要支持nand启动?这是面试的时候问的一个问题,结果我说是就是多一种支持,事后想想回答的太笨了啊,最起码也得回答个nand便宜啊,至于从sd卡驱动,以后再说。。

nand启动原理很简单,就是用nand的读方法从当前地址拷贝到链接地址,其中的难点是写地址。

以K9F2G08 (256M*8bit) 为例,其地址周期如下图:

其中列地址A0-A10也称为页内地址;行地址A12-A28也成为页号,即页的号码,第五周期的A28也成为块号。而A11是给OOB用的对OOB没有研究,先略过。。。

所以对于向页内的某个地址读写,其实际的地址排布是A28、A27、A26、... ...A13、A12、A10、A9、A8、... ...A2、A1、A0 (没有A11)。
    
另一个难点(也说不上难点,我掌握的不好而已)是关于内存的步长。开始我是这么写的:

        #define NFDATA (*((volatile unsigned long *)0x4E000010))
        。。。。。。
       
 static unsigned long nand_read_data(void)

   {
            return NFDATA;
        }
        。。。。。。
        static void nand_read_to_buf(unsigned char *buf, unsigned long addr, unsigned long count)
       {
             volatile int i = 0;
             unsigned long col = addr & 0x7ff;
  
             nand_select();
             while (i < count)
             {
 
                 nand_write_cmmd(0x00);
                 nand_write_addr(addr);
                 nand_write_cmmd(0x30);
                 nand_wait_ready();
                 for (; (col < 2048) && (i < count); i++, addr++, col++)
                 {
                     buf[i] = nand_read_data();
                 }
                 col = 0;
             }
             nand_deselect();
       }

    但是启动不起来,原因是nand_read_to_buf()的第一个参数buf是char *类型的,而nand_read_data()的返回值类型是unsigned long,肯定不对了,所以应该把nand_read_data()的返回值类型改为unsigned char,#define NFDATA (*((volatile unsigned char*)0x4E000010))
另一种改法就是步长为四字节的处理,但这样的话要求判断是否对齐,而且大小端的问题也要注意到,等系统学习完一遍了在研究。

阅读(866) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~