调试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读出的值与读的次数有关就可能不太确定了。还是再小改一下:
   
   
    结果再次执行,显示结果:
   
    看来,还真是读出来的值不一致引起的。这个该怎么办呢? 

目录
相关文章
|
6月前
|
监控 IDE Java
Java项目调试实战:如何高效调试Spring Boot项目中的GET请求,并通过equalsIgnoreCase()解决大小写不一致问题
Java项目调试实战:如何高效调试Spring Boot项目中的GET请求,并通过equalsIgnoreCase()解决大小写不一致问题
98 0
|
5月前
|
小程序 Java 数据库
基于SpringBoot学生信息管理系统设计和实现(源码+LW+调试文档+讲解等)
基于SpringBoot学生信息管理系统设计和实现(源码+LW+调试文档+讲解等)
|
5月前
|
Shell 数据安全/隐私保护 开发者
详细解读ApolloGPS调试笔记
详细解读ApolloGPS调试笔记
23 0
|
6月前
|
IDE Java 开发工具
【CSDN 云IDE】中实现Spring Boot文件的上传与下载
【CSDN 云IDE】中实现Spring Boot文件的上传与下载
82 0
【CSDN 云IDE】中实现Spring Boot文件的上传与下载
|
安全 Java Spring
Spring Security 401和403错误解析及调试:从源码到调试技巧
Spring Security 401和403错误解析及调试:从源码到调试技巧
|
Java Windows Spring
惊呆了!Spring Boot 还能远程调试?
惊呆了!Spring Boot 还能远程调试?
|
消息中间件 存储 JSON
源码环境调试|学习笔记
快速学习源码环境调试
源码环境调试|学习笔记
|
Java Spring
SpringBoot自动配置源码调试
SpringBoot自动配置源码调试
536 0
|
Java Maven 开发工具
Spring Boot Debug 调试秘籍,日后必定有用!
最近发现 Spring Boot 本地不能 Debug 调试了,原来 Spring Boot 升级后,对应插件的命令参数都变了,故本文做一个升级。
290 0
Spring Boot Debug 调试秘籍,日后必定有用!
|
IDE Java PHP
使用Cloud Studio在线编写、调试和管理Spring Boot应用
使用Cloud Studio在线编写、调试和管理Spring Boot应用
596 0
使用Cloud Studio在线编写、调试和管理Spring Boot应用