当前位置: 首页 > news >正文

【嵌入式Linux】i.MX6ULL 外部中断服务函数的初始化

文章目录

  • 1. Cortex-A7 中断系统
    • 1.1 分析
    • 1.2 具体处理流程
  • 2. 外部中断服务函数的初始化
    • 2.1 基本流程分析
    • 2.2 具体代码分析
      • 2.2.1. 定义中断处理类型和结构体
      • 2.2.2. 初始化中断系统
      • 2.2.3. 注册中断处理函数
      • 2.2.4. 具体的中断处理逻辑
      • 2.2.5. 默认的中断处理函数
  • 3. 完整代码

本文章结合了正点原子的 i.mx6u嵌入式Linux开发指南和笔者的理解。

1. Cortex-A7 中断系统

1.1 分析

1. 中断向量表:

  • Cortex-A7 也有中断向量表,位于代码的最前面。
  • 包含 8 个异常中断,每个中断对应一个向量地址和中断模式。
  • 表 17.1.2.1 列出了这 8 个中断:
    • 复位中断 (Reset):特权模式 (SVC)
    • 未定义指令中断 (Undefined Instruction):未定义指令中止模式 (Undef)
    • 软中断 (Software Interrupt, SWI):特权模式 (SVC)
    • 指令预取中止中断 (Prefetch Abort):中止模式
    • 数据访问中止中断 (Data Abort):中止模式
    • 未使用 (Not Used):未使用
    • IRQ 中断 (IRQ Interrupt):外部中断模式 (IRQ)
    • FIQ 中断 (FIQ Interrupt):快速中断模式 (FIQ)

2. Cortex-A7 中断向量表与 Cortex-M 的区别:

  • Cortex-M 中断向量表列举了芯片的所有中断向量,包括外设中断。
  • Cortex-A7 中断向量表只列出了 8 个基本中断,其中 IRQ 中断包含了所有外部中断。
  • 也就是说,Cortex-A7 中,所有外部中断都通过 IRQ 中断进行处理。

3. IRQ 中断处理:

  • 当任意一个外部中断发生时,都会触发 IRQ 中断。
  • IRQ 中断服务函数需要读取指定的寄存器来判断具体是哪个外部中断发生了。
  • 根据具体的中断做出相应的处理。

4. 外部中断与 IRQ 中断的关系:
在这里插入图片描述

  • 图中左侧的 Software0_IRQn~PMU_IRQ2_IRQ 都是 I.MX6U 的外部中断,它们都属于 IRQ 中断。
  • 当任意一个外部中断发生时,IRQ 中断会被触发。
  • 在 IRQ 中断服务函数中需要判断是哪个外部中断发生了,并进行相应的处理。

1.2 具体处理流程

  1. 某个外部中断发生。
  2. IRQ 中断被触发。
  3. IRQ 中断服务函数执行。
  4. IRQ 中断服务函数调用 C 语言中断处理函数。
  5. C 语言中断处理函数根据中断号判断是哪个外部中断发生了。
  6. C 语言中断处理函数执行相应的处理逻辑。
  • IRQ 中断就像一个“总开关”,而外部中断就像“子开关”。当某个子开关打开时,会触发总开关,然后需要根据子开关的具体情况进行处理。
  • 前面的文章我们已经对IRQ中断服务函数进行了初始化,设置在IRQ中断服务函数中执行C语言的中断服务函数:
ldr r2, =system_irqhandler	/* 加载C语言中断处理函数到r2寄存器中*/
blx r2						/* 运行C语言中断处理函数,带有一个参数,保存在R0寄存器中 */

下面我们就开始在C语言中,根据不同的中断号进行不同的中断服务函数初始化和处理。

2. 外部中断服务函数的初始化

2.1 基本流程分析

  1. 定义中断处理类型和结构体
  2. 初始化中断系统
  3. 注册中断处理函数
  4. 具体的中断处理逻辑
  5. 默认的中断处理函数

2.2 具体代码分析

2.2.1. 定义中断处理类型和结构体

此步骤定义了中断处理函数的类型别名 system_irq_handler_t 和中断处理函数结构体 sys_irq_handle_t

