调试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读出的值与读的次数有关就可能不太确定了。还是再小改一下:

   

   

    结果再次执行,显示结果:

   

    看来,还真是读出来的值不一致引起的。这个该怎么办呢? 

时间: 2024-10-22 04:24:25

调试U-Boot笔记(六)的相关文章

kvm虚拟化学习笔记(六)之kvm虚拟机控制台登录配置

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://koumm.blog.51cto.com/703525/1290996 KVM虚拟化学习笔记系列文章列表 ---------------------------------------- kvm虚拟化学习笔记(一)之kvm虚拟化环境安装http://koumm.blog.51cto.com/703525/1288795 kvm虚拟化学习笔记(二)之linux kvm虚拟机安装 h

PHP微信公众开发笔记(六)

PHP微信公众开发笔记系列 日期:2014.9.4 今天主要是完善了搜索,加入了管理员模块,优化了身份验证,将学生信息管理封装为了一个类(整这个真是好累呀,主要是数据库操作那里语法老是出问题,一直是各种小问题) 感受: PHP开发没有断点.不能及时打印log真是好累呀(我是用sublime写的,然后直接微信公众号调试,累屎我了),错误信息经常不能及时发觉.或者说有些问题能通过断点排除掉了没能够排除.但是也说明了,我写代码还是太马虎了啊. 2014.9.10整理笔记: 写这个笔记的时候,在赶功能,

JSP学习笔记(六)-----在多个JSP页面之间传递参数

js|笔记|页面 1. 怎么在多个JSP页面之间进行参数传递?需要使用JSP的内置作用域对象session.利用它的两个方法setAttribute(),getAttribute()2. 下面的这个实例实现了把第一个JSP页面的参数传递给第三个页面的功能3. 代码如下:1.jsp<html><form method=get action=2.jsp>what's your name<input type=text name=username><input type

Nginx学习笔记六Nginx的模块开发

1.Nginx配置文件主要组成:main(全局配置)这部分的指令将影响其他所有部分.server(虚拟主机配置)这部分指令主要用于指定虚拟主机域名,IP和端口.upstream(主要为反向代理,负载均衡相关配置)这部分指令用于设置反向代理及后端服务 器的负载均衡.location(目录匹配配置)这部分指令用于匹配网页位置(例如,根目录"/","/images",等 等). location部分会继承server部分的指令,而server部分会继承main部分的指令.

python网络编程学习笔记(六):Web客户端访问_python

6.1 最简单的爬虫 网络爬虫是一个自动提取网页的程序,它为搜索引擎从万维网上下载网页,是搜索引擎的重要组成.python的urllib\urllib2等模块很容易实现这一功能,下面的例子实现的是对baidu首页的下载.具体代码如下: 复制代码 代码如下: import urllib2page=urllib2.urlopen("http://www.baidu.com")print page.read() 6.2 提交表单数据 (1)用GET方法提交数据提交表单的GET方法是把表单数据

zfdebug调试zend framework笔记

一.zfdbug简介:   zend framework项目开发过程中,测试是无处不在的,但zend framework测试非常麻烦.因此就有老外写了一个zf的debug插件,功能非常全面(文件,内存,数据,缓存,变量,运行时间,异常),它能展示我们平时看不到的系统信息对我们快速定位问题,提高系统的性能,安全性等都有很大的帮助. 有了zfdebug,以后使用zend framework开发项目,调试再无烦恼. 二.zfdebug的官方地址: http://code.google.com/p/zf

设计模式学习笔记(六)—Decorator装饰模式

<设计模式>一书对Decorator是这样描述的: 动态地给一个对象添加一些额外的职责.就增加功能来说,Decorator模式比生成子类更为灵活. 也就是说:动态地给对象添加一些额外的功能.它的工作原理是:创建一个始于Decorator对象(负责新功能的对象)终止于原对象的一个对象的"链".例如,我们要为超市的收银台设计一个打印票据的程序,有的需要打印票据的头信息,有的需要打印票据的页脚信息,有的只需要打印票据的内容.如果针对每一种情况都修改一次程序,势必会很麻烦.这时我们

Unmi的Struts2学习笔记(六)

米洗毕,水适量,盖合上,心摇摆,总觉水多了一分或是少了几点,于是重又 加上或倒出少许,其实这丁点份量完全无碍煮出香喷喷的饭来.及至将熟之际, 亦有犹豫,心中默数至少10,如再有不定辄至20,掐火,20对最终质量来说或有 所损. 1. Struts2 的 Action 中可直接用属性来封装请求参数和处理结果,此谓之 属性驱动.也可以像 Struts1 那样使用专门的 ActionForm 来处理请求参数和结 果,只不过 Struts2 用的是一个更单纯的 POJO,这就做模型驱动:此时的 Acti

Windows SDK笔记(六):使用对话框资源建立窗口

Ⅰ.使用对话框资源建立主窗口 一.概述 在Charles Petzold的书中,介绍了一种直接利用对话框资源建立主窗口的方法. 使用这种方法,可以方便的在主窗口中安排子控件,而代码的其他部分跟用普通窗口时一样. 我们知道,对话框是系统预先定义的"窗口类",它有自己的窗口处理函数,我们自己写的对话框消息处理函数并不是真正的窗口消息处理函数. 但我们可以在对话框模板脚本中,指定这个对话框使用我们自己定义的窗口类,而不是系统的对话框类,这样,就将对话框的消息处理函数"嫁接"

hibernate3学习笔记(六) Session管理

请注意,在hibernate中SessionFactory是被设计成线程安全(Thread-safe)的,遗憾的是,Session却线程不安全. 这就意味着:有可能多个线程共享并操作同一个Session从而很容易使数据混乱. 解决的办法如下:(其实hibernate的文档中早已经提过了) 新建HibernateUtil类: 1.import org.apache.commons.logging.Log;2.import org.apache.commons.logging.LogFactory;