Linux驱动学习day22(interrupt子系统)

一、中断和异常的概念

中断属于一种异常。

二、ARM对异常(中断)的处理流程

1、初始化中断:a. 设置中断源,让它可以产生中断。b. 设置中断控制器(屏蔽、优先级)。c. 设置CPU总开关(使能中断)。

2、执行程序。

3、产生中断(按下按键-->中断控制器-->cpu,cpu每执行完一段指令都会检查有无异常产生-->有异常开始处理,对于不同的异常cpu会跳去不同的地址执行程序(这些地址上只是一条跳转指令,跳去执行其他指令)(这些地址是一块的,叫做异常向量))

3、 跳转到的函数处理中断:保存现场(各种寄存器),分辨中断,处理异常(中断),恢复现场。

2.1 中断处理流程图

2.2 进程、线程、中断的核心是栈

ARM芯片属于精简指令集计算机(RISC:ReducedInstructionSetComputing),它所用的指令比较简单,有如下特点:

①对内存只有读、写指令

②对于数据的运算是在CPU内部实现

③使用RISC指令的CPU复杂度小一点,易于设计

很多内容与之前的(博客重复了,Linux驱动学习day9(异常与中断处理)-CSDN博客),这里不再赘述。只记录新内容。

2.3 设备树中使用中断号

2.4 设备树中指定中断控制器

三、GIC介绍分析

ARM体系结构定义了通用中断控制器(GIC),该控制器包括一组用于管理单核或多核系统中的中断的硬件资源。GIC提供了内存映射寄存器,可用于管理中断源和行为,以及(在多核系统中)用于将中断路由到各个CPU核。它使软件能够屏蔽,启用和禁用来自各个中断源的中断,以(在硬件中)对各个中断源进行优先级排序和生成软件触发中断。它还提供对TrustZone安全性扩展的支持。GIC接受系统级别中断的产生,并可以发信号通知给它所连接的每个内核,从而有可能导致IRQ或FIQ异常发生。

3.1 GIC主要功能和模块

distributor(分发器):各种中断发送到GIC中,由 distributor判断优先级最高的中断发送到CPU interface中再发给CPU。CPU之间的通信也要经过该模块,CPU0发出SGI(软件产生的中断)信号,由GIC发送给另一个CPU。

GIC可以处理多种中断,比如PPI各个GPU自己私有的外部设备中断,SGI软件产生的中断(用于CPU之间的通信),SPI共享外部设备发出的中断(可以到达任意CPU)。GIC给每个中断分配了各个中断号,SPI范围是32-1019等等。

3.2 中断的状态

① 非活动状态(Inactive)-这意味着该中断未触发。

② 挂起(Pending)-这意味着中断源已被触发,但正在等待CPU核处理。待处理的中断要通过转发到CPU接口单元,然后再由CPU接口单元转发到内核。

③ 活动(Active)-描述了一个已被内核接收并正在处理的中断。

④ 活动和挂起(Active and pending)-描述了一种情况,其中CPU核正在为中断服务,而GIC又收到来自同一源的中断。

中断的优先级和可接收中断的核都在分发器(distributor)中配置。外设发给分发器的中断将标记为pending状态(或ActiveandPending状态,如触发时果状态是active)。distributor确定可以传递给CPU核的优先级最高的pending中断,并将其转发给内核的CPU interface。通过CPUinterface,该中断又向CPU核发出信号,此时CPU核将触发FIQ或IRQ异常。

作为响应,CPU核执行异常处理程序。异常处理程序必须从CPUinterface寄存器查询中断ID,并开始为中断源提供服务。完成后,处理程序必须写入CPUinterface寄存器以报告处理结束。然后CPUinterface准备转发distributor发给它的下一个中断。在处理中断时,中断的状态开始pending,active,结束时变成inactive。中断状态保存在distributor寄存器中。

3.3 中断发生和处理过程

3.4 异常向量表初始化和映射

3.5 GIC驱动程序对中断的处理流程

3.5.1 老版本内核

3.5.2 新版本内核

3.5.2.1 一级中断处理流程

在新版本内核中,不像老的版本内核,对于虚拟中断号是用到时分配,比如说GIC32硬件中断号上挂了一个UART模块,当uart产生中断,会去寻找没有使用的irq_desc,如下图所示16号是空的,所以16号irq被注册成uart中断,建立hwirq和virirq的映射关系(32 , 16)保存到GIC 中的irq_domain中。当32号产生中断由GIC发送给CPU,CPU会来读GIC的寄存器确定是哪一个中断号产生的中断,读寄存器发现是32号产生的中断于是去irq_domain找到映射关系找到irq_desc虚拟中断号的结构体,调用GIC_handle函数屏蔽其他中断,调用该函数提供的中断处理函数,之后清除中断。

3.5.2.2 二级中断处理流程

当在33号硬件中断下挂有GPIO模块,系统会在irq_desc数组中找到空的irq_desc存放这个GPIO中断的结构体,并将虚拟中断号和硬件中断号的联系放入GIC irq_domain中,由于GPIO模块中含有4个引脚,因此也会为4个引脚设置vir中断号,并记录在GPIO irq_domain(GPIO模块也是一个中断控制器)中。

按键2产生了中断,会有GPIO发送给GIC然后GIC发送给CPU,CPU跳到异常向量表中的irq指令,去读取GIC的寄存器,发现是33号硬件中断,找到domain中虚拟中断和硬件中断的关系,发现是17号虚拟中断,于是执行17号irq_desc中的handle函数,该函数去屏蔽33号硬件中断,读取GPIO控制器中的寄存器,发现是2号硬件中断,从 GPIO irq_domain找到其虚拟中断号,调用102个irq_disc函数中的handle函数(屏蔽中断,执行funckey函数,清除中断),最后清除中断。

四、GIC中的重要数据结构

GIC的功能主要是:可以使能、屏蔽中断,发生中断时可以从GIC里判断是哪个中断。

在内核中使用gic_chip_data结构体表示GIC。

借助下面这张图来理解结构体里面的内容:

a、当发生UART中断的时候,GIC发送中断给CPU,CPU跳到异常向量表中的跳转指令去使用handle函数来读取GIC寄存器,该函数由GIC提供。

b、知道是32号硬件中断产生的中断,会从GIC_domain中取出硬件中断和虚拟中断号的关系,得到虚拟中断号。该结构体也由GIC提供。

c、从GIC_domain得到关系之后,可以去到相应的虚拟中断号的irq_desc结构体中执行handle函数屏蔽中断,调用中断处理函数irqaction(用户提供),清理中断。handle函数由GIC提供,并且屏蔽中断和清理中断的函数在irq_data中的irq_chip中,也由GIC提供。

先更新到这,后天继续加油!

相关推荐
西岸行者7 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意7 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码7 天前
嵌入式学习路线
学习
毛小茛7 天前
计算机系统概论——校验码
学习
babe小鑫7 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms7 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下7 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。7 天前
2026.2.25监控学习
学习
im_AMBER7 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J7 天前
从“Hello World“ 开始 C++
c语言·c++·学习