注:以下内容学习于韦东山老师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,