第8课,arm架构的异常与中断

本文详细介绍了ARM架构下的异常和中断处理流程,包括软件初始化、异常种类、CPU模式与状态,特别是对未定义指令模式和SWI指令的处理。在异常处理中,硬件会保存现场并切换模式,而在退出异常时恢复现场。通过示例,解释了如何在异常模式下改进程序以避免错误和提高效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

注:以下内容学习于韦东山老师arm裸机第一期视频教程


一.arm架构的异常与中断的处理

   1.1 ARM对异常的处理流程

        1.1.1 软件初始化
            a. 设置中断源,让他可以产生中断
            b. 设置中断优先级
            c. 设置中断总开关
            
        1.1.2 正常执行程序

            对于不同的异常跳去不同的地址执行程序(这些地址一般是排在一起的,叫做异常向量),

           这些地址上只是一条跳转指令,跳去执行其它函数,如下表

        

        1.1.6 这些函数做什么事情?

            a.保存现场(各种寄存器)
            b.调用不同的处理函数
                分辨中断源
                调用不同处理函数
            c.恢复现场
            

    1.2 ARM异常种类

        在uboot 1.1.6中有如下代码

            _start:    b       reset            /* 0地址,复位异常 */
            ldr    pc, _undefined_instruction  /* 4地址,未定义指令 */
            ldr    pc, _software_interrupt        /* 8地址,软中断指令 */
            ldr    pc, _prefetch_abort            /* 12地址,指令预取异常,如果处理器预取的指令不存在,或者该地址不允许当前指令访问 */
            ldr    pc, _data_abort                /* 14地址,数据访问终止,如果数据访问指令的目标地址不存在,或者该地址不允许当前指令访问 */
            ldr    pc, _not_used
            ldr    pc, _irq                    /* 24地址,中断异常 */
            ldr    pc, _fiq                    /* 28地址,快中断异常 */

        _undefined_instruction:    .word undefined_instruction
        _software_interrupt:    .word software_interrupt
        _prefetch_abort:    .word prefetch_abort
        _data_abort:        .word data_abort
        _not_used:        .word not_used
        _irq:            .word irq
        _fiq:            .word fiq

        中断发生时CPU会强制调到0x18(24)的地方,然后跳转到其它函数进行处理

        

二.CPU模式与状态

    2.1 CPU的State

        2.1.1 ARM State

              在这种状态下,使用arm指令集,每个指令占据4字节(被编译成的机器码占据4个字节)

        2.1.2 Thumb State

              在这种状态下,使用thumb指令集,每个指令占据2字节(被编译成的机器码占据2个字节)

              thumb指令集是arm指令集压缩形式的子集,thumb更加高效,可以减少存储空间,对于嵌入式系统nor,sdram很大,不需要节省这点空间

              Thumb 不是一个完整的体系结构,不能指望处理只执行Thumb 指令而不支持 ARM 指令集.因此,Thumb 指令只需要支持通用功能,必要时可以借助于完善的 ARM 指令集

        
        2.1.3 将一个程序使用Thumb编译示例

            对于C程序,在编译时添加-mthumb即可

                修改Makefile如下:

                    objs = uart.o main.o start.o SetTacc.o my_printf.o lib1funcs.o init.o
                    A = test

                    all:$(objs)
                        #arm-linux-ld -Ttext 0 -Tdata 0x800 $^ -o $(A).elf
                        arm-linux-ld -T sdram.lds $^ -o $(A).elf
                        arm-linux-objcopy -O  binary -S $(A).elf $(A).bin
                        arm-linux-objdump -D  $(A).elf > $(A).dis
                        
                    %.o:%.c
                        arm-linux-gcc -mthumb -c -o $@ $<
                        
                    %.o:%.S
                        arm-linux-gcc -c -o $@ $<
                        
                    clean:
                        rm *.o *.elf *.bin

            对于.S程序,需要在代码中指定,在前面添加.code 32表示后续的指令使用arm指令集,在sdram_init前面添加.code 16表示下面的都使用thumb指令集,在前面需要使用bx指令进行状态切换,bx跳转的地址bit0等于1时就会进行状态的切换

            代码如下:

                .text
                .code 32        /* 表示下面的代码使用arm指令集 */
                .global _start

                _start:
                    /* 省略一些初始化代码 */
                    
                    /* 获得thumb_func地址 */
                    adr r0, thumb_func
                    /* 由于地址是4字节对齐,最后一位等于0,因此设置最后一位等于1,切换到thumb指令集 */
                    add r0, r0,#1
                    bx r0

                .code 16        /* 表示下面的代码使用thumb指令集 */
                thumb_func:
                    bl SdramInit

                    mov r0, #0
                    ldr r1, =_start
                    ldr r2, =bss_start
                    sub r2, r2, r1
                    bl Copy2Sdram
                

                    ldr r0, =bss_start
                    ldr r1, =bss_end
                    bl CleanBss
                    
                    //bl main
                    //ldr pc, =main
                    /* 对thumb指令无法直接执行ldr pc, =main */
                    ldr r0, =main
                    mov pc,
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值