免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
ARM如何讀寫Flash

1.

我在ARM上裸機。 不使用任何嵌入式操作系統(tǒng)。

我的引導程序把我的程序放在 0x00000000,(這個地方是Flash) 在初始化的時候,我把代碼區(qū)的所有代碼copy到SDRAM里面去。然后跳到SDRAM( 0xc0000000 )里面去運行。此時我能否往 0x00000000及其后的address里面寫數據?

2.

不可以,在Flash 中執(zhí)行的代碼不可以改寫Flash的內容,你可以在SDRAM中寫FLASH的內容。參考bolb和intel strongarm的dm 程序

3.

應該這樣說,flash由于本身的技術原因,擦寫過程中不能同時讀。所以,你不能在運行(讀代碼)的同時去改寫同一個flash芯片中的內容。但你說的跳到sdram中去運行并改寫flash應該是可以的。

還有,flash的寫操作不同于ram,是需要通過一系列的特定操作才完成的。這個你可以仔細看看flash芯片的手冊,不同的芯片可能會有區(qū)別。blob中可以找到具體的程序例子參考。

4.

我就是要擦除Flash. 然后寫Flash. 我現在是把代碼全部copy到SDRAM里面去。然后跳到SDRAM里面去運行。我現在也已經這樣做了。 但是我在SDRAM里面運行,而且要寫Flash(包括讀ID ) 的時候。系統(tǒng)運行就亂了。 可能產生了異常。我不知道這個怎么解決?

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.在系統(tǒng)開始時,將Flash ROM 的映射屬性設置為uncache和unbuffer.參考Windows CE的Source Code

2.連接時的數據段,代碼段的地址是否正確.參考blob

3.數據段和bss段是已經初始化正確.參考blob

4.如果還是失敗,初始化代碼用Multi ICE 拷貝到 SDRAM中直接調試運行。

注意:

1.最好不要使用ARM 提供的集成開發(fā)環(huán)境

2.再看一邊L7205的參考手冊。

3.看原理圖

4.看flash rom 的資料,如sst 、amd的源代碼

11.

你的中斷向量怎么處理的?有沒有把中斷向量映射到你的SRAM中去?

12.

因為程序運行中我不修改任何中斷向量. 我需要映射到SRAM去嗎?

----------------

不是說你是否修改中斷向量,而是說在你的代碼工作過程中會不會產生中斷

----------------

我的代碼在工作過程中 不產生中斷。因為我屏蔽了!

如果產生中斷會怎么樣?

---------------

如果發(fā)生中斷,那么cpu會去中斷向量表中訪問相應的中斷向量并執(zhí)行,而此時你的Flash處于寫狀態(tài)

13.

只要寫Flash. 程序就不知道跑到什么地方去了。 我用的是Sharp的Flash. 讀廠家的ID 命令是 0x90. 寫這個命令時,就發(fā)生錯誤了。表現為程序沒有繼續(xù)運行下去。因為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里面去執(zhí)行。

-------------

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

這樣一句語句不管你把它拷貝到哪里,他都一定會執(zhí)行到0x300這個地址去的.如果你的程序中有這樣的跳轉,因為編譯的時候編譯器不知道你會把它拷貝到別的地方,必然填充的是當前程序段內的地址.而這個地址不會隨著你的代碼的搬移而改變.那么執(zhí)行到這一句的時候就又跳回去了.

代碼本身是沒錯的,錯就錯在它是不可移動的.

25.

我的Check_flash本來就是用C寫的。 因為我只是想簡單測試一下在我把ROM CODE搬到SRAM區(qū)后,能否操作Flash.

所以就那么簡單。

我想在編譯連接階段不會把具體的段地此也放在最后的代碼中。它總是在運行的時候把所在段的地址和它相加就是了。如果真的像你所說,那么我前面的代碼(在操作Flash之前)一定不能運行。但是實際情況正像我所料。我的LCD能工作。我的蜂鳴器能響。我的LED能閃爍。

