基于IMX6ULL的Cortex-A中断原理讲解,以及编写其中断向量表

        首先借助STM32我们需要了解中断系统是如何构成的
        会有一个中断源,也就是能够向CPU发出中断请求的设备或事件。中断源不分硬件和软件,也就是产生中断信号,就会执行中断服务函数
        但是CPU是如何知道中断源产生后就找到对应的中断服务函数呢,这个时候就要引入中断向量表,它的主要功能是描述中断对应的中断服务函数,每个中断源都有一个唯一的中断号(也称向量号),CPU在接收到中断信号后,会读取中断号,并将其作为索引到中断向量表中查找对应的中断服务函数地址,找到地址后,CPU会跳转到该地址执行中断服务函数其实中断向量表类似于一张表格,表格是按照内存地址由低到高,里面的每一个地址都存放一个函数
        一般来说,中断向量表都是链接到代码的最前面,对于ARM处理器都是从0X00000000开始运行的。但是如下图博主截下来的图片可以看出在STM32中,设置的链接首地址被设置在0X8000000,所以中断向量表就无法正确的与中断服务函数对应
        针对于代码一定要从非0X000000的地方开始运行,那么就需要引入中断向量偏移这个概念

        通俗来讲就是将中断向量表移动到地址开始的地方,通过改变中断向量表在内存中的位置来避免冲突和限制,确保CPU能够正确地响应中断并执行相应的中断服务程序。
        STM32的中断向量偏移就是在这里设置的, 设置SCB的VTOR寄存器为新的中断向量表起始地址即可

        NVIC(内嵌向量中断控制器),简单来说就是中断的管理机构,这对于STM32这类 Cortex-M 内核的芯片,中断管理系统叫NVIC,但是在IMX6U中使用的是Cortex-A7内核的中断管理系统为GIC(general interrupt controller),待会儿会详细介绍
        中断服务函数就是产生中断后,会执行的额外操作

       

        那么对于STM32的中断有了大概的回顾过后,现在就要开始引入IMX6U也就是Cortex-A的内核下的中断系统,首先还是从中断向量表开始
        可以看到此内核有八个中断异常,但是其实严格来算只有7个。按照博主参考的教程上面说的是一款芯片有什么中断都是可以从中断向量表中看出来的,它和STM32有很大的区别在于,我们平时在看的时候,可以看到STM32有很多外设的中断,例如I2C,或者定时器,但是这里都没有,并不是我们的Cortex-A内核芯片只有这么几个中断

        主要是Cortex-A和Cortex-M内核芯片之间有很大的区别,对于STM32的内核来说,中断向量表中列举了一款芯片所有的中断向量,包括芯片外设的所有中断。对于Cortex-A内核CPU的所有外部中断都属于上面的IRQ中断,也就是外部中断模式,当任意一个外部中断产生的时候会触发IRQ中断。在IRQ中断服务函数里面就可以读取指定的寄存器来判断发生的具体是什么中断,更具具体的中断做出对应的处理,上面这段话博主也是从教程当中找到,并且理解到的,其中还附上了一张图,也能够较为直观的说明它们的关系

                

        在左侧列举出的所有中断,都是包含在IRQ中断中的IMX6U中断,不管左边图片中哪个中断被触发都会直接触发IRQ中断,所以需要在IRQ中断服务函数中判断究竟是左侧的哪个中断发生了,才能做出具体的处理

        在这里再依次介绍一下上面七种中断对应的意思:

1. 复位中断(Rest)CPU 复位以后就会进入复位中断,我们可以在复位中断服务函数里面 做一些初始化工作,比如初始化 SP 指针、DDR 等等

2. 未定义指令中断(Undefined Instruction) 如果指令不能识别的话就会产生此中断。

3. 软中断(Software Interrupt,SWI) 由 SWI 指令引起的中断,Linux 的系统调用会用 SWI 指令来引起软中断,通过软中断来陷入到内核空间。

4. 指令预取中止中断(Prefetch Abort) 预取指令的出错的时候会产生此中断。

5. 数据访问中止中断(Data Abort) 访问数据出错的时候会产生此中断。

