您的位置 首页 传感器

ARM怎么读写Flash

1.我在ARM上裸机。不使用任何嵌入式操作系统。我的引导程序把我的程序放在0x00000000,(这个地方是Flash)在初始化的时候,我把代码区…

1.

我在ARM上裸机。 不运用任何嵌入式操作体系

我的引导程序把我的程序放在 0x00000000,(这个当地是Flash) 在初始化的时分,我把代码区的一切代码copy到SDRAM里边去。然后跳到SDRAM( 0xc0000000 )里边去运转。此刻我能否往 0x00000000及这今后的address里边写数据?

2.

不能够,在Flash 中履行的代码不能够改写Flash的内容,你能够在SDRAM中写FLASH的内容。参阅bolb和intel strongarm的dm 程序

3.

应该这样说,flash由于自身的技能原因,擦写过程中不能一起读。所以,你不能在运转(读代码)的一起去改写同一个flash芯片中的内容。但你说的跳到sdram中去运转并改写flash应该是能够的。

还有,flash的写操作不同于ram,是需求经过一系列的特定操作才完结的。这个你能够细心看看flash芯片的手册,不同的芯片或许会有差异。blob中能够找到详细的程序比方参阅。

4.

我便是要擦除Flash. 然后写Flash. 我现在是把代码悉数copy到SDRAM里边去。然后跳到SDRAM里边去运转。我现在也现已这样做了。 可是我在SDRAM里边运转,并且要写Flash(包含读ID ) 的时分。体系运转就乱了。 或许发生了反常。我不知道这个怎样处理?

5.

假如你承认程序能够正确进入sdram运转了,最或许出问题的便是这段程序中的跳转句子。你的跳转是相对跳转仍是肯定跳转?假如是肯定跳转,编译的时分编译器不会知道你今后会把程序挪当地,跳转的意图地址仍是在flash中。这样就犯错了

6.

Sorry, 前面说错了。是跳到SRAM里边。 不过差不多。

跳转到SRAM里边后,假如不操作Flash. 到目前为止,如同没有什么问题。都能正常运转。 可是只需操作Flash,就会死!

什么是相对跳转?? 什么是肯定跳转??

我用的指令是:

;;这儿是copy_rom_data

bl copy_romdata_to_sram

;; 这儿是跳转到sram 里边去。

ldr pc, =0x600000ac

7.

机器级b和bl指令有一个约束:跳转的规模在当时指令的+/-32Mb规模内。为什么?由于跳转的意图地是以当时的指令为起点的。这便是相对(于当时地址)的跳转。肯定跳转便是直接指定意图地址的跳转,比方你直接给pc赋一个当即数值,便是肯定跳转。你也能够用bx/blx Rm来完成肯定跳转。

我其实对arm指令不熟,你自己揣摩一下吧。我仅仅说明晰一种简略呈现的过错,期望对你有协助。

8.

设置tlb表了么?

在翻开mmu之前,把00000000物理地址映射到其他一个地址例如e0000000,然后翻开mmu,对e0000000操作,便是对flash操作

9.

没有。 怎样设置TLB表? 能否给我一个sample code ?

10.

操作死机原因或许是:

1.在体系开始时,将Flash ROM 的映射特点设置为uncache和unbuffer.参阅Windows CE的Source Code

2.衔接时的数据段,代码段的地址是否正确.参阅blob

3.数据段和bss段是现已初始化正确.参阅blob

4.假如仍是失利,初始化代码用Multi ICE 仿制到 SDRAM中直接调试运转。

留意:

1.最好不要运用ARM 供给的集成开发环境

2.再看一边L7205的参阅手册。

3.看原理图

4.看flash rom 的材料,如sst 、amd的源代码

11.

你的中止向量怎样处理的?有没有把中止向量映射到你的SRAM中去?

12.

由于程序运转中我不修正任何中止向量. 我需求映射到SRAM去吗?

—————-

不是说你是否修正中止向量,而是说在你的代码作业过程中会不会发生中止

—————-

我的代码在作业过程中 不发生中止。由于我屏蔽了!

假如发生中止会怎样样?

—————

假如发生中止,那么cpu会去中止向量表中拜访相应的中止向量并履行,而此刻你的Flash处于写状况

13.

只需写Flash. 程序就不知道跑到什么当地去了。 我用的是Sharp的Flash. 读厂家的ID 指令是 0x90. 写这个指令时,就发生过错了。表现为程序没有持续运转下去。由于Flash坐落0x0000000。

14.

你是否运用L7200或是L7205,假如是请留意,SRAM的巨细和你的代码巨细

15.

我用的是Cirrus Logic EP7312. 我的代码巨细没有超越SRAM的巨细不到5K

16.

她的观点跟我相同,你很或许有肯定跳转的指令,使得你的程序运转到半途又跳回到flash中去了。

