新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > IAR下的匯編/單片機啟動代碼匯編

        IAR下的匯編/單片機啟動代碼匯編

        作者: 時間:2016-11-25 來源:網絡 收藏
        可能大家看到了在IRQ中斷向量地址中裝載的是LDR PC, [PC, #-0x0FF0]指令,這里要和大家解釋一下這條語句,在和大家解釋這條語句時,希望大家去看看LPC2103的datasheet。
        當處理器開始執行LDR PC, [PC, #-0x0FF0]
        指令,PC寄存器的值就已經變成PC+8 = 0x20(這個不清楚的朋友必須去查詢一下《ARM+Architecture+Reference+Manual(2nd+Edition)》中的Prefetch and self-modifying code),
        Result = 0x20 – 0xff0 = 0xFFFFF030(實在不知道怎么算的就用電腦自帶的計算器算算);
        在查詢LPC2103數據手冊后,發現該地址對應的寄存器為VICVectAddr。
        在這條語句執行完畢后,處理器就會跳轉到導致產生IRQ中斷,并跳轉到VICVectAddr寄存器所指向的IRQ異常處理函數中進行操作。
        實際運用中,我們可以更改一下IRQ異常向量地址的語句,讓大家更加好看。更改如下:
        LDR PC, [PC, #0xFFFFF020]
        這條語句和剛才的MDK自帶的語句實現的效果是一樣的!
        實例
        軟件實現中斷處理過程
        實驗芯片:LPC2103
        開發環境:MDK3.50
        實現功能:在不使用__irq關鍵詞時,如果編寫中斷服務程序。
        知識要點:
        1、在MDK開發環境下,對于LPC2000系列處理器,MDK默認的啟動模式位系統模式。
        2、在不使用__irq關鍵字聲明時,只將中斷處理函數當成普通函數進行處理,而不會在進入中斷時對通用寄存器的內容進行保存,也不會再退出中斷時對通用寄存器的內容進行恢復,因此這部分功能是必須手動添加的。
        下面進行代碼講述,下面就是當進入IRQ中斷處理函數時的處理程序,代碼全部用匯編語句完成詳細代碼如下:
        EXPORT IRQ_Uart0
        IMPORT DuleUart0
        REQUIRE8
        PRESERVE8
        AREA CODE, CODE, READONLY
        CODE32
        IRQ_Uart0
        STMFD SP!,{R0-R12,LR}
        ;保存當前處理器的所有寄存器
        MRS R0,SPSR
        ;保存當前處理器的SPSR
        STMFD SP!,{R0}
        MRS R0,CPSR ;保存當前處理器的CPSR
        STMFD SP!,{R0}
        MOV R12, SP ;保存當前的SP寄存器
        MRS R0,CPSR ;重新打開FIQ或IRQ中斷
        BIC R0,R0,#0xC0
        MSR CPSR_cxsf,R0
        BL DuleUart0 ;執行串口0的實際處理程序
        MOV SP,R12 ;恢復SP寄存器的值
        LDMFD SP!,{R0} ;恢復中斷時的CPSR寄存器值
        MSR CPSR_cxsf,R0
        LDMFD SP!,{R0};恢復中斷前的SPSR寄存器狀態
        MSR SPSR_cxsf,R0
        LDMFD SP!,{R0-R12};恢復中斷時的所有寄存器值
        LDMFD SP!,{LR};恢復進入中斷時的PC返回地址
        SUBS PC,LR,#4;返回中斷服務程序
        END
        大家可能存在的問題如下:
        1、為什么我們在進入這段中斷處理程序中還在使用LDM和STM語句呢,不是說在用戶或系統模式中使用該語句會產生不可預料的結果么?
        答:當系統進入IRQ異常時,就會將處理器模式切換到IRQ異常模式。
        2、為什么會在最后一句執行SUBS PC,LR,#4(這一句就不在解釋了),不清楚的就去看看《ARM體系結構與編程》
        好了,我們現在對照著在uC/OS-II中的中斷編寫方法:
        Void ISP_Function( void )
        {
        保存全部的CPU寄存器;
        調用OSIntEnter()或OSIntNesting++;
        If(OSIntNesting == 1 )
        {
        OSTCBCur->OSTCBStkPtr= SP ;
        }
        清中斷源;
        重新打開中斷;
        執行用戶代碼做中斷服務;
        調用OSIntExit();
        恢復所有CPU寄存器;
        執行中斷返回指令;
        }
        而在我們的處理代碼中,我們的執行過程如下偽代碼所示:
        Void ISRFunction( void )
        {
        保存全部寄存器的內容;
        清中斷源;
        執行用戶代碼;
        恢復所有CPU寄存器;
        執行中斷返回;
        }
        對于沒有的部分,大家可以試著去編寫一下!
        詳細代碼可以下載,也可以移植到你現有的開發板上去試試。
        --------------------------------------------------------------------------------
        基于ARM的芯片多數為復雜的片上系統,這種復雜系統里的多數硬件模塊都是可配置的,需要由軟件來設置
        其需要的工作狀態。因此在用戶的應用程序之前,需要由專門的一段代碼來完成對系統的初始化。由于這
        類代碼直接面對處理器內核和硬件控制器進行編程,一般都是用匯編語言。一般通用的內容包括:
        中斷向量表
        初始化存儲器系統
        初始化堆棧
        初始化有特殊要求的斷口,設備
        初始化用戶程序執行環境
        改變處理器模式
        呼叫主應用程序
        中斷向量表
        ARM要求中斷向量表必須放置在從0地址開始,連續8X4字節的空間內。
        每當一個中斷發生以后,ARM處理器便強制把PC指針置為向量表中對應中斷類型的地址值。因為每
        個中斷只占據向量表中1個字的存儲空間,只能放置一條ARM指令,使程序跳轉到存儲器的其他地方,再執行
        中斷處理。
        中斷向量表的程序實現通常如下表示:
        AREA Boot ,CODE, READONLY
        ENTRY
        B  ResetHandler
        B  UndefHandler
        B  SWIHandler
        B  PreAbortHandler
        B  DataAbortHandler
        B
        B  IRQHandler
        B  FIQHandler
        其中關鍵字ENTRY是指定編譯器保留這段代碼,因為編譯器可能會認為這是一段亢余代碼而加以優化。鏈
        接的時候要確保這段代碼被鏈接在0地址處,并且作為整個程序的入口。
        初始化存儲器系統
        存儲器類型和時序配置
        通常Flash和SRAM同屬于靜態存儲器類型,可以合用同一個存儲器端口;而DRAM因為有動態刷新和地
        址線復用等特性,通常配有專用的存儲器端口。
        存儲器端口的接口時序優化是非常重要的,這會影響到整個系統的性能。因為一般系統運行的速度
        瓶頸都存在于存儲器訪問,所以存儲器訪問時序應盡可能的快;而同時又要考慮到由此帶來的穩定性問題
        存儲器地址分布
        一種典型的情況是啟動ROM的地址重映射。

        評論


        技術專區

        關閉
        主站蜘蛛池模板: 德令哈市| 南城县| 黄石市| 阿克陶县| 太白县| 南阳市| 大港区| 兴宁市| 洱源县| 乌苏市| 苏尼特左旗| 泾川县| 尚义县| 黎城县| 嘉兴市| 星座| 平山县| 长顺县| 渑池县| 兰西县| 宁河县| 普宁市| 宁波市| 洛南县| 商城县| 乌审旗| 忻城县| 襄垣县| 信丰县| 北川| 东至县| 静安区| 仪陇县| 东海县| 洞口县| 通道| 乌审旗| 安乡县| 陇南市| 区。| 静乐县|