26.

你還是沒有懂我的意思.

只要你的sram中能運行程序,它就可以寫flash.

如果不能,一定是你的程序出了問題.最常見的就是真正的"自己寫自己".因為編程時,flash的狀態(tài)不是普通的讀狀態(tài),所以處理器讀不到程序代碼,當然就出錯了.

如果你做的都是對的,那么為什么會出錯呢?

你說過,你是在沒有操作系統(tǒng)的裸機上運行的,那么你的代碼一定不是一個可執(zhí)行程序,而是真正的機器代碼段.除了程序自己,沒有人會幫他設置什么運行時的段地址的.

沒有絕對跳轉的程序是可以移動的,有絕對跳轉的程序是不可移動的.

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中執(zhí)行,那么這一句之后,程序代碼就讀不到了,也就是程序飛掉了.

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), 但是如果一執(zhí)行這個語句之后,PC 無法顯示出來了(就是我調用了顯示函數,但沒有顯示)。但是好像又能跑!因為LED在閃爍。(注意在這條語句之后,我加了LED 閃爍功能,以證明程序在跑 ) 很奇怪。

33.

那就是你的顯示函數有問題啦,不是程序跑飛了。

你再仔細查查看具體的錯誤出現在什么位置上吧。

你不是有指示燈嗎,在顯示函數的入口處加入PC的檢查代碼,看看PC是在什么范圍,比如,在sram就熄滅指示燈,在flash中就點亮指示燈。

34.

謝謝各位! 我明白了。 哈哈~~~~~~~

原來是那些全局變量(字庫)的地址還沒有變。怪不得,在我寫0x00000000之前,程序仍然訪問的是Flash里面的ROM DATA. 然后在寫0x00000000后, 此時Flash的讀寫狀態(tài)發(fā)生變化,可是程序仍然要訪問Flash里面的ROM DATA. 這個時候問題就出來了。因為這個時候Flash可能無法正確讀出ROM DATA. 所以LCD Driver無法正確拿到字庫,因此無法正確顯示。因此可能作如下修改就可以拉:

LCD Driver在使用絕對地址(就是 0x60000000 + 偏移 )

但是這樣的話如果全局變量很多的話,或者有靜態(tài)變量的話,就非常麻煩了。 有什么辦法解決嗎??

有勞各位了。 真的非常感謝各位。 給了很多提示和啟發(fā)。

再次謝謝。 :-)

35.

但是這樣的話如果全局變量很多的話,或者有靜態(tài)變量的話,就非常麻煩了。 有什么辦法解決嗎??

可以用PIC,也就是動態(tài)連接庫使用的技術,我記得ppcboot用這種方法實現從Flash搬到RAM后,只要作簡單的修補(Fixup),就可以在RAM中執(zhí)行。

更簡單的方法是把全局變量放到一個結構中,程序移動后調整結構指針就可以了。

36.

1.盡量用局部變量。

2.改寫ld的參數(一般在makefile中,或者有一個單獨的ldscript),把代碼的起始地址改成你將要把它復制過去的那個sram中的地址。

37.

OK. Very good.

我測試過了??梢愿?-ro-base xxxxxx。

成功。

謝謝。

本站僅提供存儲服務,所有內容均由用戶發(fā)布,如發(fā)現有害或侵權內容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
[轉]嵌入式C語言程序的運行
友善之臂Mini2440開發(fā)板的存儲系統(tǒng)及I/O空間總結 -- adagio1983's ...
S3C2440從NAND Flash啟動和NOR FLASH啟動的問題
norflash啟動和nandflash啟動
Keil MDK使用J-LINK分別在Sram,Nor Flash以及Sdram中調試代碼的原理和方法
ARM remap與重定位摘抄
更多類似文章 >>
生活服務
分享 收藏 導長圖 關注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點擊這里聯系客服!

聯系客服