typedef void (*system_valve_handler_t)(unsigned int gicciar, void *param);typedef struct _sys_irq_handle{system_valve_handler_t irqHandler; // 中断处理函数void *usrparam;                    // 中断处理函数的参数
} sys_irq_handle_t;/*中断处理函数表*/
static sys_irq_handle_t irqTable[NUMBER_OF_INT_VECTORS];

解释

  • system_irq_handler_t 是一个函数指针类型,指向的函数用于处理中断,接收中断号和用户参数。
  • sys_irq_handle_t 结构体包含一个中断处理函数和一个用于传递给该函数的用户参数。
  • irqTable是一个结构体数组,包含所有外部中断的结构体,共NUMBER_OF_INT_VECTORS=160个。

2.2.2. 初始化中断系统

初始化中断系统包括 GIC 初始化和中断向量表的初始化。

/*初始中断向量表*/
void system_irqtable_init(void)
{irqNesting = 0;//中断计数器清0unsigned int i;for(i=0; i<NUMBER_OF_INT_VECTORS; i++){irqTable[i].irqHandler = default_irqhandler;irqTable[i].usrparam = NULL;}
}void int_Init(void)
{GIC_Init(); // 初始化GICsystem_irqtable_init();__set_VBAR(0x87800000); // 中断向量偏移设置
}

解释

  • GIC_Init() 调用是用来初始化通用中断控制器(Generic Interrupt Controller)。
  • system_irqtable_init() 初始化中断处理函数表,为每个可能的中断分配默认处理函数。
  • __set_VBAR(0x87800000) 设置中断向量基地址寄存器(VBAR)。

2.2.3. 注册中断处理函数

此步骤允许用户为特定的中断号注册自定义的处理函数。

void system_register_irqhandler(IRQn_Type irq, system_irq_handler_t handler, void *param)
{irqTable[irq].irqHandler = handler;irqTable[irq].usrparam = param;
}

解释

  • 通过指定的 irq 中断号,用户可以将自定义的处理函数 handler 和参数 param 注册到中断处理函数表 irqTable 中。

2.2.4. 具体的中断处理逻辑

  • 该部分是实际的中断处理逻辑,由具体的中断处理函数 system_irqhandler 实现。
  • system_irqhandler实际上由IRQ中断调用,完成了选择不同外部中断函数进行处理中断的功能。
void system_irqhandler(unsigned int gicciar)
{irqNesting++; // 中断计数器uint32_t intNum = gicciar & 0x3FF; // 从低10位获取中断IDif(intNum >= NUMBER_OF_INT_VECTORS) return; // 检查中断ID是否正常irqTable[intNum].irqHandler(intNum, irqTable[intNum].usrparam); // 根据中断号,选取中断处理函数执行irqNesting--; // 中断执行完,中断计数器-1
}

解释

  • irqNesting 记录当前正在处理的中断嵌套层数。
  • 通过 gicciar & 0x3FF 提取中断号,并检查其有效性,然后调用相应的中断处理函数。

2.2.5. 默认的中断处理函数

提供一个默认的中断处理函数,当没有特定的处理函数注册时使用。

void default_irqhandler(unsigned int gicciar, void *param)
{while(1); // 死循环,用于捕捉未处理的中断
}

解释

  • 这是一个防止未注册中断导致系统异常退出的安全措施。如果执行到此函数,表明发生了未注册处理函数的中断。

3. 完整代码

bsp_int.c