把你的代码贴出来看看。应该不长吧。

你用了blob吗?

17.

半途跳转到Flash中去了??? 可是假如我把读Flash ID这段代码注释掉. 程序运转很正常阿!? 看看我这段代码:

下面这段是初始化中的程序片断:

。。。。。。。。。。

IMPORT Move_Program

BL Move_Program

ldr pc, =0x600000b8 ; 跳到C的入口处。

…………………….

下面一段代码是读Flahs的ID的函数:

void CheckFlash(void)

{

unsigned long* addr = (unsigned long*)0x00000000;

unsigned long MID;

unsigned long DeviceID;

*addr = 0x00900090;

MID = *addr;

if( MID == 0x00B0000B )

{

//display Manufacture ID

}

addr+=2;

DeviceID = *addr;

if( DeviceID == 0x00D000D0 )

{

// display “Device ID”

}

}

下面的代码是仿制程序到 SRAM.

void Move_Program(void)

{

unsigned long* rom_adr=(unsigned long*)0x00000000;

unsigned long* ram_adr=(unsigned long*)0x60000000;

int i;

int rom_size;

rom_size = (int)(rom_data_base-0x00000000);

for( i=0; i

{

*ram_adr++ = *rom_adr++;

}

}

18.

BL Move_Program

這句可是要返回到flash中的

————–

这条指令( BL Move_Program ) 当然回到Flash. 他的下条指令 : ldr pc, =0x600000b8 才是真实转到SRAM里边去履行。

————-

19.

你在进入c代码后到读flash之前都做了那些事?

其他你能够试试能不能从flash中直接读数据?

20.

在读flash前,我做了LCD的初始化和相关的测验。 其他我能够直接读flash中的数据(包含程序代码等等)。

21.

MID = *addr;

if( MID == 0x00B0000B )

{

//display Manufacture ID

}

上面这段能显现出来吗?(应该能够吧)

addr+=2;

这儿,地址+2,好象不对吧,你的可是32位数据总线

DeviceID = *addr;

if( DeviceID == 0x00D000D0 )

{

// display “Device ID”

}

}

我想这儿就飞了吧

给你一段读的代码

WRITE_FLASH(0x00000000,0x00980098);

OffSet=0x10<<2;

ReadData=READ_FLASH(0x0+OffSet);

//特点Q

OffSet=0x11<<2;

ReadData=READ_FLASH(0x0+OffSet);

//特点“R“

OffSet=0x12<<2;

ReadData=READ_FLASH(0x0+OffSet);

//特点”Y“

22.

MID = *addr;

if( MID == 0x00B000B0 )

{

//display Manufacture ID

}

到这儿底子无法显现!!

下面这个你说得对。

能够改成 : addr++; addr++;

23.

你用的什么编译器?

unsigned long是多少位的?

还有,你确认你的CPU的MID是0x00B000B0?

最终,你用什么显现ID的,最好用串口,假如是LCD的话,

或许是显现句子形成的过错

—————————

我用ARM SDT 2.50.

unsigned long 是32Bit. unsigned int 也是 32Bit.

不是CPU 的MID. 是Flash的 Manufacture ID . 我坚信 它是:

0x00B000B0

我用LCD显现ID. 显现驱动是我自己写的。能正常显现。

24.

把check_flash的汇编代码贴出来。c程序里边看不出详细有了什么跳转办法。

举个比方:(用的是伪代码)

jump 0x00000300

这样一句句子不论你把它仿制到哪里,他都必定会履行到0x300这个地址去的.假如你的程序中有这样的跳转,由于编译的时分编译器不知道你会把它仿制到其他当地,必定填充的是当时程序段内的地址.而这个地址不会跟着你的代码的搬移而改动.那么履行到这一句的时分就又跳回去了.

代码自身是没错的,错就错在它是不行移动的.

25.

我的Check_flash原本便是用C写的。 由于我仅仅想简略测验一下在我把ROM CODE搬到SRAM区后,能否操作Flash.

所以就那么简略。

我想在编译衔接阶段不会把详细的段地此也放在最终的代码中。它总是在运转的时分把地点段的地址和它相加便是了。假如真的像你所说,那么我前面的代码(在操作Flash之前)必定不能运转。可是实际状况正像我所料。我的LCD能作业。我的蜂鸣器能响。我的LED能闪耀。

26.

你仍是没有懂我的意思.

只需你的sram中能运转程序,它就能够写flash.

假如不能,必定是你的程序出了问题.最常见的便是真实的”自己写自己”.由于编程时,flash的状况不是一般的读状况,所以处理器读不到程序代码,当然就犯错了.

假如你做的都是对的,那么为什么会犯错呢?

你说过,你是在没有操作体系的裸机上运转的,那么你的代码必定不是一个可履行程序,而是真实的机器代码段.除了程序自己,没有人会帮他设置什么运转时的段地址的.

