ARM架构学习6.2——中断理解
一、中断
1. 按键硬件与 GPIO 基础配置
1.1文件:
KEY:作为接收高低电平的信号
引脚的名字(用外设功能命令)
1.2看
1.3GPIO的引脚功能:
直奔两个寄存器映射表:IO复用设置——找
key引脚用于io,因此找是否有用于io的,发现了(0101 ALT5 — Select mux mode: ALT5 mux port: GPIO1_IO18 of instance: gpio1)
对gpio来说 sion无所谓
1.4电气特性配置中
keyGPIO作为输入,来配置一下电气属性
16施密特触发器、实时比较器(HYS)可以消除毛刺,增加了之后,实时性降低
15-14PUS 阻值配置 (上拉电阻、下拉电阻,不成文的规则:10K电阻)
13PUE 模式选择(输入选保持or上拉模式)(上拉 1)
12PKE(使能)上拉使能
11 ODE 开漏还是推挽使能(推挽高低电平就可以)
7-6采样速率(中速 100mhz)
5-3DSE(不用动)
1111 0000 1011 0000 F0B0
按键外设配置与实现总结:
- 按键电路通过上拉电阻设计,按键按下时引脚被拉低至GND,形成低电平有效信号。
- 引脚复用功能需配置为GPIO模式(MUX设置为0101),并启用内部上拉电阻(PUE=1, PUS=1)。
- 电气特性配置中选择22K上拉电阻(对应值F0B0),速度设为中速(100MHz),输入模式下DSE无需配置。
- GPIO方向寄存器(GDIR)需将对应位清零以设置为输入模式,通过DR寄存器读取引脚电平状态。
2轮询方式的问题分析
- 当前采用while循环持续检测按键状态的轮询方式存在响应延迟和事件漏检的风险。
- 在复杂业务场景中,若主循环执行耗时操作(如延时或传感器读取),可能导致无法及时响应按键动作。
- 轮询机制占用CPU资源,不适合处理高实时性要求的事件,尤其在安全关键系统中不可接受。
- 实时性要求高立即处理的项目:不能内核来一个个检查 GPIO18引脚是否变化,需要GPIO18引脚变化上报给内核——中断。高实时场景:必须“引脚变化 → 立即上报内核” → 中断机制
中断流程:
外设产生中断、GIC控制器、内核处理中断
1发出中断:中断源发出请求
2内核检查中断是否被屏蔽:
3中断优先级判断
4保护现场
5中断优先级判断
6恢复现场
3中断机制引入与GIC架构
- 中断机制允许外设主动通知CPU处理紧急事件,避免CPU持续轮询,提升系统效率和响应速度。
- GIC(通用中断控制器)作为ARM架构的核心组件,负责管理多个中断源的优先级、屏蔽和分发。
- GIC支持SPI(共享外设中断)、PPI(私有外设中断)和SGI(软件中断)三类中断,范围为0-1019号。
- 多核系统中GIC通过分发器决定中断应送达哪个处理器核心,单核系统则固定发送至CPU0。
4GIC控制器:(有专门的手册:ARM Generic Interrupt Controller(ARM GIC控制器)V2.0.pdf)
中断通知寄存器 IAR:(判断是谁产生的中断)
中断结束寄存器 EOIR(把中断标志位清理 写1清除)
4协处理器coprocessor
- CP0-CP15
- 浮点型运算cp10 cp11
- cp15协处理器是GIC地址总线的地址存放(专门的手册Cortex-A7 Technical ReferenceManua.pdf)
协处理器与系统控制
- GIC控制器基地址不公开,需通过协处理器CP15的CBAR寄存器获取其挂载地址。
- CP15协处理器负责管理系统级功能,包括MMU、cache控制、异常向量表重映射等关键配置。
- 异常向量表基地址可通过VBAR寄存器重新定位,i-cache使能位(bit12)可控制指令缓存开关。
- 浮点运算由CP10/CP11协处理器处理,主内核本身不具备浮点计算能力。
CP15协处理器 有16组处理器:
4.1c0 里MIDR:主寄存器
寄存器把bit分为了五个域
4.2c1 的系统控制寄存器SCTLR:
可以通过V(0)改VBAR(之前上电默认为0)
VBAR:重定向后的异常向量表基地址(本质改的是PC寄存器上电后的初值)
icache :设1 使能 后面也有控制dcache的(icache开 dcache关闭)
CBAR 存放GIC基地址
5中断流程:
5.1中断源级配置(GPIO侧)
寄存器 功能 典型值/操作 ICR2 触发方式 bit4-5 = 11 → 下降沿 IMR 屏蔽解除 写 1 → 使能 ISR 状态查询 读 1 → 有事件;写 1 → 清标志
IMX6ULL 参考手册:
1ICR中断触发方式
- ICR0(0-15位)的状态:高电平、低电平、上升沿、下降沿等处理方式
- ICR1(16-31位)的状态:高电平、低电平、上升沿、下降沿等处理方式
- gpio18引脚处理ICR2中的bit4 和bit5 (11 表示下降沿触发)
2中断屏蔽寄存器解除IMR
允不允许中断从中断源发送出去?
中断掩码:1 使能 表示允许中断
3中断状态寄存器ISR (判断32位哪个位置的引脚为1 代表这个引脚产生中断)
中断有一千多个,从中断小组里区分中断,找到这个中断之后,要清除中断状态(置1)
5.2 GIC 控制器级流程(160个中断)
内部 外部(设备中断)
SGI(软件中断)和PPI(私有外设中断)和 SPI(共享外设终端)
16+16+(128个)=160个
中断号(99)先找到一个大组,中断号越小 中断优先级越高
可能是16-31之间任何的任何一个引脚产生的中断,如何区分那一个呢 是通过GPIO_ISR区分的
1获取基地址,基地址即GIC首地址 存在CP15协处理器里CBVR
基地址:mrc p15,4, r0, c15, c0, 0 (获取p15地址放入r0里面)
2GIC_Init 初始化GIC 分发器+CPU接口使能
使用函数:GIC_Init
2GIC中GIC_EnableIRQ(99)(GIC使能,传递中断号)
GIC_EnableIRQ(99)
3中断优先级配置SetPriortity(99,0) 数字越小越高
4中断通知寄存器 获取中断号
C_IAR地址:base+0x200C基地址+偏移量地址(基地址即GIC首地址 存在CP15协处理器里)
C_IAR:add r0, r0, #0x2000
ldr r1, [r0, #0x0C]
r0原本存放基地址,加了偏移量变成IAR地址
5中断结束寄存器:中断标志清理
C_EOIR地址 :base+0x2010 基地址+偏移量地址(基地址即GIC首地址 存在CP15协处理器里)
C_EOIR: ldr r1, [r0, #0x10]
r0原本存放基地址,加了偏移量变成EOIR地址
5.3内核级封装(C 语言)p15
1异常向量表基地址映射(顺手打开icache)
- 1先把 p15取出存入r0 mrc p15, 0, r0, c1, c0, 0
- 2把r0的bit13清零 bic r0, r0, #(1 << 13)//修改异常向量表映射方式
- 3orr r0, r0, #(1 << 12)//打开ICache
- 4再把p15 存入ro
- 设置初始基地址__get_VBAR(0x87800000);
2中断向量编写汇编向量入口
sub lr, lr, #4
+ 保存现场 → 跳 C 处理函数
获取基地址和中断通知寄存器地址和中断结束地址
(tip:sub lr,#4 IRQ 异常状态返回会偏移4个地址,提前给减掉)
3、编写irq中断服务函数(c语言)
- 注册向量表:传入中断号和中断服务函数(名字),存入异常向量表
- 中断向量表:160个中断向量表数组,每个元素为一种中断服务函数,名字+()直接调用
- 封装:封装GPIO以及封装中断