接着上一篇文章写的内容(上一篇文章链接:移植uboot之修改代码支持NORFLASH),上一篇结尾测试flash的擦除读写功能,结果无法写flash,卡在了这里:
前面已经擦除成功,这里写内容写不进去,显示没有擦除成功。一开始怀疑是不是硬件问题,后来用好的uboot试了一下,是可以实现写功能的,所以排除了硬件的问题。软件有问题?看一下代码关于擦除读写的内容吧,根据串口打印的消息搜索字符串信息:Copy to Flash… 以及Flash not Erased信息。
通过搜索相关字符串消息,搜索到Cfi_flash.c中有函数:write_buff这个函数,这个函数里面有
rc = flash_write_cfiword (info, wp, cword); if (rc != 0)
return rc;
.......if ((rc = flash_write_cfibuffer (info, wp, src, i)) != ERR_OK)return rc;
.......if ((rc = flash_write_cfiword (info, wp, cword)) != 0)
return rc;
......if ((rc = flash_write_cfiword (info, wp, cword)) != 0)return rc;
......return flash_write_cfiword (info, wp, cword);
通过将上面几个判断语句屏蔽掉,然后重新编译,测试,发现可以写flash了,那么接下来就该看是哪个判断语句执行了导致无法写flash的。
通过逐个将上面结合判断语句屏蔽,最后发现是执行了这些:
while (cnt >= info->portwidth) {cword.l = 0;for (i = 0; i < info->portwidth; i++) {flash_add_byte (info, &cword, *src++);}if ((rc = flash_write_cfiword (info, wp, cword)) != 0)return rc; //lyy
才导致的无法写flash,心累啊,调试过程漫长啊,烧写编译烧写编译烧写。。。。。不过找到了问题所在,我很开心!!!
由上面代码知结构体数据info->portwidth这一项出了问题,也就是flash的端口宽度有问题。跳转到函数:flash_write_cfiword:
/*-----------------------------------------------------------------------*/
static int flash_write_cfiword (flash_info_t * info, ulong dest,cfiword_t cword)
{void *dstaddr = (void *)dest;int flag;flash_sect_t sect = 0;char sect_found = 0;/* Check if Flash is (sufficiently) erased */switch (info->portwidth) {case FLASH_CFI_8BIT:flag = ((flash_read8(dstaddr) & cword.c) == cword.c);break;case FLASH_CFI_16BIT:flag = ((flash_read16(dstaddr) & cword.w) == cword.w);break;case FLASH_CFI_32BIT:flag = ((flash_read32(dstaddr) & cword.l) == cword.l);break;case FLASH_CFI_64BIT:flag = ((flash_read64(dstaddr) & cword.ll) == cword.ll);break;default:flag = 0;break;}if (!flag)return ERR_NOT_ERASED;...........................
...........................
...........................//省略号代表后面还有其他代码
我将上面的判断语句屏蔽掉,重新烧写启动,果然,可以正常写FLASH。看来问题就是出在上面的switch (info->portwidth)结构中,端口宽度的问题!!!!
现在想想应该是哪里错了呢?
1.排除硬件问题,因为我烧写uboot都是通过旧的uboot烧写新的uboot,中间存在擦除与写flash操作
2.这之前修改代码涉及到flash端口宽度的操作的有哪些?看来是当初加这个结构体时有问题:
/* jz2440使用的是MX29LV160DB芯片 */{.mfr_id = (u16)MX_MANUFACT, /*厂家ID*/.dev_id = 0x2249, /*设备ID*/.name = "MXIC MX29LV160DB",.uaddr = { /*NOR FLASH看到的解锁地址*/[0] = MTD_UADDR_0x0555_0x02AA /* x16 */},.DevSize = SIZE_2MiB, /* 总大小 */.CmdSet = P_ID_AMD_STD,.NumEraseRegions= 4, /* 擦除区域的数目 */.regions = { ERASEINFO(16*1024, 1),ERASEINFO(8*1024, 2),ERASEINFO(32*1024, 1),ERASEINFO(64*1024, 31),}},
看来是这句话的问题了,[0] = MTD_UADDR_0x0555_0x02AA /* x16 */,我们的16位宽,应该是1,将其改成:
[1] = MTD_UADDR_0x0555_0x02AA /* x16 */
重新编译uboot,烧写测试:
一个字:完美!!!!!
感慨一下这次的调试过程:提升了一个档次吧~(之前挺菜的)
想获得各种学习资源以及交流学习的加我:
qq:1126137994
微信:liu1126137994
可以共同交流关于嵌入式,操作系统,C++语言,C语言,数据结构等技术问题!