没有肯定跳转的程序是能够移动的,有肯定跳转的程序是不行移动的.

27.

你的意思是置疑我的程序是否真的在SRAM里边运转? 仍是置疑我的Check_Flash有问题?

1)。 在Flash里边运转程序和在SRAM运转程序的速度是有很大差其他。 能够从运转的状况能够看出来。这点根本能够确认程序真的在SRAM运转。(不然也无法跨越这条指令:

ldr pc, =0x600000b8 )

2)。Check_Flash 真的有问题吗? 我真的是用C写的。

我再查看他编译今后的汇编代码看看。

28.

那,下面便是用armcc 编译发生的asm代码。

====================================

CheckFlash

MOV a2,#0x90

ADD a2,a2,#0x900000

MOV a1,#0

STR a2,[a1,#0]

MOV a2,#0

ADD a3,pc,#L000198-.-8

B LCDDrawStr

L000198

DCB “Unkn”

DCB “ow F”

DCB “LASH”

DCB ” DEV”

DCB “ICE\0″

===================================

留意。我把查看设备ID的那部分注释掉了。

从这个代码看,如同也没有问题。 你说呢?

29.

CheckFlash

MOV a2,#0x90

ADD a2,a2,#0x900000

MOV a1,#0

STR a2,[a1,#0]

假如在flash中履行,那么这一句之后,程序代码就读不到了,也便是程序飞掉了.

MOV a2,#0

ADD a3,pc,#L000198-.-8

B LCDDrawStr

L000198

DCB “Unkn”

DCB “ow F”

DCB “LASH”

DCB ” DEV”

DCB “ICE\0″

假如你的LCD显现是正常的.你试试在这段程序最初的当地把PC的值显现出来,看看是不是在flash中运转.

30.

MID = *addr;

if( MID == 0x00B000B0 )

{

你在这儿用串口先显现一下PC的值,看他是在Flash仍是

sdram里边,最好然后延时一会,看看作用

//display Manufacture ID

我置疑调用你的显现函数时分,回到Flash里边去了,假如能够,

在你的显现函数里边,也从串口输出PC的值,看看是在flash

仍是sdram里边

}

31.

我不知道你的编译器,不过象gcc的,c的函数名通常在汇编中看到的是加前缀_的c函数名. 象Move_Program的c函数,在汇编中是看不到的。在gcc中是在Move_Program前加asmlinkage。

32.

我调试过,我用LCD显现出PC. 请看:

在这个句子”*addr = 0x00900090″ 之前, PC都正常。显现成果为SRAM里边的地址(0x60000278), 可是假如一履行这个句子之后,PC 无法显现出来了(便是我调用了显现函数,但没有显现)。可是如同又能跑!由于LED在闪耀。(留意在这条句子之后,我加了LED 闪耀功用,以证明程序在跑 ) 很古怪。

33.

那便是你的显现函数有问题啦,不是程序跑飞了。

你再细心查查看详细的过错呈现在什么方位上吧。

你不是有指示灯吗,在显现函数的入口处参加PC的查看代码,看看PC是在什么规模,比方,在sram就平息指示灯,在flash中就点亮指示灯。

34.

谢谢各位! 我理解了。 哈哈~~~~~~~

原来是那些全局变量(字库)的地址还没有变。怪不得,在我写0x00000000之前,程序依然拜访的是Flash里边的ROM DATA. 然后在写0x00000000后, 此刻Flash的读写状况发生变化,可是程序依然要拜访Flash里边的ROM DATA. 这个时分问题就出来了。由于这个时分Flash或许无法正确读出ROM DATA. 所以LCD Driver无法正确拿到字库,因而无法正确显现。因而或许作如下修正就能够拉:

LCD Driver在运用肯定地址(便是 0x60000000 + 偏移 )

可是这样的话假如全局变量许多的话,或许有静态变量的话,就十分麻烦了。 有什么办法处理吗??

有劳各位了。 真的十分感谢各位。 给了许多提示和启示。

再次谢谢。 🙂

35.

可是这样的话假如全局变量许多的话,或许有静态变量的话,就十分麻烦了。 有什么办法处理吗??

能够用PIC,也便是动态衔接库运用的技能,我记住ppcboot用这种办法完成从Flash搬到RAM后,只需作简略的修补(Fixup),就能够在RAM中履行。

更简略的办法是把全局变量放到一个结构中,程序移动后调整结构指针就能够了。

36.

1.尽量用局部变量。

2.改写ld的参数(一般在makefile中,或许有一个独自的ldscript),把代码的开始地址改成你将要把它仿制曩昔的那个sram中的地址。

37.

OK. Very good.

我测验过了。能够改 -ro-base xxxxxx。

成功。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/yingyong/chuanganqi/274492.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部