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

嵌入式Linux学习: interrupt实验

Linux中的Interrupt(中断)系统是一个至关重要的组成部分,它负责管理和处理系统中发生的各种硬件和软件中断,确保系统能够正确响应外部设备的请求,保持系统的稳定性和可靠性。

1.中断的作用

  • 允许设备在没有CPU干预的情况下发送信号并请求处理。
  • 提高系统的并发处理能力,使CPU能够同时处理多个任务。
  • 确保系统能够及时响应外部设备的请求,保证系统的实时性和稳定性。

2. Linux中断子系统的组成与工作流程

  • 中断控制器:负责收集所有中断源发起的中断,并对中断进行初步处理,如优先级排序、中断分发等。
  • 中断处理函数:每个中断都会对应一个或多个中断处理函数,当中断发生时,CPU会暂停当前任务,跳转到相应的中断处理函数执行。
  • 中断描述符(irq_desc):用于描述IRQ(Interrupt Request,中断请求)线的属性与状态,是中断子系统中的重要数据结构。
  • 中断芯片(irq_chip):描述不同类型的中断控制器,提供与硬件中断控制器交互的接口。

3.特殊中断类型

  • SGI(Software Generated Interrupt):软件触发的中断,一般用于核间通信。
  • PPI(Private Peripheral Interrupt):私有外设中断,每个核心私有的中断。
  • SPI(Shared Peripheral Interrupt):共享外设中断,可以分发到某一个CPU上。
  • LPI(Locality-specific Peripheral Interrupt):GICv3中的新特性,基于消息的中断。

4. Linux 中断 API 函数

request_irq 函数

在 Linux 内核中要想使用某个中断是需要申请的,request_irq 函数用于申请中断,request_irq
函数可能会导致睡眠,因此不能在中断上下文或者其他禁止睡眠的代码段中使用 request_irq 函
数。 request_irq 函数会激活(使能)中断,所以不需要我们手动去使能中断, request_irq 函数原型
如下:

int request_irq(unsigned int irq,irq_handler_t handler,unsigned long flags,const char *name,void *dev)
/* irq:要申请中断的中断号。handler:中断处理函数,当中断发生以后就会执行此中断处理函数。flags:中断标志,可以在文件 include/linux/interrupt.h 里面查看所有的中断标志name:中断名字,设置以后可以在/proc/interrupts 文件中看到对应的中断名字。dev: 如果将 flags 设置为 IRQF_SHARED 的话, dev 用来区分不同的中断,一般情况下将dev 设置为设备结构体, dev 会传递给中断处理函数 irq_handler_t 的第二个参数。返回值: 0 中断申请成功,其他负值 中断申请失败,如果返回-EBUSY 的话表示中断已经被申请了。*/

flags中断标志介绍如下:

| 标志               | 描述                                                       			  |  
|--------------------|--------------------------------------------------------------|  
| IRQF_SHARED        | 允许多个设备共享同一个中断线,所有共享中断都需指定此标志,dev 参数为唯一区分标志         |  
| IRQF_PROBE_SHARED  | 类似IRQF_SHARED,但用于自动探测共享中断。不推荐使用              |  
| IRQF_TIMER         | 这是一个定时器中断                                              |  
| IRQF_IRQPOLL       | 驱动程序应使用慢速中断轮询                                      |  
| IRQF_ONESHOT       | 如果是共享中断,request_irq的dev参数应唯一,用于区分中断请求     |  
| IRQF_NO_SUSPEND    | 禁止在挂起期间禁用此中断                                       |  
| IRQF_FORCE_RESUME  | 强制在设备唤醒时重新启用中断,即使它被标记为IRQF_NO_SUSPEND      |  
| IRQF_NOBALANCING   | 不允许在CPU之间平衡此中断                                     |  
| IRQF_IRQ_DISABLED  | 中断被禁用(用于特殊目的的中断初始化)                         |  
| IRQF_PERCPU        | 中断是每CPU的(不支持共享)                                   |  
| IRQF_NO_THREAD     | 不要为中断创建线程(也称为“bottom half”)                     |  
| IRQF_EARLY_RESUME  | 允许在suspend-to-idle期间尽早恢复中断(与IRQF_NO_SUSPEND相关)   |  
| IRQF_TRIGGER_NONE  | 没有触发事件                                                 |  
| IRQF_TRIGGER_RISING | 上升沿触发                                                   |  
| IRQF_TRIGGER_FALLING| 下降沿触发                                                   |  
| IRQF_TRIGGER_HIGH  | 高电平触发                                                   |  
| IRQF_TRIGGER_LOW   | 低电平触发                                                   |  
| IRQF_TRIGGER_MASK  | 触发类型掩码(用于清除触发类型标志)                           |

