【裸机开发】IRQ 中断服务函数(二)—— 全局中断初始化

news2025/5/18 16:24:41

实现了 IRQ 中断服务函数的汇编部分以后,接下来我们要使用C代码实现IRQ中断服务函数的具体逻辑,主要包含初始化和中断处理两部分。

  • 全局中断初始化(全局中断使能、IRQ中断使能)
  • 具体中断处理逻辑实现

目录

一、全局中断初始化(理论流程)

二、IRQ 中断使能

1、认识中断ID

2、IRQ 中断使能实现

三、初始化 IRQ 中断服务函数表

1、中断服务函数指针

2、中断服务函数表声明

3、中断服务函数表初始化

四、总结:中断服务函数接口

1、通用中断服务函数(system_irqhandler)

2、中断服务函数注册接口

3、中断初始化接口


一、全局中断初始化(理论流程)

全局中断初始化的基本流程如下:

① GIC全局中断使能:相当于打开中断控制器

② IRQ中断使能:IRQ目前用于用户日常使用的有128种,我们需要手动指定具体哪一种中断使能

③ 初始化服务函数表:IRQ 一共160 种中断,我们需要为每一种中断分配一个默认的中断服务函数

④ 设置中断向量表:中断向量表默认保存在 0x00000000 的位置,但是 0x00000000 保存了boot rom 相关内容,所以我们有时需要把中断向量表换个地方保存。

二、IRQ 中断使能

IRQ 中断使能需要具体到某种具体的外设中断,即你要打开哪一种类型的中断,GPIO 的中断还是SPI 的中断。因此,在实现IRQ中断使能之前需要先了解中断ID

1、认识中断ID

IRQ 中断是我们最常用的一种中断,包含了所有外设可能产生的中断,如按键、I2C、SPI 等。为了区分这些外设产生的中断,IRQ 中断为这些外设产生的中断分配了中断号。

0~15号:这 16 个 ID 分配给 SGI(软件中断)。由软件触发引起的中断,通过向寄存器 GICD_SGIR 写入数据来触发,系统会使用 SGI 中断来完成多核之间的通信。

16~31号:这16个ID分配给 PPI(私有中断)。一个CPU可能包含多核,每个核有自己独有的中断,这些独有中断只能在指定的核中处理,我们称这种中断为“ 私有中断 ”。

32~1019号:剩余的分配给 SPI(共享中断)。一个CPU可能包含多核,共享中断在所有的核中都可以得到处理,不仅限于某个特定的核。(目前只用了 128 个)

2、IRQ 中断使能实现

IRQ 中断使能使用的是SDK中的接口。下面的 99 是中断ID,比如你要使用 GPIO1 的 0 -15 引脚,对应的中断ID就是66 + 32 = 98;如果要使用 GPIO1 的 16 - 31 引脚,对应的中断 ID 就是 67 + 32 = 99

注意:这里的 32 表示SGI 和 PPI 对应的32种中断,用户无法干涉。

#include "core_ca7.h"

/* 使能GIC 中 IRQ 的某个外设对应的中断 */
GIC_EnableIRQ(99);    

三、初始化 IRQ 中断服务函数表

为了区分IRQ中断具体来自于哪个外设,定义了 160 种中断(前32种中断有特殊用途),我们要做的第一件事就是给这些中断配上默认的中断函数。

1、中断服务函数指针

为了管理前面说到了的 160 种中断,我们要定义一个函数指针数组,数组中保存的是函数指针(也就是函数地址),因此我们需要确定函数指针的类型。

/* 中断服务函数的格式 */
typedef void (*irqhandler_t)(void* userParams);
  • 函数指针类型名:irqhandler_t
  • 函数格式:
    • 形参:void*,后续可能需要给中断服务函数传递参数
    • 返回值:void

2、中断服务函数表声明

为了管理每一种中断对应的中断服务函数,我们要创建一个数组,数组的下标就代表中断ID,下标对应的就是中断服务函数指针。

#define MAX_INT 160

/* 管理着所有的irq中断服务函数 */
irqhandler_t irqTable[MAX_INT];

3、中断服务函数表初始化

接下来我们要给这 160 个中断服务函数表逐一赋予默认中断服务函数,所以我们先简单定义一个默认中断服务函数。函数格式必须按照最开始的中断服务函数指针的格式来。

/* 默认中断服务函数 */
void default_irqhandler(void* userParams)
{
    return;
}

然后我们为中断服务函数表中的每一个元素进行初始化

/* 初始化 irq 中断服务函数表 */
void irqtable_init()
{
    unsigned int i = 0;
    for (; i < MAX_INT; i++)
    {
        irqTable[i] = default_irqhandler;
    }
}

四、总结:中断服务函数接口

1、通用中断服务函数(system_irqhandler)

在汇编部分,我们已经获取到了中断ID,在通用中断服务函数中,我们要根据这个中断ID执行对应的中断服务函数。

