我的引导程序把我的程序放在 0x00000000,(这个地方是Flash) 在初始化的时候,我把代码区的所有代码copy到SDRAM里面去。然后跳到SDRAM( 0xc0000000 )里面去运行。此时我能否往 0x00000000及其后的address里面写数据?
应该这样说,flash由于本身的技术原因,擦写过程中不能同时读。所以,你不能在运行(读代码)的同时去改写同一个flash芯片中的内容。但你说的跳到sdram中去运行并改写flash应该是可以的。
还有,flash的写操作不同于ram,是需要通过一系列的特定操作才完成的。这个你可以仔细看看flash芯片的手册,不同的芯片可能会有区别。blob中可以找到具体的程序例子参考。
我就是要擦除Flash. 然后写Flash. 我现在是把代码全部copy到SDRAM里面去。然后跳到SDRAM里面去运行。我现在也已经这样做了。 但是我在SDRAM里面运行,而且要写Flash(包括读ID ) 的时候。系统运行就乱了。 可能产生了异常。我不知道这个怎么解决?
如果你确认程序能够正确进入sdram运行了,最可能出问题的就是这段程序中的跳转语句。你的跳转是相对跳转还是绝对跳转?如果是绝对跳转,编译的时候编译器不会知道你以后会把程序挪地方,跳转的目的地址还是在flash中。这样就出错了
跳转到SRAM里面后,如果不操作Flash. 到目前为止,好像没有什么问题。都能正常运行。 但是只要操作Flash,就会死!
机器级b和bl指令有一个限制:跳转的范围在当前指令的+/-32Mb范围内。为什么?因为跳转的目的地是以当前的指令为起点的。这就是相对(于当前地址)的跳转。绝对跳转就是直接指定目的地址的跳转,比如你直接给pc赋一个立即数值,就是绝对跳转。你也可以用bx/blx Rm来实现绝对跳转。
在打开mmu之前,把00000000物理地址映射到另外一个地址例如e0000000,然后打开mmu,对e0000000操作,就是对flash操作
如果发生中断,那么cpu会去中断向量表中访问相应的中断向量并执行,而此时你的Flash处于写状态
只要写Flash. 程序就不知道跑到什么地方去了。 我用的是Sharp的Flash. 读厂家的ID 命令是 0x90. 写这个命令时,就发生错误了。表现为程序没有继续运行下去。因为Flash位于0x0000000。
她的看法跟我一样,你很可能有绝对跳转的指令,使得你的程序运行到中途又跳回到flash中去了。
中途跳转到Flash中去了??? 但是如果我把读Flash ID这段代码注释掉. 程序运行很正常阿!? 看看我这段代码:
在读flash前,我做了LCD的初始化和相关的测试。 另外我可以直接读flash中的数据(包括程序代码等等)。
这样一句语句不管你把它拷贝到哪里,他都一定会执行到0x300这个地址去的.如果你的程序中有这样的跳转,因为编译的时候编译器不知道你会把它拷贝到别的地方,必然填充的是当前程序段内的地址.而这个地址不会随着你的代码的搬移而改变.那么执行到这一句的时候就又跳回去了.
我的Check_flash本来就是用C写的。 因为我只是想简单测试一下在我把ROM CODE搬到SRAM区后,能否操作Flash.
我想在编译连接阶段不会把具体的段地此也放在最后的代码中。它总是在运行的时候把所在段的地址和它相加就是了。如果真的像你所说,那么我前面的代码(在操作Flash之前)一定不能运行。但是实际情况正像我所料。我的LCD能工作。我的蜂鸣器能响。我的LED能闪烁。
如果不能,一定是你的程序出了问题.最常见的就是真正的自己写自己.因为编程时,flash的状态不是普通的读状态,所以处理器读不到程序代码,当然就出错了.
你说过,你是在没有操作系统的裸机上运行的,那么你的代码一定不是一个可执行程序,而是真正的机器代码段.除了程序自己,没有人会帮他设置什么运行时的段地址的.
你的意思是怀疑我的程序是否真的在SRAM里面运行? 还是怀疑我的Check_Flash有问题?
1)。 在Flash里面运行程序和在SRAM运行程序的速度是有很大差别的。 可以从运行的情况可以看出来。这点基本可以确定程序真的在SRAM运行。(否则也无法逾越这条指令:
如果你的LCD显示是正常的.你试试在这段程序开头的地方把PC的值显示出来,看看是不是在flash中运行.
我不知道你的编译器,不过象gcc的,c的函数名通常在汇编中看到的是加前缀_的c函数名. 象Move_Program的c函数,在汇编中是看不到的。在gcc中是在Move_Program前加asmlinkage。
在这个语句*addr = 0x00900090 之前, PC都正常。显示结果为SRAM里面的地址(0x60000278), 但是如果一执行这个语句之后,PC 无法显示出来了(就是我调用了显示函数,但没有显示)。但是好像又能跑!因为LED在闪烁。(注意在这条语句之后,我加了LED 闪烁功能,以证明程序在跑 ) 很奇怪。
你不是有指示灯吗,在显示函数的入口处加入PC的检查代码,看看PC是在什么范围,比如,在sram就熄灭指示灯,在flash中就点亮指示灯。
原来是那些全局变量(字库)的地址还没有变。怪不得,在我写0x00000000之前,程序仍然访问的是Flash里面的ROM DATA. 然后在写0x00000000后, 此时Flash的读写状态发生变化,可是程序仍然要访问Flash里面的ROM DATA. 这个时候问题就出来了。因为这个时候Flash可能无法正确读出ROM DATA. 所以LCD Driver无法正确拿到字库,因此无法正确显示。因此可能作如下修改就可以拉:
可以用PIC,也就是动态连接库使用的技术,我记得ppcboot用这种方法实现从Flash搬到RAM后,只要作简单的修补(Fixup),就可以在RAM中执行。
2.改写ld的参数(一般在makefile中,或者有一个单独的ldscript),把代码的起始地址改成你将要把它复制过去的那个sram中的地址。