free_irq 函数

使用中断的时候需要通过 request_irq 函数申请,使用完成以后就要通过 free_irq 函数释放
掉相应的中断。如果中断不是共享的,那么 free_irq 会删除中断处理函数并且禁止中断。

void free_irq(unsigned int irq,void *dev)
/*irq: 要释放的中断。dev:如果中断设置为共享(IRQF_SHARED)的话,此参数用来区分具体的中断。共享中断只有在释放最后中断处理函数的时候才会被禁止掉。返回值:无。
*/

5.interrupt子系统实验

注:本实验使用的是韦东山I.MX6U开发板

dts文件

/dts-v1/;
/{gpio_keys_100ask_imx6ull{compatible = "100ask,gpio_keys";gpios = <&gpio5 1 GPIO_ACTIVE_LOW&gpio4 14 GPIO_ACTIVE_LOW>;pinctrl-names = "default";pinctrl-0 = <&key1_pinctrl&key2_pinctrl>;status = "okay";};
};
&iomuxc_snvs {key1_pinctrl: key1_pinctrl {        /*!< Function assigned for the core: Cortex-A7[ca7] */fsl,pins = <MX6ULL_PAD_SNVS_TAMPER1__GPIO5_IO01        0x000110A0>;};
};&iomuxc {key2_pinctrl: key2_pinctrl {       /*!< Function assigned for the core: Cortex-A7[ca7] */fsl,pins = <MX6UL_PAD_NAND_CE1_B__GPIO4_IO14           0x000010B0>;};
}

100ask_imx6ull-14x14.dts 完成编写后,在(内核目录)编译dts文件

book@100ask:~/100ask_imx6ull-sdk/Linux-4.9.88$ make dtbs

将编译好的dtb文件拷贝到网络文件系统中

cp /home/book/100ask_imx6ull-sdk/Linux-4.9.88/arch/arm/boot/dts/100ask_imx6ull-14x14.dtb ~/nfs_rootfs/

#include "asm-generic/errno-base.h"
#include "asm-generic/int-ll64.h"
#include "asm/gpio.h"
#include "linux/compiler.h"
#include "linux/err.h"
#include "linux/export.h"
#include "linux/gpio/consumer.h"
#include "linux/interrupt.h"
#include "linux/ioport.h"
#include "linux/kdev_t.h"
#include "linux/leds.h"
#include "linux/of.h"
#include "linux/printk.h"
#include "linux/slab.h"
#include "linux/stddef.h"
#include <linux/types.h>
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/ide.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/cdev.h>
#include <linux/device.h>
#include <linux/of_gpio.h>
#include <linux/semaphore.h>
#include <linux/timer.h>
#include <linux/irq.h>
#include <linux/wait.h>
#include <linux/poll.h>
#include <linux/fs.h>
#include <linux/fcntl.h>
#include <linux/platform_device.h>
#include <asm/mach/map.h>
#include <asm/uaccess.h>
#include <asm/io.h>struct gpio_key{int gpio;enum of_gpio_flags flags;int irq;
};static struct gpio_key *gpio_keys;static irqreturn_t gpio_keys_100ask_irq(int irq, void *dev_id)
{struct gpio_key *gpio_key = dev_id;printk("key %d val %d\n", irq,gpio_get_value(gpio_key->gpio));return IRQ_HANDLED;
}/*   当驱动与设备连匹配成功时执行此函数   */
static int keys_probe (struct platform_device *pdv){int count,i,err;int gpio,irq;enum of_gpio_flags flags;struct device_node *node = pdv->dev.of_node;count = of_gpio_count(node); // 得到设备所使用的GPIO个数gpio_keys = kzalloc(count * sizeof(struct gpio_key), GFP_KERNEL);for(i = 0; i < count; i++){gpio = of_get_gpio_flags(node,i,&flags);irq = gpio_to_irq(gpio);gpio_keys[i].gpio = gpio;gpio_keys[i].irq = irq;gpio_keys[i].flags = flags;err = request_irq(irq, gpio_keys_100ask_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, "100ask_gpio_key", &gpio_keys[i]);if(err != 0){dev_err(&pdv->dev, "Could not get irq %d.\n", irq);}}return 0;
}static int keys_remove (struct platform_device *pdv)
{int i;for(i = 0; i < of_gpio_count(pdv->dev.of_node); i++){free_irq(gpio_keys[i].irq, &gpio_keys[i]);}kfree(gpio_keys);return 0;
}static struct of_device_id keys_match[] = {{.compatible = "100ask,gpio_keys"},{},
};static struct platform_driver keys_driver = {.probe = keys_probe,.remove = keys_remove,.driver = {.name = "key_driver",.of_match_table = of_match_ptr(keys_match),},
};static int __init keys_init(void)
{return platform_driver_register(&keys_driver);
}static void __exit keys_exit(void)
{platform_driver_unregister(&keys_driver);
}module_init(keys_init);
module_exit(keys_exit);MODULE_AUTHOR("Pumpk1n");
MODULE_LICENSE("GPL");
KERN_DIR = /home/book/100ask_imx6ull-sdk/Linux-4.9.88obj-m += keys_int_driver.oall: $(MAKE) -C $(KERN_DIR) M=`pwd` modulesclean:make -C $(KERN_DIR) M=`pwd` modules cleanrm -rf modules.order

