S5P4418裸机开发(十):Undef异常处理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/M_N_N/article/details/82807683

上一帖总结了异常中断处理过程,当未定义指令异常发生时,PC最终会跳到0xFFFF0204,该地址上也是一条跳转指令。为了执行我们自定义的异常处理函数,让这条指令跳向我们的函数即可;

接着 5_lds 写;
在启动文件中加入一条未定义指令;

.text
.global _start

_start:                 // 地址 0x42C00000
    bl bss_init         // .bss段初始化
    .word 0xFFFF0000    // 无效指令,会产生Undef异常
    b main

为了能直观的看到效果,进入自定义函数后串口打印提示信息;

void except_und(){
    asm("stmdb sp!, {r0-r12, lr}\n");   // 保存现场,lr存的是产生undef异常的指令的下一条指令地址;
    uart0_init(115200);
    printf("Triggered undefined exceptions %d\r\n", 0);
    asm("ldmia sp!, {r0-r12, pc}^\n");  // 恢复现场,'^'表示恢复CPSR;
}

编译,查看反汇编文件可以得到函数except_und()的地址;

42c0016c <except_und>:
42c0016c:	e92d4800 	push	{fp, lr}
42c00170:	e28db004 	add	fp, sp, #4
42c00174:	e92d5fff 	push	{r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip, lr}
42c00178:	e3a00cc2 	mov	r0, #49664	; 0xc200
42c0017c:	e3400001 	movt	r0, #1
42c00180:	eb00032f 	bl	42c00e44 <uart0_init>
42c00184:	e301057c 	movw	r0, #5500	; 0x157c
42c00188:	e34402c0 	movt	r0, #17088	; 0x42c0
42c0018c:	e3a01000 	mov	r1, #0
42c00190:	eb0002d6 	bl	42c00cf0 <printf>
42c00194:	e8fd9fff 	ldm	sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip, pc}^
42c00198:	e8bd8800 	pop	{fp, pc}

得到了要跳转的地址,将0x42c0016c赋值给PC,要占用两条指令的位置,0xFFFF0204处可以修改为装载指令,0xFFFF0214是一个保留地址,未使用,可以将要跳转的地址放在这里;

  1. 生成具体的二进制数据;
    ldr pc, =0x42c0016c
    .word 0x00000000
    .word 0x00000000
    .word 0x00000000

结果

FFFF0204:	e59ff008 	ldr	pc, [pc, #8]	; 42c0001c <__TEXT_START+0x1c>
	...
FFFF0214:	42c0016c 	sbcmi	r0, r0, #108, 2
  1. 用WinHex修改SD卡数据,拷贝main.bin
    在这里插入图片描述

上电
在这里插入图片描述
输出了提示信息;

CPU执行流程:

42c00000 <__TEXT_START>:	// 裸机程序开始地址
42c00000:	eb000029 	bl	42c000ac <bss_init>
42c00004:	ffff0000 			; <UNDEFINED> instruction: 0xffff0000
42c00008:	ea000047 	b	42c0012c <main>
...
42c0016c <except_und>:			// Undef异常处理函数
42c0016c:	e92d4800 	push	{fp, lr}
42c00170:	e28db004 	add	fp, sp, #4
42c00174:	e92d5fff 	push	{r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip, lr}
42c00178:	e3a00cc2 	mov	r0, #49664	; 0xc200
42c0017c:	e3400001 	movt	r0, #1
42c00180:	eb00032f 	bl	42c00e44 <uart0_init>
42c00184:	e301057c 	movw	r0, #5500	; 0x157c
42c00188:	e34402c0 	movt	r0, #17088	; 0x42c0
42c0018c:	e3a01000 	mov	r1, #0
42c00190:	eb0002d6 	bl	42c00cf0 <printf>
42c00194:	e8fd9fff 	ldm	sp!, {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl, fp, ip, pc}^
42c00198:	e8bd8800 	pop	{fp, pc}

当CPU执行到42c00004时产生Undef异常,PC跳到0x34000004(IROM),然后跳到0xFFFF0004(NSIH),然后跳到0xFFFF0204(2NBOOT)
0xFFFF0204是我们修改后的指令,PC再跳自定义的异常处理函数0x42c0016c,先保存现场,处理完后恢复现场,再回到异常指令的下一条指令,即main();

工程代码

6_Undef_except

猜你喜欢

转载自blog.csdn.net/M_N_N/article/details/82807683