代码中 giccIar 就是中断ID,我们根据中断ID可以在中断服务函数表中找到对应的函数地址(函数指针),直接调用即可。

/* 通用中断服务函数 */
void system_irqhandler(unsigned int giccIar)
{
    // GICC_IAR 寄存器低10位用于存储中断ID
    unsigned int intID = giccIar & 0x3ff;            
    if (giccIar > MAX_INT)
    {
        return;
    }
    
    // 如果没有要传递的内容,那就传递 (void*)0
    irqTable[giccIar]((void *)0);
}

2、中断服务函数注册接口

方才我们只是给中断服务函数表中每一个中断ID赋予了默认中断服务函数指针,后续可能会在其他地方要修改中断ID对应的中断服务函数,因此我们这里定义一个“注册中断服务函数”

/* 注册中断服务函数 */
void register_irqhandler(unsigned int intID, irqhandler_t handler)
{
    irqTable[intID] = handler;
}

 

3、中断初始化接口

GIC 全局中断使能 和 IRQ 中断使能用的都是 SDK 中的接口。

#include "core_ca7.h"

/* 中断初始化 */
void interrupt_init()
{
    /* GIC 全局中断使能初始化 */
    GIC_Init();

    /* irq 中断服务函数表初始化 */
    irqtable_init();

    /* 设置中断向量表偏移 */
    __set_VBAR((uint32_t)0x87800000);

    /* 使能GIC 中 IRQ 的某个外设对应的中断 */
    GIC_EnableIRQ(99);    
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【C++】第14章: C++中的代码重用

第十四章 C中的代码重用 文章目录 第十四章 C中的代码重用引言14.1 valarray类简介14.1.1 接口和实现14.1.2 C和约束14.1.3 初始化顺序 14.2 has a14.2.1 组合14.2.2 私有继承14.2.2.1 访问基类的方法14.2.2.2 访问基类对象14.2.2.3 访问基类的友元函数 14.2.3 使用组合还是私有…

【软件工程导论】从已考完期末的角度记录软导常考内容

文章目录 软件工程概念软件过程模型&#xff08;了解&#xff09;软件生存周期划分数据流图内聚与耦合的种类UML中的主要图及其作用MVC模式MVVM模式黑盒测试白盒测试白盒测试法的逻辑覆盖标准 软件工程概念 什么是软件工程&#xff1f;它的目标和内容是什么&#xff1f; 软件工…

无处不在 | 亚马逊云科技的 Java 生态

Java 自诞生以来就一直是热门的编程语言。得益于丰富的生态以及完善维护的包和框架&#xff0c;Java 拥有着庞大的开发者社区。这个 1995 年诞生的计算机语言&#xff0c;以 “一次编写&#xff0c;到处运行” 的跨平台特性以及面向对象、泛型编程等现代语言的特性迅速成为了企…

企业如何通过精细化管理实现高质量增长?

增量经济时代&#xff0c;各行各业都有比较充足的发展机会&#xff0c;即使采取相似的发展模式、提供同质化的产品和服务&#xff0c;也都会获得收益和增长。当前&#xff0c;我国开始步入存量经济时代&#xff0c;增量空间正逐步被压缩&#xff0c;这将对区域格局、产业组织结…

【NLP】PageRank、TextRank算法的原理解析

一、说明 PageRank是经典的网页热度评分算法&#xff0c;在自然语言的热词提取也有同样的意义&#xff08;TextRank&#xff09;&#xff1b;本文详细叙述该算法的原理&#xff0c;配合部分代码演示其原理。 二、PageRank算法的启发因素 2.1 算法兴起 PageRank (PR) 是…

HDLBits笔记6:Circuits.Combinational Logic.Multiplexers + Arithmetic Circuits

Multiplexers 2-to-1 multiplexer module top_module( input a, b, sel,output out ); assign out sel ? b : a; endmodule2-to-1 bus multiplexer module top_module( input [99:0] a, b,input sel,output [99:0] out );assign out sel ? b : a; endmodule9-to-1 multi…

逍遥自在学C语言 | 多级指针探秘

前言 多级指针在C语言中是一种特殊的指针类型&#xff0c;它可以指向其他指针的指针。 通过多级指针&#xff0c;我们可以间接地访问或修改存储在内存中的数据。 在本文中&#xff0c;我们将讨论多级指针的概念、使用方法、使用场景以及常见错误及其避免方法。 一、人物简介…

软件项目管理 第六章 软件项目的进度管理 课后习题参考答案——主编:李冰、张桥珍、刘玉娥

第六章 软件项目的进度管理 课后习题参考答案 1.选择题 (1)快速跟进是指&#xff08;A&#xff09;。 A.采用并行执行任务,加速项目进展 B.用一个任务取代另外的任务 C.如有可能,减少任务数量 D.减轻项目风险 (2)赶工一个任务时&#xff0c;…

相机畸变概述

上节说到了相机模型,那么这节说说相机的畸变 如果有手机爱好者,听到很多测评进行测评的时候,都会提到一个词,广角防畸变,啥意思,举个栗子 来看下信号塔,是不是已经开始歪了,这就是0.6倍,超广角模式下的畸变(其实一倍也畸变,小声BB) 为啥会畸变呢,仔细看镜头,镜头是曲面的,光…

CDN和DNS

目录 宽带&#xff0c;窄带&#xff0c;带宽区别和联系如何计算带宽带宽和网速的区别和联系 CDNCDN的原理CDN的好处CDN和通信行业DNS和CDN的区别与联系用户访问未使用CDN缓存网站的过程为使用了CDN缓存后的网站的访问过程变为 CDN加速服务 DNSDNS对好处公共 DNS114 DNS阿里DNS百…

Mac安装配置Visual Studio Code(vscode)以及Java环境详细教程(初学者必看)

原本博主今天想继续给大家出Java接下来的教程,但是就在昨天我在配置vscode的时候遇到了一些问题,Windows系统的小伙伴配置起来肯定很方便,但是在Mac的小伙伴却显得十分无奈,所以我想给大家出一篇Mac的Visual Studio Code配置以及Java环境搭建教程&#xff01; 博客主页:Jovy.的…

C#中调用MATLAB的函数形式的m文件

问题介绍 需要在C#编写的winform中调用matlab写的函数类型的m文件&#xff0c;并在winform中读取m文件的返回值。 之前也写过类似的博客&#xff0c;请参考&#xff1a;C#中调用MATLAB执行MATLAB代码 本篇文章算是之前文章的更新版本吧。 步骤 1 创建C#的winform项目 在桌面…

STM32单片机(九)USART串口----第一节:USART串口协议

❤️ 专栏简介&#xff1a;本专栏记录了从零学习单片机的过程&#xff0c;其中包括51单片机和STM32单片机两部分&#xff1b;建议先学习51单片机&#xff0c;其是STM32等高级单片机的基础&#xff1b;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 &#xff1a;适用于想要…

【博弈论笔记】第二章 完全信息静态博弈

文章目录 第二章 完全信息静态博弈2.1 基本分析思路和方法2.1.1 上策均衡2.1.2 严格下策反复消去法2.1.3 划线法2.1.4 箭头法 2.2 纳什均衡2.2.1 纳什均衡的诞生2.2.2 纳什均衡的定义2.2.3 纳什与严格下策反复消去法2.2.4 一致预测性质 2.3 无限策略博弈和反应函数&#xff08;…

性能测试的具体流程

以下是一个基本的性能测试过程&#xff0c;旨在帮助了解性能测试的具体流程和步骤。 1. 确定性能测试目标及指标 首先&#xff0c;需要确定性能测试的目标和指标&#xff0c;包括响应时间、吞吐量、并发用户数等方面。这些指标应该根据业务需求和用户场景进行设定&#xff0c…

Unity-Android常见的那些骚操作

老规矩&#xff0c;先安装unity&#xff0c;再安装安卓平台&#xff0c;安装AndroidStudio ,安装JDK,安装SDK 配置JDK 环境&#xff0c;在Unity里面引用SDK 和 JDK Unity中的Android Build Support下载 在Unity中的File>Building Settings>Android>Open Download Pag…

VMware Ubuntu忘记密码修改密码

目录 一、重启 二、重置密码 三、补充 一觉醒来&#xff0c;刚想去虚拟机爽一下Linux却发现忘记了密码&#xff1f; 没关系&#xff0c;这里有详细的步骤帮你修改密码&#xff01; 一、重启 重启虚拟机&#xff0c;在进度条未读完前&#xff0c;长按shift进入GRUB系统引导…

56 KVM工具使用指南-安装 LibcarePlus

文章目录 56 KVM工具使用指南-安装 LibcarePlus56.1 安装软件依赖56.2 安装 LibcarePlus56.3 查看安装是否成功 56 KVM工具使用指南-安装 LibcarePlus 56.1 安装软件依赖 LibcarePlus 运行依赖于 libunwind、 elfutils 和 binutils&#xff0c;在配置了 yum 源的 openEuler 系…

SpringSecurity中授权时fastjson序列化问题

最近在复习Spring Security&#xff0c;复习的鉴权的时候出现问题。26.封装权限信息_哔哩哔哩_bilibili 如果是从B站中看到&#xff0c;直接说问题可能出现的原因&#xff1a;可能是private List<String> authorities;中的权限信息命名不规范&#xff0c;去掉get&#x…

Python基础篇(十一):装饰器

装饰器 前言1. 装饰器的定义2. 装饰器的应用3. 装饰器的语法4. func(*args, **kwargs) 前言 装饰器是Python中一种强大的函数或类修饰机制&#xff0c;用于在不修改原始函数或类代码的情况下&#xff0c;对其进行功能扩展或修改。装饰器基于函数式编程的概念&#xff0c;通过将…