执行命令: make

编译 keys_int_driver.c文件为 keys_int_driver.ko内核模块文件

拷贝文件到网络文件系统中

cp keys_int_driver.ko ~/nfs_rootfs/

串口连接开发板

挂载到网络文件系统中

[root@100ask:~]# mount -t nfs -o nolock,vers=3 192.168.5.11:/home/book/nfs_rootfs /mnt

将/mnt/100ask_imx6ull-14x14.dtb文件复制到/boot/下面

[root@100ask:~]# cp /mnt/100ask_imx6ull-14x14.dtb /boot/

重启开发板,等待重启完成后重新挂载网络文件系统中

[root@100ask:~]# reboot
[root@100ask:~]# mount -t nfs -o nolock,vers=3 192.168.5.11:/home/book/nfs_rootfs /mnt

进入到/mnt/目录中,并向内核加载模块文件keys_int_driver.ko

[root@100ask:~]# cd /mnt
[root@100ask:mnt]# insmod keys_int_driver.ko

设置内核消息的打印

echo "7 4 1 7" > /proc/sys/kernel/printk

按下按键key1,key2可分别在控制台打印消息

遇到的错误:

genirq: Flags mismatch irq 208. 00000003 (100ask_gpio_key) vs. 00000083 (User1 Button)

解决办法:

If you want to use the same irq number to register different interrupt handler, please use IRQ_SHARED flags.

 err = request_irq(irq, gpio_keys_100ask_irq, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING | IRQF_SHARED, "100ask_gpio_key", &gpio_keys[i]);

相关文章:

嵌入式Linux学习: interrupt实验

Linux中的Interrupt&#xff08;中断&#xff09;系统是一个至关重要的组成部分&#xff0c;它负责管理和处理系统中发生的各种硬件和软件中断&#xff0c;确保系统能够正确响应外部设备的请求&#xff0c;保持系统的稳定性和可靠性。 1.中断的作用 允许设备在没有CPU干预的情…...

GPT-4o mini 来袭:开发者如何驾驭新一代AI模型?

GPT-4o Mini 来袭&#xff1a;开发者如何驾驭新一代 AI 模型&#xff1f; 引言 随着人工智能&#xff08;AI&#xff09;技术的飞速发展&#xff0c;越来越多的先进模型不断涌现&#xff0c;给各行各业带来了深远的影响。OpenAI 最新推出的 GPT-4o Mini 是一种创新的 AI 模型…...

校园点餐系统

1 项目介绍 1.1 摘要 在这个被海量信息淹没的数字化时代&#xff0c;互联网技术以惊人的速度迭代&#xff0c;信息的触角无处不在&#xff0c;社会的脉动随之加速。每一天&#xff0c;我们都被汹涌而至的数据浪潮包裹&#xff0c;生活在一个全方位的数字信息矩阵中。互联网的…...

进口不锈钢309S螺栓的应用优势

