调试U-Boot笔记(六)

简介:
   昨天我们查看了Flash写入失败的相关代码。我在怀疑自己是不是在配置的时候选错了芯片型号。从电路原理图上看,我们的NorFlash芯片型号是:AM29LV160DB/SST39VF1601。
    经过一番查找,终于搞明白了。
 
    在 u-boot/board/ 目录下有很多个文件夹。每一个文件夹以板子的型号命令,比如smdk2400,smdk2410,my2440等。在每一个文件夹下都有该板子单独的设备 驱动文件。在my2440这个文件夹下就有一个flash.c文件。这个文件里定义了NorFlash驱动函数。
   
   
    既然我们找到了这个文件,那么我们就用AXD单步进行调试一下。
 
    单步执行 > protect off all 时,运行到do_protect()函数。我发现在
   
    红框所地的代码并没有执行。我查看了一下 include/configs/my2440.h文件,没有搜到CFG_FLASH_PROTECTION 宏的定义。不知道这会对烧写U-Boot到NorFlash有无影响。
 
    我还遇到一个问题,为什么在AXD里调试U-Boot,看不到变量里的值。我记得用ADS编写代码再用AXD调试时都可以看到的嘛。如何解决?

    在board/my2440/flash.c文件中搜索宏 ERR_PROG_ERROR.
    可以搜到两处使用了ERR_PROG_ERROR宏:
  •     volatile static int write_hword (flash_info_t * info, ulong dest, ushort data)
  •     int flash_erase (flash_info_t * info, int s_first, int s_last)
    其中write_hword()应该是在命令 “cp.b 0x30000000 0 40000”时出错的主要原因。看代码如下: 

volatile static int write_hword (flash_info_t * info, ulong dest, ushort data)
    {
        vu_short *addr = (vu_short *) dest;
        ushort result;
        int rc = ERR_OK;
        int cflag, iflag;
        int chip;
        /*
         * Check if Flash is (sufficiently) erased
         */
        result = *addr;
        if ((result & data) != data)
            return ERR_NOT_ERASED;
        /*
         * Disable interrupts which might cause a timeout
         * here. Remember that our exception vectors are
         * at address 0 in the flash, and we don't want a
         * (ticker) exception to happen while the flash
         * chip is in programming mode.
         */
        cflag = icache_status ();
        icache_disable ();
        iflag = disable_interrupts ();
        MEM_FLASH_ADDR1 = CMD_UNLOCK1;
        MEM_FLASH_ADDR2 = CMD_UNLOCK2;
        MEM_FLASH_ADDR1 = CMD_UNLOCK_BYPASS;
        *addr = CMD_PROGRAM;
        *addr = data;
        /* arm simple, non interrupt dependent timer */
        reset_timer_masked ();
        /* wait until flash is ready */
        chip = 0;
        do {
            result = *addr;
            /* check timeout */
            if (get_timer_masked () > CFG_FLASH_ERASE_TOUT) {
                chip = ERR | TMO;
                break;
            }
            if (!chip && ((result & 0x80) == (data & 0x80)))
                chip = READY;
            if (!chip && ((result & 0xFFFF) & BIT_PROGRAM_ERROR)) {
                result = *addr;
                if ((result & 0x80) == (data & 0x80))
                    chip = READY;
                else
                    chip = ERR;
            }
        } while (!chip);
        *addr = CMD_READ_ARRAY;
        if (chip == ERR || *addr != data)
            rc = ERR_PROG_ERROR;
        if (iflag)
            enable_interrupts ();
        if (cflag)
            icache_enable ();
        return rc;
    }

    见L63~64可知,只有chip的值为ERR或则从addr地址上读出来的数据不等于data就会返回ERR_PROG_ERROR错误。
    ERR只在代码的44,56两处出现。但如果执行了44行的代那,那么chip的值应该是ERR|TMO=0x03,不等于ERR。那么只有在56行这个有可能。分析一下50~57行代码的功能:
    在40行 result = *addr,从addr地址上读取一个数据。在50行处检查result的第5位 ( (result & 0xFFFF ) & BIT_PROGRAM_ERROR),如果为1则表示写错误。然后在51行再读取一次,再进行一次检查。如果数据正常却将chip置为READY,否则置为ERR。
 
    为了找到倒底是哪里出错,在将在这里加调试信息。
   
   
    编译后生成u-boot.bin文件,然后复制到e:u-boot-gdbu-boot.bin。再进行调试。
    在终端看到如上:
   
    可见,得到失败的原因了,是359行处 (*addr != data) 条件不成立。不过有一点问题,如果*addr读出的值与读的次数有关就可能不太确定了。还是再小改一下:
   
   
    结果再次执行,显示结果:
   
    看来,还真是读出来的值不一致引起的。这个该怎么办呢? 

目录
相关文章
|
人工智能 自然语言处理 异构计算
微软开源SliceGPT介绍
【2月更文挑战第13天】微软开源SliceGPT介绍
248 6
微软开源SliceGPT介绍
|
存储 监控 安全
推荐5款极具效率的实用工具软件
每次分享实用的软件,都会给人一种踏实和喜悦的感觉,这也是我热衷于搜集和推荐高效工具软件的原因。
344 1
|
机器人 API
钉钉里{"code: 400, 错误描述:机器人权限校验不通过;解决方案:请登陆开放平台后台,检查机器人是否归属于token对应的主应用名下 请问场景机器人-发消息-这个报错什么原因导致的啊?
钉钉里{"code: 400, 错误描述:机器人权限校验不通过;解决方案:请登陆开放平台后台,检查机器人是否归属于token对应的主应用名下 请问场景机器人-发消息-这个报错什么原因导致的啊?
836 0
|
8月前
|
机器学习/深度学习 人工智能 安全
企业AI采用:董事会成员的视角与策略
企业AI采用:董事会成员的视角与策略
|
8月前
|
缓存 NoSQL Redis
Redis原理—3.复制、哨兵和集群
详细介绍了Redis的复制原理、哨兵原理和集群原理。
|
8月前
|
人工智能 缓存 自然语言处理
自建 DeepSeek 时代已来,联网搜索如何高效实现
自建 DeepSeek 时代已来,联网搜索如何高效实现
|
10月前
|
弹性计算 运维 监控
评测报告:阿里云服务诊断工具
评测报告:阿里云服务诊断工具
235 32
|
负载均衡 Cloud Native 中间件
KubeSphere实战
KubeSphere实战
167 0
|
11月前
|
网络协议 安全 算法
OSPFv3新特性介绍
OSPFv3新特性介绍
202 4
|
机器学习/深度学习 人工智能 自然语言处理
什么是AIGC(人工智能生成内容)
AIGC是一种新的人工智能技术,它的全称是Artificial Intelligence Generative Content,即人工智能生成内容。它是一种基于机器学习和自然语言处理的技术,能够自动产生文本、图像、音频等多种类型的内容。这些内容可以是新闻文章、小说、图片、音乐,甚至可以是软件代码。AIGC系统通过分析大量的数据和文本,学会了模仿人类的创造力,生成高质量的内容。AIGC涵盖了从简单的自动化文本生成到复杂的视觉艺术创作等广泛的应用。
728 4