在搞定了nandflash bin文件的基础上,
可以做些简单的应用测试程序了,现在又几个方式烧写nandflash
1. 通过MDK自带的烧写方式
2. 通过把程序加载到SDRAM中运行,把指定的bin文件烧写进nandflash中。
3. 通过工具DNW,USB烧写
对于方式1,我加上led显示发现 Init()函数被flashOS调用了2次
,这很奇怪。打算放弃方式1,采取方式2来进行。
按照正常流程,Init()在整个操作流程中应该只调用一次就可以,现在竟然调用了两次,这难道是因为程序运行复位了???确实是程序跑飞了,但怎么还能自己复位呢?
方式2需要实现fopen等文件操作接口。
网上下载了一个2410完全开发pdf教程,说的非常好,看了后有了很多启发,也让我有了更大的信心
继续回到方式1,因为在nand编程算法中没有涉及到MPLLCON的设置,根据手册,设置MPLLCON之前(即没有使用PLL),CPU的时钟是来自于外部晶振12MHZ,所以我想在nand编程算法中嵌入
串口打印输出的代码baud = 115200bps,出现flash time out!!!这是一个问题
或者我尝试这样做:在flash编程算法中我田间MPLL的设置操作,之后看UART输出情况。
(插曲,我在SDRAM把对nand进行编程时发现nand前面很多块都是坏块,那坏块以后就不会用了吗?这不是浪费吗)
test:
还有一个问题很奇怪,我用不带校verify的nand编程算法把2410_Run_nand
的bin文件(大小为17K放到)烧写到nand中,之后竟然可以运行起来,串口中看到了打印的数据,但是要等很长时间才能打印出来,这非常奇怪,使用的
bootload中也加入了代码的搬运工作。。。原因待查
现在往其中烧录bin文件(27KB)之后,无法运行。我无意中注意到bootload中的nand_read_ll()函数只是根据地址和尺寸从nand中读取数据,并没有检查坏块的操作,这就有可能搬运到了无效的数据到SDRAM中
运行,当然程序也就无法工作了。如果程序size是低于1个blocksize的(16KB)烧录后运行是OK的,但是如果超过16KB则会出现异常问题。
解决思路:增加坏块检查。
应该这样:把nandboot单独做个project编译生成bin(务必保证小于4KB)文件,烧录到nand 0x0开始的区域,该nboot中做代码搬运,nandcopy的源地址为应用程序的load位置,目标地址为SDRAM的位置。
运行异常还有可能有个原因:可能我的主程序中有中断设置,在运行中产生了一次中断,则PC指向了默认的异常向量表(0x0/4/8/C等开始的地方)这导致程序流程就乱了。嘿嘿。所以首先要确定一下
在程序中如果发生中断的话。PC如何处理。
测试思路:在SDRAM中调试运行一个带中断的程序,触发中断后看PC的指向。就这么办!!!
(这个任务一定要在明天,及2010.01.16做一下,务必要看2410中中断一章节手册)
新任务1,在MDK下建立好VIVI针对2410的编译project。通读VIVI,下周三前完成。
新任务2,2010.01.17号开始仔细研究MMU机制,打算花一天时间,并写好记录文档。
继续跟踪2410init.s上在nand中运行情况,使用串口打印字符,可以知道程序流程,目前已经发现uart初始化OK, 在进入nandcopy函数中程序没有返回,所以问题可以定位在这个地方,
NND先检查它的nand配置也没有错误。bl nand_read_ll进入该函数前没有问题,但是没有它没有返回。我现在怀疑这个nand_read_ll函数根本就进不去,因为在link的时候,这个函数不知道被link在哪里了,
或者说被link到前4K SRAM区域之外的地方,所以用bl指令跳转到那根本不行。但即使跳转的不对,为什么会出现8次重新的开始的情况呢?继续查?
哈哈,经过查看编译后的map文件。发现nand_read_ll函数果然被定位到SRAM之外区域呢?这肯定是跳转不到的呀。。
map如下:
wait_idle 0x00001204 ARM Code 44 nandread.o(.text)
nand_read_ll 0x00001230 ARM Code 216 nandread.o(.text)
知道事发原因了,那现在开始改 link布局。
我看了一下发现在4KB以内的代码主要有(毫无疑问2410Init.o代码肯定是在里面的,因为我在sct文件中指定了它的布局)2410lib.o, led.o, nanddriver.o,这就必须要面对一下分散加载
机制的使用了。OK, let‘s go,胜利就在不远的前方。
暂且有两个思路:
思路 1,精简代码,只针对bootload工程,
这个bootload起名 dreamload(自己给自己搞笑了)
---UART
---USB(暂不加)
---NAND READ
确保其编译生成的bin文件一定要在4KB以内。
思路 2,利用好分散加载文件,程序大些,bin甚至超过blocksize也无所谓,只要main程序在bin中的load addr让dreamload中nandcopy函数知道,保证复制到SDRAM中没有问题
先按照第一种方式做:
在这之前,在巩固一下分散加载的机制,|Image$$EREGION_name$$Base|指的是某个region的执行地址;|load$$EREGION_name$$Base|指的是某个region的加载地址;
这个我理解为编译器在link过程时,把|load$$EREGION_name$$Base|和bin文件中的EREGION位置关联起来。
NND回过来看这个在网上下载的2410init.s真是垃圾,错误百出,作者也太无良了,是不是故意写错的啊?
不过也好,我可以更深入的了解事情的真相哦。继续改自己的bootload!!!
做了几个3个实验,发现问题
实验一:保证整个bin文件小于4KB,下载后运行没有问题
实验二:在上述基础上,不做nandcopy过程,在SRAM中运行也没有问题
实验三:把user_main()函数定位到超过4KB的区域外,在下载到nand中运行,发现无法运行
看来可以知道是由于block坏块引起的,因为我知道我板子上的nand从第二个块开始就好多坏块,在用MDK工具下载bin是是关注了是或否有坏块的,如果有坏块会一次找下一个块,直到找到好块为止。
所以有可能user_main函数已经被定位到nandflash很后面的区域了。
而在现在的nandboot里面读取数据时没有关注是否坏块,所以拷贝到SDRAM中的内容可能是完全错乱的,所以打算明天回来在异常向量里面加上打印语句。现在的现象是异常复位。
那我就不明白了,所谓的vivi难道在copy数据前都没有对nand的坏块进行检查吗?
这是为什么呢?
我靠在网上一搜这个问题,是很大的难题啊?涉及到坏块管理。
何时才能移植我的UC/OS + GUI啊,还有 wince 和 linux 的移植!!! 真是万事开头难
~。。~