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

          新聞中心

          EEPW首頁(yè) > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > ARM開發(fā)的問(wèn)題總結(jié)

          ARM開發(fā)的問(wèn)題總結(jié)

          作者: 時(shí)間:2016-11-09 來(lái)源:網(wǎng)絡(luò) 收藏
          匯編代碼要注意有些要頂格,有些要加空格,否則編譯會(huì)有問(wèn)題

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

          (一)堆的設(shè)置問(wèn)題

          在啟動(dòng)代碼 B__mian指令后,程序沒(méi)有跳到main函數(shù)處,而是進(jìn)入了異常中斷。

          原因:通過(guò)反匯編,可以看到,在執(zhí)行B__mian指令后,并不是立即跳到main函數(shù)處,而是先跳到__main庫(kù)函數(shù)入口,再執(zhí)行一些堆棧的拷貝等初始化操作,最后跳到main函數(shù)處。出現(xiàn)異常,可能是堆或棧的設(shè)置有問(wèn)題。(在一個(gè)例子中發(fā)現(xiàn)把堆得起始地址改小就可以了)

          (二)ARM在RAM中調(diào)試問(wèn)題

          IROM1:0x4000000 0x10000 (必須將IROM1地址設(shè)置到RAM空間)

          IRAM1:0x4010000 0x8000

          RAM.ini 文件中

          PC = 0x04000000;

          (三)如何指定某段代碼的運(yùn)行空間

          選擇該文件(*.c),鼠標(biāo)右鍵(options for File *.c)---->Memory Assignment 可指定該文件代碼運(yùn)行的空間(可以運(yùn)行在FLASH,也可以指定在RAM)

          (四)MDK生成bin文件

          可以用ARM自帶的fromelf.exe將*.axf文件轉(zhuǎn)換成*.bin文件

          Options for Target---->user---->run #1----->

          C:/Keil/ARM/BIN31/fromelf.exe --bin -o ./output/Axf_To_Bin.bin ./output/Axf_To_Bin.axf

          (四)編譯后的代碼含義

          Program Size: Code=2356 RO-data=32 RW-data=28 ZI-data=1292

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

          Total RO Size (Code + RO Data) 2388 ( 2.33kB)
          Total RW Size (RW Data + ZI Data) 1320 ( 1.29kB)
          Total ROM Size (Code + RO Data + RW Data) 2416 ( 2.36kB)

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

          Execution Region RW_IRAM1 (Base: 0x04000000, Size: 0x00000528, Max: 0x00018000, ABSOLUTE)

          Base Addr Size Type Attr Idx E Section Name Object

          0x04000000 0x0000001c Data RW 89 .data main.o
          0x0400001c 0x00000004 PAD
          0x04000020 0x00000508 Zero RW 1 STACK str91x.o

          Code表示程序代碼量

          RO-data 表示固定常量(const 變量)

          RW-data 表示初始化常量(char gloab_test =5)

          ZI -data 表示未初始化初始化常量,即是零(char gloab_test =0)

          燒寫到FALSH的空間:Code + RO Data + RW Data

          RAM空間: RW Data + ZI Data

          啟動(dòng)代碼中,顯然有個(gè)RW Data 拷貝過(guò)程,其實(shí)還應(yīng)該包括初ZI -data 清零過(guò)程,堆和棧的初始化過(guò)程,這些應(yīng)該在B__mian指令后實(shí)現(xiàn),只有通過(guò)反匯編可以看到

          (五)未對(duì)齊的數(shù)據(jù)指針

            C和C++編程標(biāo)準(zhǔn)規(guī)定,指向某一數(shù)據(jù)類型的指針,必須和該類型的數(shù)據(jù)地址對(duì)齊方式一致,所以ARM 編譯器期望程序中的 C 指針指向存儲(chǔ)器中字對(duì)齊地址,因?yàn)檫@可使編譯器生成更高效的代碼。

            比如,如果定義一個(gè)指向 int 數(shù)據(jù)類型的指針,用該指針讀取一個(gè)字,ARM 編譯器將使用LDR 指令來(lái)完成此操作。如果讀取的地址為四的倍數(shù)(即在一個(gè)字的邊界)即能正確讀取。但是,如果該地址不是四的倍數(shù),那么,一條 LDR 指令返回一個(gè)循環(huán)移位結(jié)果,而不是執(zhí)行真正的未對(duì)齊字載入。循環(huán)移位結(jié)果取決于該地址向?qū)τ谧值倪吔绲钠屏亢拖到y(tǒng)所使用的端序(Endianness)。例如,如果代碼要求從指針指向的地址 0x8006 載入數(shù)據(jù),即要載入 0x8006、0x8007、0x8008 和 0x8009 四字節(jié)的內(nèi)容。但是,在 ARM 處理器上,這個(gè)存取操作載入了0x8004、0x8005、0x8006 和 0x8007 字節(jié)的內(nèi)容。這就是在未對(duì)齊的地址上使用指針存取所得到的循環(huán)移位結(jié)果。

            因而,如果想將指針定義到一個(gè)指定地址(即該地址為非自然邊界對(duì)齊),那么在定義該指針時(shí),必須使用 __packed 限定符來(lái)定義指針: 例如,

            __packedint *pi; // 指針指向一個(gè)非字對(duì)其內(nèi)存地址

            使用了_packed限定符限定之后,ARM 編譯器將產(chǎn)生字節(jié)存取命令(LDRB或STRB指令)來(lái)存取內(nèi)存,這樣就不必考慮指針對(duì)齊問(wèn)題。所生成的代碼是字節(jié)存取的一個(gè)序列,或者取決于編譯選項(xiàng)、跟變量對(duì)齊相關(guān)的移位和屏蔽。但這會(huì)導(dǎo)致系統(tǒng)性能和代碼密度的損失。

            值得注意的是,不能使用 __packed 限定的指針來(lái)存取存儲(chǔ)器映射的外圍寄存器,因?yàn)?ARM 編譯程序可使用多個(gè)存儲(chǔ)器存取來(lái)獲取數(shù)據(jù)。因而,可能對(duì)實(shí)際存取地址附近的位置進(jìn)行存取,而這些附近的位置可能對(duì)應(yīng)于其它外部寄存器。當(dāng)使用了位字段(Bitfield)時(shí), ARM 程序?qū)⒃L問(wèn)整個(gè)結(jié)構(gòu)體,而非指定字段。

          (六) Ro Base設(shè)置

          鏈接文件選項(xiàng)中,應(yīng)將映像文件的Ro Base地址設(shè)置到映像文件實(shí)際運(yùn)行的起始地址。例如,將Ro Base設(shè)置成0x30000000,把它下載到0x0地址開始執(zhí)行是不正確,必須將該代碼復(fù)制到0x30000000起始地址處才能開始正確執(zhí)行,或者將Ro Base 設(shè)置到0x0地址

          (七)__irq關(guān)鍵字

          匯編調(diào)用C中斷函數(shù)

          匯編文件相關(guān)代碼(*.s)

          IMPORT IRQ_Handler ;不能頂格寫

          IRQ_Addr DCD IRQ_Handler

          C文件相關(guān)代碼(*.c)

          __irq void IRQ_Handler (void) {
          if (IRQSIG & 0x00000004) { // Timer 0 Interrupt
          T0CLRI = 1; // Clear Timer 0 Interrupt
          T0_Tick++; // Increment Timer 0 Tick
          }
          }

          “__irq”專門用來(lái)聲明IRQ中斷服務(wù)程序,如果用“__irq”來(lái)聲明一個(gè)函數(shù),那么該函數(shù)表示一個(gè)IRQ中斷服務(wù)程序,編譯器便會(huì)自動(dòng)在該函數(shù)內(nèi)部增加中斷現(xiàn)場(chǎng)保護(hù)的代碼



          關(guān)鍵詞: ARM開發(fā)問(wèn)題總

          評(píng)論


          技術(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); })();