6. IRQ 中断(IRQ Interrupt) 外部中断,前面已经说了,芯片内部的外设中断都会引起此 中断的发生。

7. FIQ 中断(FIQ Interrupt) 快速中断,如果需要快速处理中断的话就可以使用此中断。

        在上面的七个中断种,我们常用的也就是复位中断和IRQ中断,所以我们需要编写的就是这两个中断的中断服务函数

        在这里讲解完中断向量表后,在我们编写中断向量表后,按照前面的讲解,自然也是需要设置中断向量地址偏移的,毕竟我们代码链接的地址是0X87000000,所以需要偏移到这个地址的最上层

        讲解完中断向量表和地址偏移后,接下来就是中断控制器了,在STM32中叫做NVIC,但是在Cortex-A的内核中的中断控制器叫做GIC(Generic Interrupt Controller),按照博主参考的教程,GIC一共有四个版本,分别为V1、V2、V3、V4,但是由于V1非常古老,所以就废弃了,对于V3和V4来说是供64位芯片的使用,所以对于AEM架构来说合适的基本只有V2,所以主要讲解的也是GIC V2
        GIC V2 最多支持 8 个核。ARM 会根据 GIC 版本的不同研发 出不同的 IP 核,那些半导体厂商直接购买对应的 IP 核即可,比如 ARM 针对 GIC V2 就开发出 了 GIC400 这个中断控制器 IP 核。当 GIC 接收到外部中断信号以后就会报给 ARM 内核,但是 ARM 内核只提供了四个信号给 GIC 来汇报中断情况:VFIQ、VIRQ、FIQ 和 IRQ,关系图如下
        

        GIC 接收众多的外部中断,然后对其进行处理,最终就只通过四个信号 报给 ARM 内核,这四个信号的含义如下,VFIQ:虚拟快速 FIQ。 VIRQ:虚拟外部 IRQ。 FIQ:快速中断 IRQ。 IRQ:外部中断 IRQ。
        VFIQ 和 VIRQ 是针对虚拟化的,我们这里不讲解虚拟化,剩下的就是 FIQ 和 IRQ 了。我们只使用 IRQ,所以相当于 GIC 最终向 ARM 内核就上报一个 IRQ 信号。我们来看一下GIC的工作原理,也就是上报原理是什么

        ARM的cpu,特别是cortex-A系列的CPU,目前都是多core的cpu,因此对于多core的cpu的中断管理,就不能像单core那样简单去管理,由此arm定义了GICv2架构,来支持多核cpu的中断管理。,首先我们先看GIC控制器这个地方,首先GIC将众多的中断源分为三类

        1. SPI(Shared Peripheral Interrupt) 名为共享中断,所有的核心共享的中断,这个是最常见的,对于那些外部中断都属于SPI中断,例如三件中断,串口中断等,这些中断所有的核心都可以处理,不指定核心
        2. PPI((Private Peripheral Interrupt) 私有中断,在之前提到过,GIC是支持多核的,每个核都会有自己独有的中断。这些都有的中断肯定是需要指定对应的核心来处理,所以这些中断也叫做私有中断
        3. SGI(Software-generated Interrupt) 软件中断,由软件触发引起的中断,通过向寄存器 GICD_SGIR 写入数据来触发,系统会使用 SGI 中断来完成多核之间的通信。

        在使用GIC时,中断ID(interruput ID)是用来表示特定中断源的编号。每个中断源都有唯一的中断ID,用于区分不同的中断类型和源。GIC通过中断ID来管理路由中断
        通俗来讲也就是为了区分不同的中断,引入了中断号。中断源有很多,为了区分这些不同的中断源肯定要给它们分配一个唯一的ID,这些ID就是中断ID,每一个CPU最多支持1020个中断ID,在1020个中断ID中,包含了PPI、SPI、SGI,我们需要了解这三类中断源是如何分配这些ID的

        ID0-ID15是给SGI的,ID16-ID31是给PPI,剩余的ID32-ID1019给SPI,也就是按键中断等外部中断。这个ID有什么用呢?
        当时在前面也描述过,对于所有产生的外部中断触发都只有IRQ这个中断模式,而IRQ只有一个中断服务函数,所以需要在IRQ的中断服务函数中获取到触发当前中断的中断号,再次通过对应的中断号找到对应的中断处理函数
        在我们移植的NXP官方SDK库中的文件MCIMX6Y2C.h,在文件中定义了一个枚举类型IRQN_Type,此枚举类型就枚举出了IMX6U的所有中断,篇幅有限,就不全部截取了

        从上图以及下图,我么可以看到GIC架构分为了两个逻辑块:Distributor 和 CPU Interface,它们分别叫做分发器断和CPU接口端

        分发器(Distributor),此模块负责将中断进行优先级划分(prioritization)并且转发到指定的CPU interface中,与Distributor相关的寄存器均以GICD_作为前缀。Distributor在多处理器系统中的关键作用:它集中管理所有中断源,决定它们的优先级,并将优先级最高的中断有效地分发给系统中的各个CPU或核心
        其实简单来说,系统中所有的中断源都连接在分发器上,可以通过其中的仲裁单元控制中断源的属性,例如优先级,状态等,分发器把中断输出到CPU interface,后者决定将哪个中断转发给CPU核心
        分发器需要完成的主要工作包括   全局中断使能控制、控制每一个中断的使能或关闭、设置每个中断的优先级、设置每个中断的目标处理器列表、设置每个外部中断的触发模式:电平触发或边沿触发、设置每个中断组(例如Group0或者1),转发SGI中断到一个或者多个目标处理器等

        CPU接口单元 (CPU Interface),CPU核心通过控制器的CPU接口单元接收中断。CPU接口单元寄存器用于屏蔽,识别和控制和转发到CPU核心的中断的状态。系统中的每个CPU核心都有一个单独的CPU接口
        CPU核心都可以在GIC中找到一个对应的CPU Interface。它就是分发器和CPU核心之间的桥梁
        它的主要作用就是   使能或者关闭发送到CPU核心的中断请求信号、确认一个中断(也就是完成中断的应答),通知中断处理完成,设置优先级掩码,通过掩码来设置哪些中断不需要上报给CPU核心等

        整个中断的处理流程,首先是中断收集与缓存,当系统某个外设或设备产生中断信号的时候,GIC首先先收集这些中断请求。GIC内部的中断分分发器负责检测所有源的中断信号,并根据优先级等信息等中断进行管理,收集到的中断请求会被暂时缓存在分发器中,这些中断处于pending(等待中)的状态
        然后再进行中断优先级判断与选择,GIC的分发器会根据各个中断的优先级来决定哪些中断需要优先处理。分发器会选择优先级高低顺序,依次发送到处理器
        被选择的中断信号,GIC将中断请求通过CPU接口(GIC CPU Interface)发送到处理器,一般CPU接口寄存器保存了一个中断号,这个中断号对应的是当前需要处理的中断来源设备或外设,
此时,GIC将该中断的状态pending(等待中)变为active(处理中),意味着该中断正在进行处理
        GIC在后续将中断号发送到CPU接口,处理器通过读取AIR寄存器来获取中断号。每个产生中断的信号都会得到一个中断号,也就是他们的标识符,用于确定哪个外设或设备产生了中断
        读取完中断号后,每个中断号通常会在中断向量表中有一个对应的入口(其实一般就是地址),上面也说过了,中断向量表是处理器在处理中断时用来寻找对应,中断服务程序(ISR)的关键部分。包含了每个中断号对应的ISR的地址,处理器通过中断号查找中断向量表中对应的入口,找到中断服务程序的地址,一旦确定了ISR的入口地址,处理器通过跳转到该地址来执行相应的中断服务程序
        在完成跳转以后,开始执行中断服务程序(ISR),ISR会根据中断号的类型执行一系列处理步骤,例如读取外设状态、进行数据传输、清楚外设的中断标志等。ISR在执行期间,中断状态保持为active,表示当前中断正在处理,但是这里做一点提示,ISR通常应该尽量短小,以便快速完成,避免其他中断被长时间延迟处理。复杂的处理可以推迟到非中断的时候进行
        当CPU完成中断服务程序的处理后,它需要通知GIC该中断已经处理完毕。这是通过写入结束中断寄存器(EOI,End of Interrupt Register)来完成的。在完成中断处理后,CPU将该中断号写入GIC的EOI寄存器,通知GIC该中断已经完成,可以清除该中断状态。
        GIC收到处理器的EOI信号后,GIC会将该中断的状态从active状态清除,并将其重置为**idle(空闲)**状态,表示该中断处理已完成,系统可以再次接收该中断的请求。如果还有其他等待处理的中断,GIC分发器会继续根据优先级选择下一个中断请求,并重复上述过程。
        

        在最后,如果在处理中断A时,又有更高优先级的中断B产生,GIC会中断当前的中断服务程序,处理优先级更高的中断。这称为中断嵌套。处理器会保存当前中断的状态,转而处理新的高优先级中断。完成后,再恢复并继续处理原始的中断。
        但是,在我们多核处理器(MPU)中,多数多是使用的GIC中断控制器,一般来说是不需要频繁的使用中断嵌套的,多加个的一个显著优势就是可以通过并行处理,也就是多个核心同时份工作,来分担工作负载
        因为多核架构的并行性,允许多个CPU核心并行处理不同的任务或中断。当有多个中断请求时,GIC可以将不同的中断分配给不同的核心处理器,这样每个核心可以独立处理其分配的中断,而不会出现中断嵌套的情况。例如,GIC可以将优先级较高的中断分配给一个核心,而将低优先级的中断分配给另一个核心。这样即便是多个高优先级中断发生,也可以同时在不同的核心上得到处理,而无需打断正在处理的其他中断。
        中断的分发机制,在多核系统中,GIC通过其分发器可以将中断请求发送给多个CPU接口。每个CPU接口负责一个核心,这样就可以在不同的核心上并行处理中断,而不是依赖单个核心去处理所有中断。GIC Distributor能够对中断进行智能分发。它根据中断的类型、优先级以及核心的负载情况,将中断发送到合适的核心处理器。这减少了单核系统中频繁嵌套中断的需求。
        以及考虑到中断嵌套的成本来说,中断嵌套会增加上下文切换的开销。在单核处理器中,嵌套中断会导致处理器频繁保存和恢复中断处理上下文,这不仅消耗时间,还会增加栈的使用量,影响系统性能。

        所以对于多核系统来说,中断分发中断分发的机制主要有以下几种方式,进一步减少了对中断嵌套的需求,某些中断可以被配置为始终发送到特定的核心处理器进行处理。这样,系统可以将常见的中断集中到少数核心上处理,而其他核心专注于执行应用程序或其他任务。
        GIC可以采用轮询机制,将中断轮流分配到各个核心处理器。这样即便多个中断同时发生,也可以平衡地分配给各核心进行处理。
        系统可以静态也可以动态,对于静态来说系统,可以配置某些中断源始终由某个特定的核心处理器处理,这样可以减少动态分配时带来的负载不平衡和开销。静态分配的中断一般不会产生嵌套的需求,因为核心只负责处理它指定的中断。
        动态的情况,系统可以根据核心的负载情况动态分配中断。比如,当某个核心负载较低时,GIC可以将更多的中断发送到该核心进行处理,而不是让所有中断集中在一个核心上,从而避免过多的中断嵌套。

        虽然多核系统中频繁的中断嵌套并不常见,但在某些情况下,嵌套中断仍然是有用的,单个核心上处理优先级极高的中断:如果一个核心在处理较低优先级的中断时,发生了极高优先级的中断请求,系统可能仍然需要抢占低优先级中断来处理更重要的任务。这通常是非常重要的实时系统设计中的需求。在多核处理器中的某些实时任务场景,某些高优先级的中断不能延迟处理,此时可能会允许嵌套高优先级的中断。
        总之在多核处理器系统中,使用GIC可以通过并行处理中断,显著减少对中断嵌套的需求。GIC通过中断分发器可以将不同的中断分配给多个核心,充分利用多核架构的并行性,避免频繁的上下文切换和中断嵌套带来的性能损耗。不过,特定情况下(如实时性要求很高的场景),嵌套中断仍然可能被使用,但总体来说,多核系统能够有效地降低对复杂中断嵌套的依赖。

        下一讲我们就开始具体实验的讲解了,第一步肯定就是编写中断向量表了,基本原理就讲到这里了

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/418311.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

springboot+vue+mybatis智慧篮球馆预约+PPT+论文+讲解+售后

近些年来,随着科技的飞速发展,互联网的普及逐渐延伸到各行各业中,给人们生活带来了十分的便利,智慧篮球馆预约利用计算机网络实现信息化管理,使整个智慧篮球馆预约的发展和服务水平有显著提升。 本文拟采用Eclipse开发…

玄机科技《师兄啊师兄》——动漫宇宙里绽放“黑神话”之光!

当国产3A游戏《黑神话:悟空》以其对中国文化的深情致敬与精湛呈现,点燃了全球玩家们心中的文化之火,震撼游戏界时,独属于动漫界的“黑神话”——玄机科技以科技之名,行文化之实,将这股文化热潮延伸至动漫领…

[羊城杯 2021]Ez_android-快坚持不下去的第五天

找到mainactivity函数 1. 用户名和密码的检查 2. 密码的加密然后 - 1 的操作 for (int i 0; i < bArr.length; i) {bArr[i] (byte) (bArr[i] - 1); } 这段代码通过遍历字节数组中的每个元素&#xff0c;将每个元素的值减去 1&#xff0c;并更新数组。这里的 byte 强制转…

LLM Attention and Rotary Position Embedding(旋转位置编码)

旋转位置编码&#xff08;Rotary Position Embedding&#xff0c;RoPE&#xff09;是一种能够将相对位置信息依赖集成Attention计算里的方法。就是在做词表映射的时候不是单一的进行一个embedding计算&#xff0c;还考虑位置信息。 一些资料 [1] https://arxiv.org/pdf/2104.0…

2024全国大学省数学建模竞赛A题-原创参考论文(部分+第一问代码)

一问题重述 1.1 问题背景 "板凳龙"&#xff0c;又称"盘龙"&#xff0c;是浙闽地区的传统地方民俗文化活动。这种独特的表演艺术形式融合了中国传统龙舞的精髓和地方特色&#xff0c;展现了人们对美好生活的向往和对传统文化的传承。 在板凳龙表演中&am…

版本控制系统Git/Gitlab/GitHub

版本控制系统 git和svn:公司内部的代码仓库&#xff0c;用于存放项目代码&#xff0c;方便整合开发过程 公共代码仓库&#xff1a;github全球 gitee国内 git 分布式 ---没有中心代码库&#xff0c;所有机器之间的地位同等&#xff08;每台机器上都有相同的代码&#xff09; …

18055 主对角线上的元素之和

### 思路 1. 输入一个3行4列的整数矩阵。 2. 计算主对角线上的元素之和。 3. 输出主对角线上的元素之和。 ### 伪代码 1. 初始化一个3行4列的矩阵 matrix。 2. 输入矩阵的元素。 3. 初始化一个变量 sum 为0&#xff0c;用于存储主对角线元素之和。 4. 遍历矩阵的行&#xff0c…

AI产品经理:ai产品经理从零基础到精通,非常详细收藏我这一篇就够了

在互联网的浪潮中&#xff0c;AI人工智能领域无疑是最引人注目的风口。AI产品经理&#xff0c;作为这一领域的新兴岗位&#xff0c;以其高薪、低压力、无年龄限制等优势&#xff0c;吸引了众多互联网从业者的目光。随着GPT等AIGC工具的兴起&#xff0c;AI产品经理的市场需求日益…

企业网银登录提示请确认您已插入工商银行U盾证书的解决方法

昨天受人之托帮小企业财务解决上网银的问题 因为不是专业做这个的&#xff0c;所以只能安装“常识”行事&#xff0c;但结果实在是令人意想不到。 排错的步骤&#xff1a; 同一台电脑上尝试不同浏览器&#xff0c;发现360浏览器的接受度相当普遍&#xff1b;给U盾换不同的连接…

【408 数据结构】第1章绪论

文章目录 绪论考纲DS 基本概念1. 基本概念2. 数据结构三要素 算法&#xff08;时/空间复杂度计算&#xff09;1. 算法概念2. 算法效率的度量时间复杂度&#xff1a;空间复杂度&#xff1a; 小结 绪论 考纲 计算时间复杂度和空间复杂度&#xff08;重点难点&#xff09; DS …

如何使用AI来免费提升你的图片质量

学习如何使用AI免费放大您的图像&#xff0c;可以将那些恼人的低分辨率图像转变为高分辨率的杰作——至少在某种程度上是这样。虽然使用我们用于此任务的应用程序Upscayl需要稍微调整一下不同的模型&#xff0c;但您至少应该能够将图像转换成视觉上更令人愉悦的效果。 Upscayl…

Python教程(二十) : 十分钟入门【PyQt6】

文章目录 专栏列表环境准备1 安装 Python2 安装 PyQt6 创建 PyQt6 项目1 创建项目目录2 创建主 Python 文件 代码书写测试流程1 导入 PyQt6 模块2 创建主窗口类3 创建应用程序实例并运行 核心解析&#xff1a;PyQt6 中的模块示例代码&#xff1a; PyQt6 常用的控件1. QPushButt…

【Linux网络编程八】实现最简单Http服务器(基于Tcp套接字)

基于TCP套接字实现一个最简单的Http服务器 Ⅰ.Http请求和响应格式1.请求格式2.响应格式3.http中请求格式中细节字段4.http中响应格式中细节字段 Ⅱ.域名ip与URLⅢ.web根目录Ⅳ.Http服务器是如何工作的&#xff1f;一.获取请求二.分析请求2.1反序列化2.2解析url 三.构建响应3.1构…

java重点学习-mysql

2.1 如何定位慢查询? 1:介绍一下当时产生问题的场景(我们当时的一个接口测试的时候非常的慢&#xff0c;压测的结果大概5秒钟) 2.我们系统中当时采用了运维工具(Skywalking)&#xff0c;可以监测出哪个接口&#xff0c;最终因为是sql的问题 3.在mysql中开启了慢日志查询&#…

【LeetCode】14.最长公共前缀

题目要求 解题思路 这道题我们可以通过一列一列的比较是否相等来解决 代码实现 class Solution { public:string longestCommonPrefix(vector<string>& strs) {string ret;//以第一个字符串为标准for(int i0;i<strs[0].size();i){//保存第一个字符串的第i个位…

前端---对MVC MVP MVVM的理解

就需要从前端这些年的从无到有、从有到优的变迁过程讲一下。 1. Web1.0时代 在web1.0时代并没有前端的概念&#xff0c;开发一个web应用多数采用ASP.NET/Java/PHP编写&#xff0c;项目通常用多个aspx/jsp/php文件构成&#xff0c;每个文件中同时包含了HTML、CSS、JavaScript、…

微信小程序手写签名

微信小程序手写签名组件 该组件基于signature_pad封装&#xff0c;signature_pad本身是web端的插件&#xff0c;此处将插件代码修改为小程序端可用。 signature_pad.js /*!* Signature Pad v5.0.3 | https://github.com/szimek/signature_pad* (c) 2024 Szymon Nowak | Releas…

[数据集][目标检测]轮胎检测数据集VOC+YOLO格式4629张1类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;4629 标注数量(xml文件个数)&#xff1a;4629 标注数量(txt文件个数)&#xff1a;4629 标注…

Spring扩展点系列-InstantiationAwareBeanPostProcessor

文章目录 简介测试一1、配置文件Bean注册2、单元测试方法3、测试类4、输出结果结论 测试二1、测试类2、输出结果结论 源码解析postProcessPropertiesCommonAnnotationBeanPostProcessorAnnotationInjectedBeanPostProcessor 总结 简介 spring容器中Bean的生命周期内所有可扩展…

【重构获得模式 Refactoring to Patterns】

重构获得模式 Refactoring to Patterns 面向对象设计模式是“好的面向对象设计”&#xff0c;所谓“好的面向对象设计”指的是那些可以满足“应对变化&#xff0c;提高复用”的设计。 现代软件设计的特征是“需求的频繁变化”。设计模式的要点是“寻找变化点&#xff0c;然后…