![]() |
|
||||||||||||||||||
| . 网站首页 . 新品 . 新闻 . 方案 . 文库 . TI应用 . TI资源 . FPGA应用 . FPGA资源 . 移动技术 . 爱科技 . 厂商 . 代码 . 下载 . 产品 . 商城 . 邮购须知 . | ||
|
||
|
|||||
| uboot环境变量不能保存的调试 | |||||
作者:IamGooda… 文章来源:IamGooday 点击数: 更新时间:2012-1-2 ![]() |
|||||
|
在我的板子上设计了2个uboot,分为大小u-boot。小u用于启动,因为程序小,所以速度快,而且适合放在单个块(128K)中.大u包含网络,功能全面。 在实际的启动过程中,小u出现不能保存环境变量的问题,本文用于记述我的调试过程。 出现该问题首先想到的是修改配置文件,把所有更flash env相关的配置宏全部找了一遍,并且做了各种各样的组合尝试。以失败告终。 接下来只好深入代码去查找原因,发现出错是因为 Attempt to write not page aligned data 查看语句得知,这个主要是 进一步的跟踪变得异常困难,主要的问题在于:当我想通过printk函数打印一些输出时,可执行程序经常启动不起来。尤其是在出错语句附近,每次加printk语句都会导致系统启动失败(启动到printk时打印不出东西,然后还挂死在该语句上)。百思不得其解,直至现在尚未搞清。 于是想到用仿真器调试。BDI仿真器可以单步执行语句,同时也可以配合GDB(DDD)进行调试,具体方法建另一篇文章。但是悲哀的发现,没有办法直接通过BDI加载代码,因为要想通过BDI加载的前提就是BDI先要初始化DRAM,使得程序可以先放在RAM中。对我目前所用芯片(DM8148)的初始化会涉及不少寄存器,但我查遍身边的资料,都没有发现这些寄存器定义,况且,调试这个部分也挺费时间。 那么不用仿真器加载,只是用仿真器控制或者查看,是否可以呢。答案是可以的。我们可以连上仿真器,同时通过flash正常启动,这个时候分别有2个过程同时进行。1)板子通过Nand flash正常启动,程序被加载到RAM后执行。2)仿真器在检测到开电后通过JTAG通信得知有ARM开始工作,然后hold住正在执行的程序。 在实际的实验中,当仿真器hold住程序时,u-boot程序往往已经运行了大部分,所有的初始化过程都已经完成了。因此无法通过程序单步来观察整个初始化过程的变化,也许可以通过设置仿真器来改进JTAG通信的速度,使得仿真器能更快的hold住程序,但是多次尝试后发现很难,毕竟JTAG通信过快反过来会带来JTAG的连接失败。 于是想到通过仿真器重置PC指针,使得u-boot再次重新执行,并在执行前在关键代码处设置断点,实验发现2个地方与预想的不一致,1)再次执行的程序与第一次执行的输出不一致,有一些明显的错误输出的log。2)我确实可以用仿真器使得在相应的位置停下来。但是当我用ddd真正执行单步时,发现指针乱飞,完全不是想想的那样,于是只好作罢。 放弃仿真器后,同事提了一个很好的建议,不用print语句,那可以往一段固定地址的buffer输出东西,然后还是用仿真器,通过查看对应的地址就能获知实际设置的值了。按照这个思路,在查询u-boot.map后找了一个肯定不用的地方,然后往里面直接写数据,就像这样: *(unsigned int *)(0x80200000) = reg_value; 编译运行时发现,还是和printk一样的问题,程序hang,无法输出任何东西。 没有足够的log支持,只能仔细阅读源代码,试图找到是否是某些指针赋值之类的问题,最后把nand初始化的部分倒是理解透彻了。趁此回忆一下: NAND的初始化源于drivers/mtd/nand/nand.c,这个文件 nand_init(void) --> nand_init_chip(nand_info[i], &nand_chip[i], base_address[i]) --> board_nand_init(nand) -> nand_scan -> add_mtd_device -->[ti81xx_nand.c]nand setting nand_scan -->[nand_base.c] nand_scan_ident() -> nand_scan_tail() 硬件检测Nand 设置mtd和chip的参数,包括本文所讲的pagesize等 最后在u-boot的一个讨论中发现,printk不是标准的u-boot log输出语句,用printf反过来更标准一些,于是尝试用printf来打印一些log,果然,出现程序hang的概率大幅减小。最后发现,在赋值语句3048的前后加打印语句,会出现十分奇特的现象。 3047 printf(A) 3048 chip->subpagesize = mtd->writesize >> mtd->subpage_sft; 3049 printf(B) 小u在启动时只出现了B,A始终没有出现。大u启动时一切正常,A,B依次出现。 以上所有的怀疑最后都集中到了一点,程序发生错乱极有可能是因为优化过度。理论上来说这里的语句不应该会被优化掉,因为在赋值语句的后面马上就出现了引用。尝试实验,将对应的chip指针改成volatile类型,一些正常。 其实上述过程的很多地方已经可以想象到是因为程序优化问题了。但是我没有往那方面想,于是,始终得不到正确答案。 |
|||||
| 欢迎点击进入:TI德州中文网 (国内唯一针对TI应用的中文技术网站) 文章录入:admin 责任编辑:admin | |||||
| 【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 | |||||
| 最新热点 | 最新推荐 | 相关文章 | ||
| IAR + Proteus7.6仿真MSP430… |
| 网友评论:(只显示最新10条。评论内容只代表网友观点,与本站立场无关!) |
| | 设为首页 | 加入收藏 | 联系站长 | 友情链接 | 版权申明 | 网站公告 | 管理登录 | | |||
|
|