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

          新聞中心

          EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > ARM9學(xué)習(xí)筆記之——SDRAM實(shí)驗(yàn)

          ARM9學(xué)習(xí)筆記之——SDRAM實(shí)驗(yàn)

          作者: 時(shí)間:2016-11-20 來源:網(wǎng)絡(luò) 收藏
          最近,我有努力學(xué)習(xí)《深入淺出嵌入式底層軟件開發(fā)》。我自我覺得這本書很好。如果你有一塊Mini2440的開發(fā)板,那就再好不過了。

          學(xué)了點(diǎn)東西,寫點(diǎn)總結(jié)。以下是我在做 Page130,2.6.8內(nèi)存驅(qū)動(dòng)實(shí)驗(yàn)總結(jié)。

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

          -------

          我按照書上的指示,完成了代碼的編寫。對項(xiàng)目作如下配置:

          上述的配置中 -ro-base 0x30000000 告訴Linker,本程序?qū)⒈患虞d到 0x30000000 上運(yùn)行。

          實(shí)驗(yàn)程序的功能是,程序最初是在0x00000000 地址上開始運(yùn)行。它初始化SDRAM后,將自己到0x30000000地址上,然后跳到SDRAM中運(yùn)行。

          第一個(gè)問題:我在用AXD進(jìn)行調(diào)試時(shí),總是發(fā)現(xiàn)程序運(yùn)行到 copyallloop 中死掉。

          copyallIMPORT	|Image$$RO$$Base|    IMPORT	|Image$$RW$$Limit|    ldr r0, = |Image$$RO$$Base|   ldr r1, = |Image$$RW$$Limit|   ldr r2, = 0x00000000   copyallloopteq r0, r1   beq quitcopy   ldr r3 , [r2], #4   str r3 , [r0], #4	     b copyallloop   quitcopymov pc, lr

          copyall函數(shù)的功能是將 0x00000000 地址上的所有程序代到到SDRAM的 0x30000000 地址上去??墒强偸窃赾opyallloop 循環(huán)中死掉。

          結(jié)果查看寄存器才知道,知道程序開始并沒有被加載到0x00000000的地址上,而是被加載到SDRAM中。如下是程序開始運(yùn)行時(shí),各寄存器的值:

          由此可以得知,PC的初始值為0x3000005C,而不是PC = 0x00000000。說明調(diào)試時(shí)程序被加載到SDRAM中運(yùn)行。

          這么一來,那么將0x00000000地址區(qū)間的數(shù)據(jù)考到0x30000000地址上來,而程序自身就運(yùn)行在0x30000000地址上。這樣一來,的數(shù)據(jù)將程序自己給覆蓋了。難怪要死在那里。

          在進(jìn)入copyallloop之前,反匯編如下:

          當(dāng)r0 = 0x3000000D0時(shí):


          此時(shí),0x300000D0之前的指令已被更改。所以,死在這里了。

          第二個(gè)問題:為什么xmain()函數(shù)被放在0x0000地址上,而不是start呢?

          令我奇怪的是,程序開始執(zhí)行時(shí),PC并不等于0x00000000,而是另一個(gè)值。如下所示:



          可見,圖中所示A處,PC并不等于0x0000,而是0x005C。不對呀!ARM核啟動(dòng)不是多0x0000開始的嗎?怎么成了0x005C呢?再看D處,start啟動(dòng)程序被放到了0x005C的位置。而放在 0x0000 地址上的指令則是xmain函數(shù)入口,見C處。

          當(dāng)我退出調(diào)試模式,直接復(fù)位運(yùn)行。我發(fā)現(xiàn),程序只在反復(fù)運(yùn)行 xmain() 函數(shù)。而沒有執(zhí)行start處初始化相關(guān)的指令??梢夾RM復(fù)位后,還是從0x0000地址上開始執(zhí)行的。

          那么,為什么編譯器要把 xmain 放在0x0000地址上,而不是 start 呢?我詳細(xì)地對比了書上的配置界面的各項(xiàng)設(shè)置。發(fā)現(xiàn)在 Equivalent Command Line 欄中,我少寫了 "-first init.o" 這句話的意思就是說,把init.o目標(biāo)文件的代碼放在首位。正確的命令串為:

          -info totals -ro-base 0x30000000 -first init.o


          修改配置后,重新編譯。在AXD中查看其反匯編代碼,如下:

          這樣一來,start就被放到了前面了。

          第三個(gè)問題:如何完成實(shí)驗(yàn)?

          現(xiàn)在,我把 RO Base設(shè)置成了0x30000000 ,只要一進(jìn)入調(diào)試模式,AXD就自動(dòng)將我的代碼加載到了 SDRAM 的 0x30000000地址上了。

          按照書中的要求,代碼應(yīng)該被燒錄到 0x00000000 地址上(Nor Flash)中才對。而且工程編譯后又沒有bin或hex文件,也沒法直接用H-Flasher燒。

          (1)我該怎么讓代碼在調(diào)試時(shí)燒到 0x00000000 上,而不是 0x30000000上。

          (2)如何讓工程在編譯時(shí)生成燒錄文件。

          關(guān)于生成bin文件方法:

          1. DebugRel Settings->Linker->ARM fromELF->Output format指定Plain binary->Output file name 路徑

          2. DebugRel Settings->Target->Post-Linker中選擇ARM fromELF

          3. 重新Make,就會(huì)生成bin文件。



          關(guān)鍵詞: ARM9SDRAM實(shí)

          評論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁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); })();