TQ2440下keil测试程序
主要内容: 一楼: 一. 简单原理介绍 二楼: 一. 复制代码, 建立并配置工程 二. 修改部分代码 三. 测试结果 (看不到图片的可以下载4楼的word文档, 移植成功的程序代码在6楼) 前段时间发了这个教程: http://www.armbbs.net/forum.php?mod=viewthread&tid=10423 把标题定为教程实在是我自夸了点, 其实应该算是我学习的总结吧, 写份文档, 自己以后忘了也有个参考, 又可以帮助和我卡在同一个问题的新手, 其实我也是新手, 新手教新手, 不知道会不会误导大家了... 一. 简单原理介绍 那个教程里面主要讲了一些简单的配置, 原理没有仔细介绍, 其实当时我也不太懂, 当时看重的是实际效果, 原理嘛, 在我们从SB到NB的过程会慢慢理解的, 现在稍微理解了一点, 在写这篇教程之前简单介绍一下之前的存储器的地址配置的问题吧, 也和等会移植的内容有关啦, 耐心看吧: TQ2440开发板算起来应该是有3个片外存储器吧, 一个是 nand flash, 一个是 nor flash, (这两个应该算是ROM了), 还有一个SDRAM (就是RAM啦, SDRAM是个 什么东西, 还没学数电...不知道...) 首先,2440的程序代码是可以存放在SDRAM里面运行的.从汇编上讲, 就是程序指针(PC指针, 程序计数器, 各种称呼, 指向一下条要执行的程序代码 的一个寄存器)可以指到SDRAM的内存单元. 然后再说nor flash, 2440的程序也可以在nor flash里执行, 原因我不清楚. 从nor flash启动的时候, PC指向的0地址就是nor flash的首地址, 就是说nor flash 的首地址映射到内存的0地址, 对比一下SDRAM, SDRAM在2440是映射到0x3000 0000 地址 然后是nand flash, nand flash 也是映射到了 0地址, 为样就和nor flash有冲突了, 所以就有了从nor 启动和从nand启动的区别了, 然后我又想说, 其实nand本身是不能运行程序的(这里的意思是说, 因为nor flash本身为了容量大和本身的接口, 是不能向CPU不断的快速的输送指令的, 我的理解就是这样, 大家可以去参考nor 和 nand 的区别的资料), 既然我说nand不能运行程序, 那个地址映射有什么意义? 是这样的, 2440从nand启动的时候, 它内部的nand flash控制器会把前4k的代码复制到内部的缓存去执行, 而这些缓存就是对应地址的0单元开始. (其实这个直接去参考2440 datasheet 上的地址映射会比看我在这里瞎说的强...) 刚才说了从nand启动的时候是把前4k的代码复制到内部的缓存去执行的, nand flash的容量远远远远大于4K呀, 不充分利用就太浪费了...如果你的程序超过4K了怎么办? 很简单, 你在前4K的程序里, 利用什么for啊while之类的把剩下的代码复制到SDRAM里面去, 复制完了以后后再用一条汇编指令 ldr (用来跳转到绝对地址的, 类似C语言的goto, 但有点区别) 跳到SDRAM里面继续执行, (因为前4K的代码在内部缓存运行的时候对应的地址是从0-4K的, SDRAM是的地址是从0x30000000开始的, 你不跳, 就等着系统崩溃吧). 刚才说的这些工作你可以自己写代码, 也可以移植个boot loader来帮你做, 操作系统就是从boot loader开始的...这部分我没学, 不说了... 那么ldr指令是怎么跳转的? 在2440init.s里有这两句, ldr pc, =copy_proc_beg copy_proc_beg 类似C语言的 goto copy_proc_beg copy_proc_beg: 注意, 我说的是类似, 从汇编层面是讲, 是有很大的不同的, 我比较懒, 就不详细解释了 上面的ldr 的作用就是: 你的工程最后生成可执行的代码里面, copy_proc_beg 对应的地址(绝对地址, 就是说应该放在存储器的哪个位置), 会被复制到PC指针, 所以我们在nand启动的工程配置里, rom应该是这样的: srart(开始): 0x30000000 size(大小, 我这里是随便设置的): 0x800000 抱歉, 我之前的教程里的生成下载到nand的bin文件的那部分配置讲错了, 当时并不理解, 不过, 小于4K的程序还是可以用的了^_^ //////////////////////////////////////////////////////////////// 补充: 其实教程1那里的只有把ROM配置成从0x0开始才是可以正常运行的, 原因是用了KEIL给的启动代码, 有一句是这样的 IMPORT __main ; 相当于extern void main() LDR R0, =__main ; 跳到main函数的绝对地址去执行 如果rom 设置 0x3000 0000 开始的话, 教程1的代码里又没有进行搬移的工作, 跳到SDRAM里去, 没有代码, 程序就不能正常运行了 //////////////////////////////////////////////////////////////// 这样, 编译器生成以后, 标号copy_proc_beg对应的地址是0x3*******, 也就是在SDRAM里面, 然后你在运行前4k的程序的时候PC指针的内容是0x00000***, 完成之前说的代码从nand flash到SDRAM的搬移工作后, 用一条 ldr pc, =copy_proc_beg 指令, 把PC指针的内容改成0x3*******, 就跳转到SDRAM里面运行了 基本的原理讲到这里, 洗澡去, 等会再进入正题...顺便想一下有没有需要补充的... //////////////////////////////////////////////////////////////// 补充: 用JLINK在SDRAM调试的时候, ROM配置也是 srart(开始): 0x30000000 size(大小, 我这里是随便设置的): 0x800000 然后你按下调试键的时候, 代码由J-LINK帮你复制到SDRAM了, 然后再把PC指到0X30000000开始执行, 这J-LINK的这些工作是由一个初始化文件(教程1里配置的时候从keil的安装目录那边复制过来的文件)指导完成的. 如果你在调试的时候按了这个键 就把单片机给复位了, 然后PC指针指向的地址就是0, 如果你再点运行, 除非你的nand flash 或 nor flash里面有程序, 要不然是不会正常运行的, 即使有程序, 也不能正常调试, 你要把PC指针改回0x30000000才可以让2440继续跑你要调试的程序, (双击PC又边的数字 0x00000000就可以改他的值了) 关于nor flash的设置, 没什么好讲的了, 从0开始执行, 嗯, 就这样了 //////////////////////////////////////////////////////////////// 更正:经29楼网友指出,原文的这一段是错误的,ARM9是哈佛结构的,已经删了 “2440算是冯诺什么曼结构的计算机, 通俗的说, 2440的程序代码是可以放在RAM里面执行(我们的PC机也是这种类型的), 不同于51, 也许你会注意到, 51的程序是不能在内部的RAM里面执行的, 现在的51单片机的程序一般是存在片内的ROM里的, 传统的51的内部RAM顶多也就那么256个字节, 变量都存不了几个, 运行个鬼程序, 51单片机算是哈佛结构的.”
用户评论
Dabort exception!!! 自己找找问题吧
楼主的分享不错,主要是指明了Keil下的思路,多谢!
中断部分有问题,请改下,依旧感谢
中断确实不能用,得改进。
确实不能中断处理,也不能设置断点,学学自己怎么改进吧
是一个比较好的程序,但是在RAM里面模拟的时候出现了问题,不能中断处理,需要改善。