IMX6ULL裸機學習(10)— 未定義異常和SVC異常例項
阿新 • • 發佈:2021-01-11
技術標籤:IMX6ULL裸機
IMX6ULL裸機學習(10)— 未定義異常和SVC異常例項
一、未定義異常
未定義的指令異常就是 CPU 或協處理器不認識這條指令,執行這樣的指令時就會產生“未定義指令異常”。所以我們只要在程式中寫入一個不是指令的資料就可以產生未定義異常。
如下所示,使用.word
偽指令,可以在當前位置放一個word型的值,在imx6ull中,即一個32位資料
.word 0x12345678
然後我們修改start.s
檔案如下所示,其中其他幾個異常暫時沒有實現,先用0填充
.text /* .text段儲存程式碼,是隻讀和可執行的,後面的指令都屬於.text段。 */
.global _start /* .global表示_start是一個全域性符號,會在連結器連結時用到 */
_start: /* 標籤_start,彙編程式的預設入口是_start */
b reset /* 復位異常,復位後從這裡開始執行 */
ldr pc,=_undefined_instruction /* 未定義的指令異常,當cpu執行到不認識的指令時,會跳轉到這裡 */
.word 0 /* ldr pc,=_software_interrupt /* 軟中斷異常,當cpu執行svc指令時,會跳轉到這裡 */
.word 0 /* ldr pc,=_prefetch_abort /* 預取中止異常,處理器預取指令的地址不存在,或不允許當前訪問時 */
.word 0 /* ldr pc,=_data_abort /* 資料中止異常,處理器資料訪問指令的地址不存在,或不允許當前訪問時 */
.word 0 /* ldr pc,=_not_used /* 未使用,預留的地址 */
.word 0 /* ldr pc,=_irq /* 中斷請求有效,且CPSR中的I位(即中斷遮蔽位)為0時,產生IRQ異常 */
.word 0 /* ldr pc,=_fiq /* 快速中斷請求有效,且CPSR中的F位(即快中斷遮蔽位)為0時,產生FIQ異常 */
reset:
/* 1、設定棧 */
ldr sp, =(0x80000000+0x100000) /* 設定棧頂地址 */
/* 2、設定異常向量表基地址 : VBAR */
ldr r0, =_start
mcr p15, 0, r0, c12, c0, 0
/* 3、清除bss段 */
ldr r1, =__bss_start /* 將bss段開始地址存入r1暫存器 */
ldr r2, =__bss_end /* 將bss段結束地址存入r2暫存器 */
b clean_bss
clean:
mov r3, #0 /* 將0存入r3暫存器 */
str r3, [r1], #4 /* 將r3中的值存到r1中的值所指向的地址中, 同時r1中的值加4 */
clean_bss:
cmp r1, r2 /* 比較r1和r2內的值是否相等 */
bne clean /* 如果不相等則跳轉到clean標籤處,如果相等則往下執行 */
/* 4、呼叫系統初始化函式,在異常處理函式中需要用到uart功能,需要先初始化uart */
bl SystemInit
/* 5、寫入一個未定義指令 */
.word 0xffffffff
/* 6、跳轉到led函式 */
bl main
/* 7、原地迴圈 */
b .
_undefined_instruction:
/* 1、設定Undefined模式下的棧 */
ldr sp, =(0x80000000+0x50000)
/* 2、儲存現場 */
stmdb sp!, {r0-r12,lr}
/* 3、呼叫處理函式 */
bl do_undefined_c
/* 4、恢復現場 */
ldmia sp!, {r0-r12,pc}^
修改main.c
檔案如下所示
#include "uart.h"
#include "led.h"
void SystemInit(void)
{
uart_init();
}
int main(void)
{
led_init();
putstring("imx6ull\r\n");
while(1)
{
putstring("led on\r\n");
led_on();
delay(1000000);
putstring("led off\r\n");
led_off();
delay(1000000);
}
}
void do_undefined_c(unsigned int lr)
{
putstring("Exception: undefinedinstruction.\r\n");
}
接下來make編譯,然後燒錄到開發板,執行,列印如下所示