#include "bsp_int.h"
static unsigned int irqNesting;//中断计数器,用于嵌套/*中断处理函数表*/
static sys_irq_handle_t irqTable[NUMBER_OF_INT_VECTORS];
/*初始中断向量表*/
void system_irqtable_init(void)
{irqNesting = 0;//中断计数器清0unsigned int i;for(i=0; i<NUMBER_OF_INT_VECTORS; i++){irqTable[i].irqHandler = default_irqhandler;irqTable[i].usrparam = NULL;}
}/*注册中断处理函数*/
void system_register_irqhandler(IRQn_Type irq, system_irq_handler_t handler, void *param)
{irqTable[irq].irqHandler = handler;irqTable[irq].usrparam = param;
}//中断初始化函数
void int_Init(void)
{GIC_Init();//初始化GICsystem_irqtable_init();__set_VBAR(0x87800000);//中断向量偏移设置}/*具体的中断处理函数,IRQ_Handler会调用此C函数*/
void system_irqhandler(unsigned int gicciar)
{irqNesting++;//中断计数器uint32_t intNum = gicciar & 0x3FF;//从低10位获取中断ID//检查中断ID是否正常if(intNum >= NUMBER_OF_INT_VECTORS) return;//根据中断号,选取中断处理函数执行irqTable[intNum].irqHandler(intNum, irqTable[intNum].usrparam);irqNesting++;//中断执行完,中断计数器-1
}//默认中断处理函数
void default_irqhandler(unsigned int gicciar, void *param)
{while(1);
}

bsp_int.h

#ifndef __BSP_INT_H
#define __BSP_INT_H#include "imx6u.h"// 这段代码定义了一个类型别名 system_irq_handler_t,
// 用于表示一个指向中断处理函数的指针。
// 该函数指针指向的函数接收两个参数:
// 中断号
// 和一个指向任意类型数据的指针,用于传递额外的参数。
typedef void (*system_irq_handler_t)(unsigned int gicciar, void *param);//中断处理函数结构体
typedef struct _sys_irq_handle{system_irq_handler_t irqHandler;//中断处理函数void *usrparam;//中断处理函数的参数
}sys_irq_handle_t;void int_Init(void);
void system_irqtable_init();
void default_irqhandler(unsigned int gicciar, void *param);
void system_register_irqhandler(IRQn_Type irq, system_irq_handler_t handler, void *param);#endif // !__BSP_INT_H

相关文章:

【嵌入式Linux】i.MX6ULL 外部中断服务函数的初始化

文章目录 1. Cortex-A7 中断系统1.1 分析1.2 具体处理流程 2. 外部中断服务函数的初始化2.1 基本流程分析2.2 具体代码分析2.2.1. 定义中断处理类型和结构体2.2.2. 初始化中断系统2.2.3. 注册中断处理函数2.2.4. 具体的中断处理逻辑2.2.5. 默认的中断处理函数 3. 完整代码 本文…...

线性代数、矩阵计算

一、线性代数 1、对于向量&#xff0c;若a是标量&#xff0c;为a的绝对值乘以b的向量长度。 2、点乘 3、范数&#xff1a;向量或者矩阵的长度 L1范数&#xff1a;&#xff08;对向量&#xff09;每个元素的绝对值求和 L2范数&#xff1a;&#xff08;对向量&#xff09;torch.…...

PostgreSQL 高级功能(五)

1. 存储过程与函数 1.1 创建存储过程 存储过程是一组预编译的SQL语句&#xff0c;可以简化复杂的操作。以下是一个简单的存储过程示例&#xff1a; CREATE OR REPLACE FUNCTION add_user(username VARCHAR, email VARCHAR) RETURNS VOID AS $$ BEGININSERT INTO users (use…...

食品企业仓储式批发零售一体化解决方案

食品企业需要有效应对日益复杂的市场挑战和消费者需求的快速变化的挑战并提升市场竞争力&#xff0c;仓储式类的批发零售一体化需求应运而生。这一全新的商业模式不仅整合了传统的批发和零售模式&#xff0c;还优化了供应链管理和客户体验&#xff0c;成为食品行业发展的新引擎…...

chrome插件,修改对应URL的http请求的header头,包括ajax请求

要创建一个可以灵活修改HTTP请求头的Chrome扩展&#xff0c;包括一个用户界面来动态设置头部名称和值&#xff0c;可以按照以下步骤进行。我们会用到 chrome.storage API 来保存用户的设置&#xff0c;并在后台脚本中使用这些设置来修改请求头。 文件结构 my_chrome_extensio…...

C语言 | Leetcode C语言题解之第191题位1的个数

题目&#xff1a; 题解&#xff1a; int hammingWeight(uint32_t n) {int ret 0;while (n) {n & n - 1;ret;}return ret; }...

【C++11(二)】lambda表达式和可变参数模板

一、可变参数模板 C11的新特性可变参数模板 能够让您创建可以接受 可变参数的函数模板和类模板 // Args是一个模板参数包&#xff0c;args是一个函数形参参数包 // 声明一个参数包Args...args&#xff0c;这个参数包中可以包含0到任意个模板参数。 template <class ...Arg…...

昇思25天学习打卡营第2天|张量Tensor

张量Tensor 创建张量张量的属性张量索引张量运算 稀疏张量 总结 简单讲讲张量&#xff0c;数学和物理学界以一种方式定义张量&#xff0c;机器学习上则是以另一种方式定义张量&#xff0c;这里的张量也与神经网络联系紧密&#xff0c;神经网络需要进行大量的数学计算&#xff0…...

[leetcode]valid-triangle-number. 有效三角形的个数

. - 力扣&#xff08;LeetCode&#xff09; class Solution { public:int triangleNumber(vector<int>& nums) {int n nums.size();sort(nums.begin(), nums.end());int ans 0;for (int i 0; i < n; i) {for (int j i 1; j < n; j) {int left j 1, righ…...

java SQL server 多实例的情况

而对于java&#xff0c;对付多个数据库实例就有些要注意的了&#xff1a; 首先&#xff0c;同样连接字符串上加上“\实例名”&#xff1a; jdbc:sqlserver://127.0.0.1\\mssqlserver2008;DatabaseNameLPT; 此处应去掉端口1433。因为连接数据库自命名实例的url中没有端口号1433…...

html--404页面

<!DOCTYPE html> <html> <head> <meta http-equiv"Content-Type" content"text/html; charsetUTF-8"> <meta http-equiv"X-UA-Compatible" content"IEedge,chrome1"> <title>404 错误页面不存在&…...

[word] Word如何删除所有的空行? #职场发展#学习方法

Word如何删除所有的空行&#xff1f; 很多网友从网页复制文字粘贴到word文档后发现段落之间有空行&#xff0c;如果文字不多&#xff0c;手动删除这些空行也没有多少工作量&#xff0c;但是如果文字的字数达到成千上万&#xff0c;一个个手动删除这些空行还是很繁琐的。那么&a…...

【CSS】深入探讨 CSS 的 `calc()` 函数

深入探讨 CSS 的 calc() 函数 calc() 是一个 CSS 函数&#xff0c;用于在样式表中进行数学计算&#xff0c;从而动态地设置 CSS 属性值。它允许开发者在指定长度、百分比、数值等时&#xff0c;进行加减乘除运算。通过 calc() 函数&#xff0c;我们可以实现更灵活和响应式的设…...

MongoDB异地备份数据文件脚本(带日志打印,便于排查)

此脚本是以文件夹的形式备份&#xff0c;非压缩包形式 如需备份成加密压缩包&#xff0c;可用此脚本&#xff1a;MongoDB定时异地备份所有数据库为加密压缩包-CSDN博客 1.可以直接下载本文件使用&#xff0c;将其放到mongo安装目录的bin目录下&#xff08;可手动执行&#xf…...

论文导读 | Manufacturing Service Operations Management近期文章精选

编者按 在本系列文章中&#xff0c;我们梳理了顶刊Manufacturing & Service Operations Management5月份发布有关OR/OM以及相关应用的文章之基本信息&#xff0c;旨在帮助读者快速洞察行业/学界最新动态。 推荐文章1 ● 题目&#xff1a;Robust Drone Delivery with Weath…...

【Linux命令】top linux下的任务管理器

一、概述 top命令是Linux下常用的性能分析工具&#xff0c;能够实时显示系统中各个进程的资源占用状况&#xff0c;类似于Windows的任务管理器。top是一个动态显示过程&#xff0c;即可以通过用户按键来不断刷新当前状态。如果在前台执行该命令&#xff0c;它将独占前台&#…...

2024年在分数限制下,选好专业还是选好学校?

分数限制下&#xff0c;选好专业还是选好学校&#xff1f; 24年高考帷幕落下&#xff0c;一场新的思考与选择悄然来临。对于每一位高考考生&#xff0c;学校和专业都是开启大学新生活的两个前置必选项。但有时候“鱼与熊掌不可兼得”&#xff0c;在分数受限的条件下&#xff0…...

cropperjs 裁剪/框选图片

1.效果 2.使用组件 <!-- 父级 --><Cropper ref"cropperRef" :imgUrl"url" searchImg"searchImg"></Cropper>3.封装组件 <template><el-dialog :title"title" :visible.sync"dialogVisible" wi…...

ArkTS开发系列之事件(2.8.2手势事件)

上篇回顾&#xff1a;ArkTS开发系列之事件&#xff08;2.8.1触屏、键鼠、焦点事件&#xff09; 本篇内容&#xff1a;ArkTS开发系列之事件&#xff08;2.8.2手势事件&#xff09; 一、绑定手势方法 1. 常规手势绑定方法 Text(手势).fontSize(44).gesture(TapGesture().onAct…...

【MATLAB源码-第135期】基于matlab的变色龙群优化算法CSA)机器人栅格路径规划,输出做短路径图和适应度曲线。