进口不锈钢309S螺栓因其优异的性能和广泛的应用范围而在许多行业中备受青睐。309S不锈钢是一种含硫的易切削不锈钢&#xff0c;具有良好的耐高温和耐腐蚀性能&#xff0c;使其成为高温环境下理想的选择。下面我们就来详细探讨一下进口不锈钢309S螺栓的应用优势。 一、309S不锈钢…...

C# 设计模式之工厂方法模式

总目录 前言 本文是个人基于C#学习设计模式总结的学习笔记&#xff0c;希望对你有用&#xff01; 在简单工厂模式中说到了简单工厂模式的缺点&#xff1a;简单工厂模式系统难以扩展&#xff0c;一旦添加新产品就不得不修改简单工厂方法&#xff0c;这样就会造成简单工厂的实现…...

Webpack 从入门到精通

(创作不易&#xff0c;感谢有你&#xff0c;你的支持&#xff0c;就是我前行的最大动力&#xff0c;如果看完对你有帮助&#xff0c;请留下您的足迹&#xff09; 目录 一、Webpack 简介 二、Webpack 的核心概念 三、Webpack 的安装与配置 安装 Node.js 安装 Webpack 初始…...

基于VScode和C++ 实现Protobuf数据格式的通信

目录 1. Protobuf 概述1.1 定义1.2Protobuf的优势 2. Protobuf 语法3、序列号和反序列化3.1 .pb.h 头文件3.2 序列化3.3 反序列化 4、测试用例 Protobuf详细讲解链接 1. Protobuf 概述 1.1 定义 protobuf也叫protocol buffer是google 的一种数据交换的格式&#xff0c;它独立…...

linux环境openssl升级

1、下载openssl https://openssl-library.org/source/ 或者通过wget --no-check-certificate https://www.openssl.org/source/openssl-3.0.13.tar.gz 2、解压openssl tar -zxvf openssl-3.0.13.tar.gz 3、切换到解压后的目录 cd openssl-3.0.13/ 4、配置openssl安装目录…...

150Kg载重遥控履带式无人车技术详解

150Kg载重遥控履带式无人车是一种专为复杂地形和重载运输设计的无人化智能平台。它结合了先进的动力技术、履带式行走机构、远程遥控系统、高精度感知与导航技术及模块化设计&#xff0c;能够在恶劣环境下执行物资运输、侦察监视、灾害救援等多种任务。该车以其卓越的越野能力、…...

STM32的外部中断详解

一、什么是中断&#xff1f; 想象一下你正在家里做饭&#xff0c;突然门铃响了&#xff0c;你听到门铃声后&#xff0c;会暂时放下手中的事情&#xff08;比如炒菜&#xff09;&#xff0c;去开门看看是谁。在这个例子中&#xff0c;门铃声就是一个“中断”&#xff0c;它打断…...

关于python问题 ,生成的excel文件内无爬取的数据存在,请问应如何解决?

&#x1f3c6;本文收录于《CSDN问答解惑-专业版》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收…...

详细介绍Avalonia中的文件操作StorageProvider服务

文章目录 一、介绍二、StorageProvider的原理三、StorageProvider的实现1. 创建文件选择和保存对话框2. 选择目录四、StorageProvider的配置五、StorageProvider的高级用法1. 读取和写入文件2. 获取文件和目录信息3. 管理文件和目录4. 处理不同平台的差异六、总结一、介绍 在桌…...

「7.31更新日志」JVS·智能BI、逻辑、规则引擎功能更新说明

项目介绍 JVS是企业级数字化服务构建的基础脚手架&#xff0c;主要解决企业信息化项目交付难、实施效率低、开发成本高的问题&#xff0c;采用微服务配置化的方式&#xff0c;提供了 低代码数据分析物联网的核心能力产品&#xff0c;并构建了协同办公、企业常用的管理工具等&am…...

编程语言 | C | 代码整理 | 4月

八月拍了拍你&#xff0c;并对你说&#xff1a;“好运就要开始了”&#xff01; 目录 编程语言 | C | 代码整理 | 4月2019/4/12019/4/22019/4/22019/4/32019/4/42019/4/52019/4/62019/4/72019/4/82019/4/92019/4/102019/4/112019/4/122019/4/132019/4/142019/4/152019/4/162019…...

模板可变参数

当涉及到 C 编程中的模板参数处理时&#xff0c;特别是在处理可变数量的参数时&#xff0c;模板可变参数&#xff08;variadic templates&#xff09;是一个非常有用的特性。本篇博客将深入介绍模板可变参数的基本概念、语法、应用场景以及示例代码&#xff0c;帮助读者理解如何…...

是你!是你!我们的黄金写手!

...

QT 获取用于获取特定屏幕坐标处的最上层小部件(父与子关系的类)

QPoint globalPos pEvent->globalPos(); QWidget* widget QApplication::widgetAt(globalPos); 注意:屏幕坐标(包括显示器双屏)...

【应急响应】Linux权限维持 -隐藏权限

前言 不知攻焉知守&#xff0c;学会排查就要先学习如何攻击。 隐藏文件 Linux下创建一个隐藏文件&#xff1a;touch .test.txt 查看Linux下的隐藏文件需要用到命令&#xff1a;ls -al 隐藏文件时间戳 touch -r .docker hello.php 创建的hello.php文件会和.docker创建文件的时间…...

还有哪些AI应用案例目前备受关注

目前备受关注的AI应用案例众多&#xff0c;以下是一些代表性的例子&#xff1a; 1. WPS AI 背景&#xff1a;WPS AI是金山办公发布的基于大语言模型的人工智能办公助手&#xff0c;于2023年11月开启公测。 功能&#xff1a;WPS AI锚定AIGC&#xff08;内容创作&#xff09;、C…...

将控制台内容输出到文本文件

示例代码&#xff1a; Imports System.IO Module Module1Sub Main()Dim fs As New FileStream("D:\Desktop\test\输出结果.txt", FileMode.Create, FileAccess.Write, FileShare.None)Dim sw As New StreamWriter(fs)Console.SetOut(sw)Console.SetError(sw)For i …...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销&#xff0c;平衡网络负载&#xff0c;延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...

工程地质软件市场:发展现状、趋势与策略建议

一、引言 在工程建设领域&#xff0c;准确把握地质条件是确保项目顺利推进和安全运营的关键。工程地质软件作为处理、分析、模拟和展示工程地质数据的重要工具&#xff0c;正发挥着日益重要的作用。它凭借强大的数据处理能力、三维建模功能、空间分析工具和可视化展示手段&…...

【配置 YOLOX 用于按目录分类的图片数据集】

现在的图标点选越来越多&#xff0c;如何一步解决&#xff0c;采用 YOLOX 目标检测模式则可以轻松解决 要在 YOLOX 中使用按目录分类的图片数据集&#xff08;每个目录代表一个类别&#xff0c;目录下是该类别的所有图片&#xff09;&#xff0c;你需要进行以下配置步骤&#x…...

【VLNs篇】07:NavRL—在动态环境中学习安全飞行

项目内容论文标题NavRL: 在动态环境中学习安全飞行 (NavRL: Learning Safe Flight in Dynamic Environments)核心问题解决无人机在包含静态和动态障碍物的复杂环境中进行安全、高效自主导航的挑战&#xff0c;克服传统方法和现有强化学习方法的局限性。核心算法基于近端策略优化…...

GruntJS-前端自动化任务运行器从入门到实战

Grunt 完全指南&#xff1a;从入门到实战 一、Grunt 是什么&#xff1f; Grunt是一个基于 Node.js 的前端自动化任务运行器&#xff0c;主要用于自动化执行项目开发中重复性高的任务&#xff0c;例如文件压缩、代码编译、语法检查、单元测试、文件合并等。通过配置简洁的任务…...

关于uniapp展示PDF的解决方案

在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项&#xff1a; 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库&#xff1a; npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...

从零开始了解数据采集(二十八)——制造业数字孪生

近年来&#xff0c;我国的工业领域正经历一场前所未有的数字化变革&#xff0c;从“双碳目标”到工业互联网平台的推广&#xff0c;国家政策和市场需求共同推动了制造业的升级。在这场变革中&#xff0c;数字孪生技术成为备受关注的关键工具&#xff0c;它不仅让企业“看见”设…...

倒装芯片凸点成型工艺

UBM&#xff08;Under Bump Metallization&#xff09;与Bump&#xff08;焊球&#xff09;形成工艺流程。我们可以将整张流程图分为三大阶段来理解&#xff1a; &#x1f527; 一、UBM&#xff08;Under Bump Metallization&#xff09;工艺流程&#xff08;黄色区域&#xff…...