接着上一篇文章写的内容(上一篇文章链接:移植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语言,数据结构等技术问题!