操作环境&#xff1a; MATLAB 2022a 1、算法描述 变色龙群优化算法&#xff08;Chameleon Swarm Algorithm&#xff0c;CSA&#xff09;是一种新颖的群体智能优化算法&#xff0c;受到自然界中变色龙捕食和社交行为的启发。变色龙以其独特的适应能力而著称&#xff0c;能够根…...

Java 8 Stream API 入门到实践详解

一、告别 for 循环&#xff01; 传统痛点&#xff1a; Java 8 之前&#xff0c;集合操作离不开冗长的 for 循环和匿名类。例如&#xff0c;过滤列表中的偶数&#xff1a; List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建

制造业采购供应链管理是企业运营的核心环节&#xff0c;供应链协同管理在供应链上下游企业之间建立紧密的合作关系&#xff0c;通过信息共享、资源整合、业务协同等方式&#xff0c;实现供应链的全面管理和优化&#xff0c;提高供应链的效率和透明度&#xff0c;降低供应链的成…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

基于当前项目通过npm包形式暴露公共组件

1.package.sjon文件配置 其中xh-flowable就是暴露出去的npm包名 2.创建tpyes文件夹&#xff0c;并新增内容 3.创建package文件夹...

Spring Boot面试题精选汇总

&#x1f91f;致敬读者 &#x1f7e9;感谢阅读&#x1f7e6;笑口常开&#x1f7ea;生日快乐⬛早点睡觉 &#x1f4d8;博主相关 &#x1f7e7;博主信息&#x1f7e8;博客首页&#x1f7eb;专栏推荐&#x1f7e5;活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...

