新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > ARM入門筆記(2)

        ARM入門筆記(2)

        作者: 時間:2016-12-02 來源:網絡 收藏
        ―將程序執行到C文件的main函數

        二.實驗目的

        運用ADS編寫一個小程序,使程序能夠從起始的匯編代碼運行到C程序的main()函數(這也可稱作非常簡單的起動代碼),并通過仿真器連接目標板,最終能夠在AT91SAM7S64里正確運行。

        三.實驗程序和參數設置

        1>連接器的選項設置

        選項設置如圖2-1所示。因為在AT91SAM7S64中FLASH存儲器的地址是以0x0開始,而SRAM的地址是以0x00200000開始,所以我將下圖中的RO Base和RW Base分別設置成了0x0和0x00200000。其它設置請參考有關書籍。
                  

        圖2-1. 選項設置圖

        2>啟動代碼

        ARM應用系統中,芯片復位后,在進入C語言的main()函數前,都要執行一段啟動代碼。該代碼一般都是用匯編語言編寫,用來完成系統運行環境和應用程序的初始化,詳情請參考有關書籍。由于本實驗的目的很簡單,就是想讓程序復位后,進入main()函數,所以有些初始化代碼盡量精簡,留下了下述代碼。另外,__main是C語言的內部庫函數,可以在進入用戶main()之前完成內部RAM的初始化工作,類似KeilC51中的startup.a51。當執行完__main這段代碼后,再跳轉到main()函數。

        AREA init,CODE,READONLY
        CODE32
        Mode_USREQU0x10 ;CPSR中各種處理器模式對應的控制位
        I_Bit EQU0x80 ;CPSR中的中斷禁止位
        F_Bit EQU0x40
        USR_StackEQU0x00203000 ;定義RAM的最高地址,無重映射
        ENTRY
        B InitReset ; 0x00 Reset handler
        undefvec B undefvec ; 0x04 Undefined Instruction
        swivec B swivec ; 0x08 Software Interrupt
        pabtvec B pabtvec ; 0x0C Prefetch Abort
        dabtvec B dabtvec ; 0x10 Data Abort
        rsvdvec B rsvdvec ; 0x14 reserved
        irqvec B irqvec ; 0x18IRQ
        fiqvec B fiqvec ; 0x1c FIQ
        InitReset
        MSR CPSR_c,#Mode_USR | I_Bit | F_Bit ;改成用戶模式且禁止IRQ和FIQ中斷
        LDR SP,=USR_Stack
        IMPORT__main
        b __main;跳轉到__main執行,它位于C運行時庫中
        END
        3>C語言主函數
        在C語言主函數中做了一個死循環,如下述所示。
        int main(void)
        {
        while (1);
        }

        四.出現的問題與解決方法

        當完成上述操作后,先用軟件仿真,很快達到了目的,但將程序通過仿真器在目標板運行時出現了下述問題。

        1> 當執行單步運行時,PC一直停留在0x0處,而且Debug Log窗口中顯示“RDI Warning 00148: Cant set point”。
        原因是仿真器在ROM中設置的斷點數是有限的,且單步運行時內部還要占用斷點??梢允褂?ldquo;Option->Config Processor”打開“Processor Properties-ARM7TDMI”窗口,且按照下圖設置以關斷相的斷點。


        圖2-2

        2> 裝載的代碼與實踐程序不一樣

        原因是由于程序沒有裝載到AT91SAM7S64的FLASH ROM里,在調試器中顯示的是FLASH ROM中原先就有的程序。因為在連接器的選項設置中,將RO Base和Image entry point指向了0地址,而在AT91SAM7S64的這段空間為FLASH ROM區,而仿真器不能直接將代碼下載到FLASH ROM里。用仿真器只能將代碼下載到AT91SAM7S64的內部SRAM里進行調試,必須將ARM Linker->Output->Simple image->RO Base和Image entry point的0,改成SRAM的地址0x002000000。

        3>在軟件仿真的情況下,執行“B __main”指令,能使程序跳到C文件的main函數,但用硬件仿真時,還沒執行到main函數時就進入了異常中斷。

        原因是執行“B __main”指令后,程序先跳到__main庫函數的入口,再進行一些初始化操作,最后再跳入用戶的main函數。但在初始化過程中,由于堆?;蚱渌蛟斐沙绦虺鲥e。有兩種方法可以解決這個問題。第一:將“B __main”指令直接改成“B main”,使程序不進行初始化而直接跳入用戶的main()函數。第二:合理初始化堆棧。由于考慮到剛接觸ARM和將問題簡單化,我選擇了第一種方法。

        五.總結

        1> 在用仿真器時,必須將程序下載到AT91SAM7S64的內部SRAM中,而不是Flash ROM。

        2> 從匯編代碼進入C文件函數時,可以直接使用C語言中的標號(可參考書中混合編程部分),如執行“B main”則直接跳到C語言的main()函數入口。

        3> 在起動代碼中,可以調用__main()庫函數進行存儲器的初始化,也可以自己編寫更有效的代碼進行初始化,在初始化后就可以使用“B __main”指令直接跳轉到C的main()函數。


        評論


        技術專區

        關閉
        主站蜘蛛池模板: 台南县| 道孚县| 霍林郭勒市| 临桂县| 彭水| 贞丰县| 玉田县| 南澳县| 泽库县| 达孜县| 海晏县| 昂仁县| 保亭| 云龙县| 剑川县| 永兴县| 芦山县| 分宜县| 抚松县| 平利县| 寿阳县| 华宁县| 靖安县| 崇礼县| 民丰县| 商水县| 江阴市| 岳池县| 武宁县| 双柏县| 塘沽区| 泌阳县| 高碑店市| 北海市| 阿图什市| 邵阳市| 浦北县| 曲松县| 新龙县| 博白县| 新乡市|