一.按键检测
1.硬件原理
当未按下按键时,GPIO_5为低电平,按下按键GPIO_5变为高电平。
根据引脚编号找到引脚名称
根据引脚名称找到引脚编号
裸机程序控制外设
特点:读数据手册、设寄存器值
- 找出外设有哪些相关寄存器
- 找出外设相关寄存器如何设置
二.中断检测
1.通用中断控制器(GIC)
GIC用于管理单核或多核芯片中的中断资源
- ARM公司开发了4 个版本GIC规范 ,V1~V4
- ARMv7-A内核搭配GIC-400使用(v2)
2.GIC结构
-
三类信号源:
- 软件中断:用于多核通信,ID0~ID15
- 私有中断:内核独有的中断,ID16~ID31
- 共享中断:所有内核共享的中断,ID32~ID1019
-
分发器:选择把中断信号发送到哪一个cpu接口单元
有哪些相关寄存器?
-
中断数量:GICD_TYPER
-
中断清除: GICD_ ICENABLERn
-
中断使能:GICD_ISACTIVERn
-
中断优先级设置:GICD_IPRIORITYR
-
-
cpu接口单元:处理信号后,发送信号给CPU
有哪些相关寄存器?
- 中断优先级数量:GICC_PMR
- 抢占优先级和子优先级设置: GICC_BPR
- 保存中断ID:GICC_IAR
- 通知cpu中断完成:GICC_EOIR
2.获取GIC基地址
方法一:查询芯片数据手册
方法二:查询cp15协处理器
共有16个:c0~c15。每个协处理器本身有多种含义,需逐步配置
//设置并读协处理器
MRC {cond} p15, <opc1>, <Rn>, <CRn>, <CRm>, <opc2>
//设置并写协处理器
MCR {cond} p15, <opc1>, <Rn>, <CRn>, <CRm>, <opc2>
- cond:执行条件,一般省略
- opc1:第一层设置
- Rn:通用寄存器
- CRn:要设置的协处理器
- CRm:第二层设置
- opc2:第三层设置
CBAR寄存器
CRn=c15,opc1=4,CRm=c0,opc2=0
- 查询GIC的地址
MRC p15, 4, r1, c15, c0, 0 ;获取 GIC 基地址
把c15配置成CBAR寄存器,此时成c15的值就是GIC的基地址。
SCTLR 寄存器
CRn=c1,opc1=0,CRm=c0,opc2=0
-
bit13:中断向量表基地址
-
cache\mmu\分支预测…
MRC p15, 0, <Rt>, c1, c0, 0 ;读取 SCTLR 寄存器,数据保存到 Rt 中。 MCR p15, 0, <Rt>, c1, c0, 0 ;将 Rt 中的数据写到 SCTLR(c1)寄存器中。
VBAR寄存器
CRn=c12,opc1=0,CRm=c0,opc2=0
- bit5~31:中断向量表偏移地址
MRC p15, 0, <Rt>, c12, c0, 0 ;读取 VBAR 寄存器,数据保存到 Rt 中。
MCR p15, 0, <Rt>, c12, c0, 0 ;将 Rt 中的数据写到 VBAR寄存器中。
2.中断向量表
一级查表
自动跳转指定位置(基址+偏移)
addr | TYPE | FUNCTION | MODE |
---|---|---|---|
0x00 | Reset | 复位中断 | SVC |
0x04 | Undefined instructions | 未定义指令中断 | Undef |
0x08 | Supervisor Call | 软中断 | SYC |
0x0C | Prefetch abort | 指令预取中止中断 | ABT |
0x10 | Data abort | 数据访问中止中断 | ABT |
0x14 | RESERVED | 未使用 | 未使用 |
0x18 | IRQ interrupt | IRQ 中断 | IRQ |
0x1C | FIQ interrupt | FIQ 中断 | FIQ |
通过触发不同类型的中断,系统进入到相应的运行模式
二级查表
预先注册、回调执行
3.中断处理流程
中断上下文
cpu通过内核寄存器来运行指令并进行数据的读写处理的,它在进入中断前一个时刻的具体值,称为中断上下文
具体流程
-
初始化irq模式栈指针
-
进入irq模式
- cpsr寄存器
-
保存现场
- 通用寄存器
- lr
- spsr
-
获取中断编号
- 读取GIC基地址
- GICC基地址(GIC cpu interface)
- GICC_IAR寄存器
-
执行中断处理函数
- 根据中断编号,回调IRQ中断服务表
-
还原现场
-
通用寄存器
-
lr
-
spsr
-
-
返回原程序
- 三级流水线
cpsr寄存器
- bit31:负数标记位
- bit30:零标志位
- …
- M[4:0]:运行模式控制位
- 10000:User 模式
- 10001:FIQ 模式
- 10010:IRQ 模式
- 10011:SVC模式
- 10111:Abort模式
- 11011:Undef模式
- 11111:System模式
- 10110:Monitor模式
- 11010:Hyp模式
mrs <Rt>,cpsr //读cpsr
msr cpsr,<Rt> //写cpsr
cps #xx //写立即数到cpsr中的M[4:0]
GICC基地址
4.1.3 CPU interface register ma (GIC官方手册)
三级流水线
- 取指令(pc)
- 译指令
- 执行指令
lr = pc = 当前执行指令+8
当前执行指令的下一条:lr-4
3.按键中断实验
GIC相关寄存器
-
分发器
- 中断数量:GICD_TYPER
- 中断清除: GICD_ ICENABLERn
- 中断使能:GICD_ISACTIVERn
- 中断优先级设置:GICD_IPRIORITYR
详见GIC官方手册
4.3 Distributor register descriptions
-
cpu接口单元
- 中断优先级数量:GICC_PMR
- 抢占优先级和子优先级设置: GICC_BPR
- 保存中断ID:GICC_IAR
- 通知cpu中断完成:GICC_EOIR
详见GIC官方手册
4.4 CPU interface register descriptions
GPIO中断相关寄存器
-
gpio中断触发类型:高/低电平、上升/下降沿
-
GPIO5_ICR1(0~15)
-
GPIO5_ICR2(16~31)
-
-
gpio中断屏蔽
- GPIO5_IMR
-
gpio中断状态寄存器
- GPIO5_ISR
-
gpio双边缘触发
- GPIO5_EDGE_SEL
详见芯片数据手册
28.5 GPIO Memory Map/Register Definition
中断服务函数表
记录每个IRQ中断的回调函数
-
函数指针
-
函数参数
中断向量表偏移位置
C语言读写cp15协处理器
__ASM ( code : 输出操作数列表 : 输入操作数列表 );
-
code
-
具体操作指令(字符串表示)
-
#
是把宏参数变为一个字符串 -
##
是把两个参数连接在一起
__STRINGIFY(p##coproc) ", ->“p15”
-
-
操作数
通过%加数字引用,比如%0 引用第一个操作数,%1 引用第二个操作数
r:将变量放入通用寄存器
4.位置无关码和重定位
程序执行和变量访问的两种方式:
- pc指针+偏移地址
- 绝对地址
位置无关码
没有出现绝对地址访问的代码称为位置无关码
- 普通.text段指令
- 局部变量
位置无关码可以在任意合法内存运行
位置相关码
出现了绝对地址访问的代码称为位置相关码
-
访问.data段:初始值非零的全局变量、静态变量
-
访问.rodata段:字符串、具有初始值的数组
-
访问.bss段:初始值为0的全局变量、静态变量
-
特殊.text段指令
汇编: ldr pc,=100000
c语言:(*(void(*)(void))0x100000)();
位置相关码必须在指定运行地址运行
重定位
在执行位置相关码之前,可以通过位置无关代码把位置相关码加载到位置相关代码的指定位置,如重定位.data段