【开发技术】.Net使用FFmpeg视频特定帧上绘制内容

目录 一、目的 二、解决方案 2.1 什么是FFmpeg 2.2 FFmpeg主要功能 2.3 使用Xabe.FFmpeg调用FFmpeg功能 2.4 使用 FFmpeg 的 drawbox 滤镜来绘制 ROI 三、总结 一、目的 当前市场上有很多目标检测智能识别的相关算法&#xff0c;当前调用一个医疗行业的AI识别算法后返回…...

CSS | transition 和 transform的用处和区别

省流总结&#xff1a; transform用于变换/变形&#xff0c;transition是动画控制器 transform 用来对元素进行变形&#xff0c;常见的操作如下&#xff0c;它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...

uniapp 开发ios, xcode 提交app store connect 和 testflight内测

uniapp 中配置 配置manifest 文档&#xff1a;manifest.json 应用配置 | uni-app官网 hbuilderx中本地打包 下载IOS最新SDK 开发环境 | uni小程序SDK hbulderx 版本号&#xff1a;4.66 对应的sdk版本 4.66 两者必须一致 本地打包的资源导入到SDK 导入资源 | uni小程序SDK …...

第7篇:中间件全链路监控与 SQL 性能分析实践

7.1 章节导读 在构建数据库中间件的过程中&#xff0c;可观测性 和 性能分析 是保障系统稳定性与可维护性的核心能力。 特别是在复杂分布式场景中&#xff0c;必须做到&#xff1a; &#x1f50d; 追踪每一条 SQL 的生命周期&#xff08;从入口到数据库执行&#xff09;&#…...

6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础

第三周 Day 3 &#x1f3af; 今日目标 理解类&#xff08;class&#xff09;和对象&#xff08;object&#xff09;的关系学会定义类的属性、方法和构造函数&#xff08;init&#xff09;掌握对象的创建与使用初识封装、继承和多态的基本概念&#xff08;预告&#xff09; &a…...