文章目录
LED灯
linux_bsp/board_driver/1.ledc
GPIO中断
中断相关概念
IRQ中断简介
Cortex-A内核CPU的所有外部中断都属于IRQ中断,任意外部中断发生都会出发IRQ中断,在中断服务函数中需要判断到底是哪个中断发生。
一共有七种中断:
①、复位中断(Rest),CPU 复位以后就会进入复位中断,我们可以在复位中断服务函数里面
做一些初始化工作,比如初始化 SP 指针、DDR 等等。
②、未定义指令中断(Undefined Instruction),如果指令不能识别的话就会产生此中断。
③、软中断(Software Interrupt,SWI),由 SWI 指令引起的中断,Linux 的系统调用会用 SWI
指令来引起软中断,通过软中断来陷入到内核空间。
④、指令预取中止中断(Prefetch Abort),预取指令的出错的时候会产生此中断。
⑤、数据访问中止中断(Data Abort),访问数据出错的时候会产生此中断。
⑥、IRQ 中断(IRQ Interrupt),外部中断,芯片内部的外设中断都会引起此中断的发生。
⑦、FIQ 中断(FIQ Interrupt),快速中断,如果需要快速处理中断的话就可以使用此中断。
GIC中断控制器
简介
ARMV7-A使用的中断控制器是GIC V2
GIC控制器接收众多外部中断,再通过四个信号报给ARM内核。
上报给ARM内核的四个信息分别为:
VFIQ :虚拟快速FIQ
VIRQ :虚拟外部IRQ
FIQ :快速中断IRQ
IRQ:外部中断IRQ
总体框架图
GIC 将众多的中断源分为三类:
①、SPI(Shared Peripheral Interrupt),共享中断,所有 Core 共享的中断,这个是最常见的,那些外部中断都属于 SPI 中断。比如按键中断、串口 中断等等,这些中断所有的 Core 都可以处理,不限定特定 Core。 中断ID32~ID1019。
②、PPI(Private Peripheral Interrupt),私有中断, GIC 是支持多核的,每个核有自己独有的中断。这些独有的中断要指定的核心处理,因此这些中断就叫做私有中断。 中断ID16~ID31。
③、SGI(Software-generated Interrupt),软件中断,由软件触发引起的中断,通过向寄存器GICD_SGIR 写入数据来触发,系统会使用 SGI 中断来完成多核之间的通信。中断ID0~ID15。
IMX6ULL 中断源ID对照
GIC逻辑分块
GIC架构分为两个逻辑块,Distributor 和 CPU Interface,分发器端和接口端。
Distributor(分发器端) :负责处理中断事件的分发问题,即中断时间发送到哪个interface上,并控制将优先级最高的中断,发送到CPU接口端。
①、全局中断使能控制。
②、控制每一个中断的使能或者关闭。
③、设置每个中断的优先级。
④、设置每个中断的目标处理器列表。
⑤、设置每个外部中断的触发模式:电平触发或边沿触发。
⑥、设置每个中断属于组 0 还是组 1。
CPU Interface(CPU 接口端) :CPU 接口端 就是分发器和 CPU Core 之间的桥梁,每个 CPU Core 都可以在 GIC 中找到一个与之对应的 CPU Interface。
①、每个 CPU Core 都可以在 GIC 中找到一个与之对应的 CPU Interface。
②、应答中断。
③、通知中断处理完成。
④、设置优先级掩码,通过掩码来设置哪些中断不需要上报给 CPU Core。
⑤、定义抢占策略。
⑥、当多个中断到来的时候,选择优先级最高的中断通知给 CPU Core。
CP15协处理器
中断使能及优先级设置
总中断使能
程序状态寄存器CPSR的I = 0时,使能IRQ,I=1时禁止IRQ
F=0时使能FIQ,F=1禁止FIQ。
也可以使用指令完成使能与禁止
具体中断ID使能
GIC 寄存器 GICD_ISENABLERn 和 GICD_ ICENABLERn 用来完成外部中断的使能和禁止,共有16组,完成对512个中断ID的控制。
其中 GICD_ISENABLER0 的 bit[15:0]对应 ID15~0 的 SGI 中断,GICD_ISENABLER0 的 bit[31:16]对应 ID31~16 的 PPI 中断。剩下的GICD_ISENABLER1~GICD_ISENABLER15 就是控制 SPI 中断的。
中断优先级设置
中断优先级分为抢占优先级和子优先级,GIC控制器的这些寄存器决定中断优先级相关设置。
GICC_PMR寄存器:决定使用几级优先级
** GICC_BPR 寄存器 :决定抢占优先级和子优先级占用位数**
** D_IPRIORITYR 寄存器:决定优先级**
32位优先级是,则使用7:3区间代表优先级,设置时需要左移三位。
GICD_IPRIORITYR[40] = 5 << 3; ///中断ID40,优先级设置为5
裸机(led、中断、定时器)->uboot->kernel->rootfs
裸机->设备驱动(包括各个子系统)->进程管理->文件系统->网络协议