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

移植uboot到TQ2440出现No NAND device found!!!的解决办法

发布时间:2020-12-15 06:20:58 所属栏目:百科 来源:网络整理
导读:在增加Nand读写支持的时候,曾经一度出现下面的错误信息: NAND:No NAND device found!!!? 0MiB 这个信息曾经困扰了我很久,终于在某一天成功的解决了。在此写下以记录教训! 首先,用Source Insight搜索这个信息的打印出处,在drivers/mtd/nand/nand_base.
在增加Nand读写支持的时候,曾经一度出现下面的错误信息:

NAND:No NAND device found!!!? 0MiB

这个信息曾经困扰了我很久,终于在某一天成功的解决了。在此写下以记录教训!

首先,用Source Insight搜索这个信息的打印出处,在drivers/mtd/nand/nand_base.c文件:

intnand_scan_ident(struct mtd_info *mtd,int maxchips)

{

?????? int i,busw,nand_maf_id;

?????? struct nand_chip *chip = mtd->priv;

?????? struct nand_flash_dev *type;

?????? ……

?????? type = nand_get_flash_type(mtd,chip,&nand_maf_id);

?

?????? if (IS_ERR(type)) {

#ifndefCONFIG_SYS_NAND_QUIET_TEST

????????????? printk(KERN_WARNING "No NAND device found!!!n");

#endif

?????? ……

}

根据打印条件,判断是type返回值出错,于是分析nand_get_flash_type函数,可以发现在函数中有这么两行:

?????? if (!type)

????????????? return ERR_PTR(-ENODEV);

因此猜测是type出错了,于是向上查找type的赋值情况,在紧挨着上述两行代码前面有这么几行:

?????? /* Lookup the flash id */

?????? for (i = 0; nand_flash_ids[i].name !=NULL; i++) {

????????????? if (dev_id ==nand_flash_ids[i].id) {

???????????????????? type =? &nand_flash_ids[i];

???????????????????? break;

????????????? }

?????? }

这段代码是Nand ID的匹配查找工作,在源代码的文件drivers/mtd/nand/nand_ids.c文件中定义了常见的Nand Flash厂商号和设备号,上述代码就是把从硬件Flash中读取到的设备号与源码中的Nand Flash ID列表进行比对,如果有一个ID与从硬件NAND上读取的ID匹配,说明找到了外设Nand,否则就没找到。根据这个信息,我们在这个函数的前面找到了读取硬件ID的代码:

?????? chip->cmdfunc(mtd,NAND_CMD_RESET,-1,-1);

?????? /* Send the command for reading device ID*/

?????? chip->cmdfunc(mtd,NAND_CMD_READID,0x00,-1);

?????? /* Read manufacturer and device IDs */

?????? *maf_id = chip->read_byte(mtd);

?????? dev_id = chip->read_byte(mtd);

?????? /*下面这行是我后来加上的,目的就是看看读取的ID号到底是多少。*/

?????? printf("In %s,*maf_id is 0x%x,dev_idis 0x%x.n",__func__,*maf_id,dev_id);

重新编译并下载之后看到如下打印信息:

NAND:In nand_get_flash_type,*maf_id is 0x95,dev_id is 0x95.

No NAND device found!!!

0 MiB

?? ?依然是找不到Nand。不过从这句话我们可以看出,读取Nand的厂商号和设备号出了问题。实际上的厂商号是0xEC,设备号是0xDA。

?? 于是定位到读取ID代码上,搜索chip->read_byte函数的赋值语句发现是在本文件中的nand_read_byte函数,再起里面加上打印语句:

?????? static uint8_t nand_read_byte(structmtd_info *mtd)

?????? {

?????? ??????struct nand_chip *chip = mtd->priv;

?????? ???????printf("Innand_read_byte,chip->IO_ADDR_R is %pn",chip->IO_ADDR_R);

?????? ???????return readb(chip->IO_ADDR_R);

?????? }

接着搜索发送命令/地址的函数,chip->cmdfunc,发现该函数调用了chip->cmd_ctrl函数,而这个函数正好是自己在nand_flash函数中实现的函数,也加上打印语句:

25static void s3c2440_hwcontrol(struct mtd_info *mtd,int cmd,unsigned int ctrl)

26 {

?????????? ……

56???????? printf("Ins3c2440_hwcontrol.ctrl is 0x%x,cmd is 0x%xn",ctrl,cmd);

57???????? if (cmd != NAND_CMD_NONE)

58???????????????? writeb(cmd,chip->IO_ADDR_W);

59 }

上述函数是在board_nand_init函数中赋值的,在这个函数也加上打印信息。另外,在函数s3c2440_dev_ready中也增加打印信息,判断一下读取硬件是否出现问题,为此修改如下:

61static int s3c2440_dev_ready(struct mtd_info *mtd)

62 {

63???????? struct s3c2440_nand *nand =s3c2440_get_base_nand();

64???????? unsigned int ready=0;

65???????? ready = readl(&nand->NFSTAT)& 0x01;

66???????? printf("Ins3c2440_dev_ready,dev is %s ready.n",ready?"":"not");

67???????? return ready;

68 }

重新编译并下载之后看到的信息如下图所示:

可以看到,虽然基本断定函数调用没有问题,但是厂商号和设备号依然是0x95,依旧找不到NAND!!!因此,肯定的说,是Nand的发送命令和地址的地方出现了错误。该功能的实现在nand->cmd_ctrl函数中,回去仔细研究,发现问题就是出在这里:

49???????????????? if (ctrl & NAND_NCE)

50????????????????????????writel(readl(&nand->NFCONF)& ~S3C2440_NFCONT_nCE,

51??????????????????????????????? &nand->NFCONF);

52???????????????? else

53????????????????????????writel(readl(&nand->NFCONF)| S3C2440_NFCONT_nCE,

54???????????????????????? ???????&nand->NFCONF);

?? S3C2410和S3C2440的寄存器是不相同的,原先的S3C2410使用的是NFCONF寄存器,而S3C2440使用的是NFCONT寄存器,修改成NFCONT,重新编译下载,成功!!

(编辑:李大同)

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

    推荐文章
      热点阅读