<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          ARM如何讀寫(xiě)Flash

          作者: 時(shí)間:2016-11-11 來(lái)源:網(wǎng)絡(luò) 收藏
          1.

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

          本文引用地址:http://www.ex-cimer.com/article/201611/316653.htm

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

          2.

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

          3.

          應(yīng)該這樣說(shuō),flash由于本身的技術(shù)原因,擦寫(xiě)過(guò)程中不能同時(shí)讀。所以,你不能在運(yùn)行(讀代碼)的同時(shí)去改寫(xiě)同一個(gè)flash芯片中的內(nèi)容。但你說(shuō)的跳到sdram中去運(yùn)行并改寫(xiě)flash應(yīng)該是可以的。

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

          4.

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

          5.

          如果你確認(rèn)程序能夠正確進(jìn)入sdram運(yùn)行了,最可能出問(wèn)題的就是這段程序中的跳轉(zhuǎn)語(yǔ)句。你的跳轉(zhuǎn)是相對(duì)跳轉(zhuǎn)還是絕對(duì)跳轉(zhuǎn)?如果是絕對(duì)跳轉(zhuǎn),編譯的時(shí)候編譯器不會(huì)知道你以后會(huì)把程序挪地方,跳轉(zhuǎn)的目的地址還是在flash中。這樣就出錯(cuò)了

          6.

          Sorry, 前面說(shuō)錯(cuò)了。是跳到SRAM里面。 不過(guò)差不多。

          跳轉(zhuǎn)到SRAM里面后,如果不操作Flash. 到目前為止,好像沒(méi)有什么問(wèn)題。都能正常運(yùn)行。 但是只要操作Flash,就會(huì)死!

          什么是相對(duì)跳轉(zhuǎn)?? 什么是絕對(duì)跳轉(zhuǎn)??

          我用的指令是:

          ;;這兒是copy_rom_data

          bl copy_romdata_to_sram

          ;; 這兒是跳轉(zhuǎn)到sram 里面去。

          ldr pc, =0x600000ac

          7.

          機(jī)器級(jí)b和bl指令有一個(gè)限制:跳轉(zhuǎn)的范圍在當(dāng)前指令的+/-32Mb范圍內(nèi)。為什么?因?yàn)樘D(zhuǎn)的目的地是以當(dāng)前的指令為起點(diǎn)的。這就是相對(duì)(于當(dāng)前地址)的跳轉(zhuǎn)。絕對(duì)跳轉(zhuǎn)就是直接指定目的地址的跳轉(zhuǎn),比如你直接給pc賦一個(gè)立即數(shù)值,就是絕對(duì)跳轉(zhuǎn)。你也可以用bx/blx Rm來(lái)實(shí)現(xiàn)絕對(duì)跳轉(zhuǎn)。

          我其實(shí)對(duì)arm指令不熟,你自己琢磨一下吧。我只是說(shuō)明了一種容易出現(xiàn)的錯(cuò)誤,希望對(duì)你有幫助。

          8.

          設(shè)置tlb表了么?

          在打開(kāi)mmu之前,把00000000物理地址映射到另外一個(gè)地址例如e0000000,然后打開(kāi)mmu,對(duì)e0000000操作,就是對(duì)flash操作

          9.

          沒(méi)有。 怎么設(shè)置TLB表? 能否給我一個(gè)sample code ?

          10.

          操作死機(jī)原因可能是:

          1.在系統(tǒng)開(kāi)始時(shí),將Flash ROM 的映射屬性設(shè)置為uncache和unbuffer.參考Windows CE的Source Code

          2.連接時(shí)的數(shù)據(jù)段,代碼段的地址是否正確.參考blob

          3.數(shù)據(jù)段和bss段是已經(jīng)初始化正確.參考blob

          4.如果還是失敗,初始化代碼用Multi ICE 拷貝到 SDRAM中直接調(diào)試運(yùn)行。

          注意:

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

          2.再看一邊L7205的參考手冊(cè)。

          3.看原理圖

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

          11.

          你的中斷向量怎么處理的?有沒(méi)有把中斷向量映射到你的SRAM中去?

          12.

          因?yàn)槌绦蜻\(yùn)行中我不修改任何中斷向量. 我需要映射到SRAM去嗎?

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

          不是說(shuō)你是否修改中斷向量,而是說(shuō)在你的代碼工作過(guò)程中會(huì)不會(huì)產(chǎn)生中斷

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

          我的代碼在工作過(guò)程中 不產(chǎn)生中斷。因?yàn)槲移帘瘟耍?/p>

          如果產(chǎn)生中斷會(huì)怎么樣?

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

          如果發(fā)生中斷,那么cpu會(huì)去中斷向量表中訪問(wèn)相應(yīng)的中斷向量并執(zhí)行,而此時(shí)你的Flash處于寫(xiě)狀態(tài)

          13.

          只要寫(xiě)Flash. 程序就不知道跑到什么地方去了。 我用的是Sharp的Flash. 讀廠家的ID 命令是 0x90. 寫(xiě)這個(gè)命令時(shí),就發(fā)生錯(cuò)誤了。表現(xiàn)為程序沒(méi)有繼續(xù)運(yùn)行下去。因?yàn)镕lash位于0x0000000。

          14.

          你是否使用L7200或是L7205,如果是請(qǐng)注意,SRAM的大小和你的代碼大小

          15.

          我用的是Cirrus Logic EP7312. 我的代碼大小沒(méi)有超過(guò)SRAM的大小不到5K

          16.

          她的看法跟我一樣,你很可能有絕對(duì)跳轉(zhuǎn)的指令,使得你的程序運(yùn)行到中途又跳回到flash中去了。

          把你的代碼貼出來(lái)看看。應(yīng)該不長(zhǎng)吧。

          你用了blob嗎?

          17.

          中途跳轉(zhuǎn)到Flash中去了??? 但是如果我把讀Flash ID這段代碼注釋掉. 程序運(yùn)行很正常阿!? 看看我這段代碼:

          下面這段是初始化中的程序片斷:

          。。。。。。。。。。

          IMPORT Move_Program

          BL Move_Program

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

          .........................

          下面一段代碼是讀Flahs的ID的函數(shù):

          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"

          }

          }

          下面的代碼是復(fù)制程序到 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 ) 當(dāng)然回到Flash. 他的下條指令 : ldr pc, =0x600000b8 才是真正轉(zhuǎn)到SRAM里面去執(zhí)行。

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

          19.

          你在進(jìn)入c代碼后到讀flash之前都做了那些事?

          另外你可以試試能不能從flash中直接讀數(shù)據(jù)?

          20.

          在讀flash前,我做了LCD的初始化和相關(guān)的測(cè)試。 另外我可以直接讀flash中的數(shù)據(jù)(包括程序代碼等等)。

          21.

          MID = *addr;

          if( MID == 0x00B0000B )

          {

          //display Manufacture ID

          }

          上面這段能顯示出來(lái)嗎?(應(yīng)該可以吧)

          addr+=2;

          這里,地址+2,好象不對(duì)吧,你的可是32位數(shù)據(jù)總線

          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

          }

          到這兒根本無(wú)法顯示!!

          下面這個(gè)你說(shuō)得對(duì)。

          可以改成 : addr++; addr++;

          23.

          你用的什么編譯器?

          unsigned long是多少位的?

          還有,你確定你的CPU的MID是0x00B000B0?

          最后,你用什么顯示ID的,最好用串口,如果是LCD的話,

          可能是顯示語(yǔ)句造成的錯(cuò)誤

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

          我用ARM SDT 2.50.

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

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

          0x00B000B0

          我用LCD顯示ID. 顯示驅(qū)動(dòng)是我自己寫(xiě)的。能正常顯示。

          24.

          把check_flash的匯編代碼貼出來(lái)。c程序里面看不出具體有了什么跳轉(zhuǎn)方式。

          舉個(gè)例子:(用的是偽代碼)

          jump 0x00000300

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

          代碼本身是沒(méi)錯(cuò)的,錯(cuò)就錯(cuò)在它是不可移動(dòng)的.

          25.

          我的Check_flash本來(lái)就是用C寫(xiě)的。 因?yàn)槲抑皇窍牒?jiǎn)單測(cè)試一下在我把ROM CODE搬到SRAM區(qū)后,能否操作Flash.

          所以就那么簡(jiǎn)單。

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

          26.

          你還是沒(méi)有懂我的意思.

          只要你的sram中能運(yùn)行程序,它就可以寫(xiě)flash.

          如果不能,一定是你的程序出了問(wèn)題.最常見(jiàn)的就是真正的"自己寫(xiě)自己".因?yàn)榫幊虝r(shí),flash的狀態(tài)不是普通的讀狀態(tài),所以處理器讀不到程序代碼,當(dāng)然就出錯(cuò)了.

          如果你做的都是對(duì)的,那么為什么會(huì)出錯(cuò)呢?

          你說(shuō)過(guò),你是在沒(méi)有操作系統(tǒng)的裸機(jī)上運(yùn)行的,那么你的代碼一定不是一個(gè)可執(zhí)行程序,而是真正的機(jī)器代碼段.除了程序自己,沒(méi)有人會(huì)幫他設(shè)置什么運(yùn)行時(shí)的段地址的.

          沒(méi)有絕對(duì)跳轉(zhuǎn)的程序是可以移動(dòng)的,有絕對(duì)跳轉(zhuǎn)的程序是不可移動(dòng)的.

          27.

          你的意思是懷疑我的程序是否真的在SRAM里面運(yùn)行? 還是懷疑我的Check_Flash有問(wèn)題?

          1)。 在Flash里面運(yùn)行程序和在SRAM運(yùn)行程序的速度是有很大差別的。 可以從運(yùn)行的情況可以看出來(lái)。這點(diǎn)基本可以確定程序真的在SRAM運(yùn)行。(否則也無(wú)法逾越這條指令:

          ldr pc, =0x600000b8 )

          2)。Check_Flash 真的有問(wèn)題嗎? 我真的是用C寫(xiě)的。

          我再檢查他編譯以后的匯編代碼看看。

          28.

          那,下面就是用armcc 編譯產(chǎn)生的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看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();