45、und(未定义机器码)异常模式程序示例

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

1、硬件向量表

2、代码如下

(1)、增加一个异常打印函数printException.c。

#include <uart.h>

void printException(unsigned int cpsr, char *str)
{
    puts("Exception! cpsr = ");
    printHex(cpsr);
    puts(" ");
    puts(str);
    puts("\n\r");
}

(2)、在makefile添加它。

objs =  start.o  uart.o sdram.o main.o exception.o

(3)、修改start.S

_start:
    b reset  /* vector 0 : reset */
    b do_und /* vector 4 : und */

do_und:
    /* 执行到这里之前:
     * 1. lr_und保存有被中断模式中的下一条即将执行的指令的地址
     * 2. SPSR_und保存有被中断模式的CPSR
     * 3. CPSR中的M4-M0被设置为11011, 进入到und模式
     * 4. 跳到0x4的地方执行程序 
     */

    /* 因为cpu一上电是在管理模式下运行,sp_und未设置, 先设置它 */
    ldr sp, =0x34000000

    /* 在und异常处理函数中有可能会修改r0-r12, 所以先保存 */
    /* lr是异常处理完后的返回地址, 也要保存 */
    stmdb sp!, {r0-r12, lr}  
    
    /* 保存现场 */
    /* 处理und异常 */
    mrs r0, cpsr
    ldr r1, =und_string
    bl printException
    
    /* 恢复现场 */
    ldmia sp!, {r0-r12, pc}^  /* ^会把spsr的值恢复到cpsr里 */   
und_string:                       /* 定义一个字符串带\n */
    .string "undefined instruction exception"

reset:

在调用main函数前调用如下代码

bl uart0_init

    bl print1
    /* 故意加入一条未定义指令 */
und_code:
    .word 0xdeadc0de  /* 未定义指令 */
    bl print2

(4)、在uart.c添加打印调试的代码进去

void print1(void)
{
    puts("abc\n\r");
}

void print2(void)
{
    puts("123\n\r");
}

3、程序优化

(1)、防止程序超过4K,所以让他跳转到SDRAM中执行

ldr pc, und_addr /* vector 4 : und */

und_addr:
    .word do_und

ldr pc, =sdram
sdram:
    bl uart0_init

    bl print1
    /* 故意加入一条未定义指令 */
und_code:
    .word 0xdeadc0de  /* 未定义指令 */
    bl print2

4、程序的启动执行流程

猜你喜欢

转载自blog.csdn.net/qq_18077275/article/details/89306504
今日推荐