rk3568中断irq

前言

本文记录的是在rk3568开发板通过按键中断的实验了解和学习linux中断irq


一、Linux中断简介

在单片机中,中断的过程:
①、使能中断,初始化相应的寄存器
②、编写中断服务函数,中断发生以后相应的中断服务函数就会执行。在 Linux 内核中也提供了大量的中断相关的 API 函数,我们来看一下这些跟中断有关的API 函数:
在Linux驱动中:

1.1 request_irq 函数

(1)中断号:每个中断都有一个中断号,通过中断号即可区分不同的中断,有的资料也把中断号叫做中断线,在 Linux 内核中使用一个 int 变量表示中断号。
(2)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 里面查看所有的中断标志,这里我们
介绍几个常用的中断标志,如表 所示:

IRQF_SHARED多个设备共享一个中断线,共享的所有中断都必须指定此标志。如果使用共享中断的话,request_irq 函数的 dev 参数就是唯一区分他们的标志。
IRQF_ONESHOT单次中断,中断执行一次就结束。
IRQF_TRIGGER_NONE无触发
IRQF_TRIGGER_RISING上升沿触发。
IRQF_TRIGGER_FALLING下降沿触发。
IRQF_TRIGGER_HIGH高电平触发。
IRQF_TRIGGER_LOW低电平触发。

这些标志可以通过“|”来实现多种组合。
Linux 按键输入实验》中使用 GPIO3_C5 这个 IO,通过将此 IO 接到 3.3V模拟按键按下,也就是按下以后为高电平,因此可以设置为上升沿触发,也就是将 flags 设置为IRQF_TRIGGER_RISING。
name:中断名字,设置以后可以在/proc/interrupts 文件中看到对应的中断名字。
dev:如果将 flags 设置为 IRQF_SHARED 的话,dev 用来区分不同的中断,一般情况下将dev 设置为设备结构体,dev 会传递给中断处理函数 irq_handler_t 的第二个参数。
返回值:0 中断申请成功,其他负值 中断申请失败,如果返回-EBUSY 的话表示中断已经被申请了。

1.2 free_irq 函数

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

void free_irq(unsigned int irq, void *dev_id)

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

1.3 中断处理函数

使用 request_irq 函数申请中断的时候需要设置中断处理函数,中断处理函数格式如下所示:

irqreturn_t (*irq_handler_t) (int, void *)

第一个参数是要中断处理函数要相应的中断号。
第二个参数是一个指向 void 的指针,也就是个通用指针,需要与 request_irq 函数的 dev_id 参数保持一致。用于区分共享中断的不同设备,dev_id 也可以指向设备数据结构。中断处理函数的返回值为 irqreturn_t 类型,irqreturn_t 类型定义如下所示:

irqreturn_t 结构enum irqreturn {IRQ_NONE = (0 << 0),IRQ_HANDLED = (1 << 0),IRQ_WAKE_THREAD = (1 << 1),};typedef enum irqreturn irqreturn_t;

可以看出 irqreturn_t 是个枚举类型,一共有三种返回值。一般中断服务函数返回值使用如下形式:

return IRQ_RETVAL(IRQ_HANDLED) 

1.4 中断使能与禁止函数

常用的中断使用和禁止函数如下所示:

void enable_irq(unsigned int irq)
void disable_irq(unsigned int irq)

enable_irq 和 disable_irq 用于使能和禁止指定的中断,irq 就是要禁止的中断号。disable_irq函数要等到当前正在执行的中断处理函数执行完才返回,因此使用者需要保证不会产生新的中断,并且确保所有已经开始执行的中断处理程序已经全部退出。在这种情况下,可以使用另外一个中断禁止函数:

void disable_irq_nosync(unsigned int irq)

disable_irq_nosync 函数调用以后立即返回,不会等待当前中断处理程序执行完毕。上面三
个函数都是使能或者禁止某一个中断,有时候我们需要关闭当前处理器的整个中断系统,也就
是在学习 STM32 单片机的时候常说的关闭全局中断,这个时候可以使用如下两个函数:

local_irq_enable()//不建议使用
local_irq_disable()//不建议使用

建议使用以下API来全局打开或者关闭中断

local_irq_save(flags)
local_irq_restore(flags)

1.5 获取中断号

编写驱动的时候需要用到中断号,我们用到的中断号,中断信息已经写到了设备树里面,
因此可以通过 irq_of_parse_and_map 函数从 interupts 属性中提取到对应的设备号,函数原型如下:

unsigned int irq_of_parse_and_map(struct device_node *dev, int index)

函数参数和返回值含义如下:
dev:设备节点。
index:索引号,interrupts 属性可能包含多条中断信息,通过 index 指定要获取的信息。
返回值:中断号。
如果使用 GPIO 的话,可以使用 gpio_to_irq 函数来获取 gpio 对应的中断号,函数原型如下:

int gpio_to_irq(unsigned int gpio)

函数参数和返回值含义如下:
gpio:要获取的 GPIO 编号。
返回值:GPIO 对应的中断号。

二、上半部与下半部

我们在使用request_irq 申请中断的时候注册的中断服务函数属于中断处理的上半部,只要中断触发,那么中断处理函数就会执行。
上半部:上半部就是中断处理函数,那些处理过程比较快,不会占用很长时间的处理就可以放在上半部完成。
下半部:如果中断处理过程比较耗时,那么就将这些比较耗时的代码提出来,交给下半部去执行,这样中断处理函数就会快进快出。
这里有一些可以借鉴的参考点:
①、如果要处理的内容不希望被其他中断打断,那么可以放到上半部。
②、如果要处理的任务对时间敏感,可以放到上半部。
③、如果要处理的任务与硬件有关,可以放到上半部
④、除了上述三点以外的其他任务,优先考虑放到下半部。
上半部处理很简单,直接编写中断处理函数就行了,关键是下半部该怎么做呢?Linux 内
核提供了多种下半部机制,接下来我们来学习一下这些下半部机制。

2.1 下半部机制——软中断(不建议)

softirq_action结构体定义在文件 include/linux/interrupt.h 中,内容如下:

代码如下(示例):

 struct softirq_action{void (*action)(struct softirq_action *);};

在 kernel/softirq.c 文件中一共定义了 10 个软中断,如下所示:
示例代码 15.1.2.2 softirq_vec 数组

static struct softirq_action softirq_vec[NR_SOFTIRQS];

NR_SOFTIRQS 是枚举类型,定义在文件 include/linux/interrupt.h 中,定义如下:

示例代码 15.1.2.3 softirq_vec 数组
enum
{HI_SOFTIRQ=0, /* 高优先级软中断 */TIMER_SOFTIRQ, /* 定时器软中断 */NET_TX_SOFTIRQ, /* 网络数据发送软中断 */NET_RX_SOFTIRQ, /* 网络数据接收软中断 */BLOCK_SOFTIRQ, IRQ_POLL_SOFTIRQ, TASKLET_SOFTIRQ, /* tasklet 软中断 */SCHED_SOFTIRQ, /* 调度软中断 */HRTIMER_SOFTIRQ, /* 高精度定时器软中断 */RCU_SOFTIRQ, /* RCU 软中断 */NR_SOFTIRQS
};

要使用软中断,必须先使用 open_softirq 函数注册对应的软中断处理函数,open_softirq 函数原型如下:

void open_softirq(int nr, void (*action)(struct softirq_action *))

函数参数和返回值含义如下:
nr:要开启的软中断,在示例代码 15.1.2.3 中选择要开启的软中断。
action:软中断对应的处理函数。
返回值:没有返回值
注册好软中断以后需要通过 raise_softirq 函数触发,raise_softirq 函数原型如下:

void raise_softirq(unsigned int nr)

函数参数和返回值含义如下:
nr:要触发的软中断,在示例代码 15.1.2.3 中选择要注册的软中断。
返回值:没有返回值。
软中断必须在编译的时候静态注册!Linux 内核使用 softirq_init 函数初始化软中断,
softirq_init 函数定义在 kernel/softirq.c 文件里面,函数内容如下:

示例代码 15.1.2.4 softirq_init 函数内容
625 void __init softirq_init(void)
626 {
627 int cpu;
628
629 for_each_possible_cpu(cpu) {
630 per_cpu(tasklet_vec, cpu).tail =
631 &per_cpu(tasklet_vec, cpu).head;
632 per_cpu(tasklet_hi_vec, cpu).tail =
633 &per_cpu(tasklet_hi_vec, cpu).head;
634 }
635
636 open_softirq(TASKLET_SOFTIRQ, tasklet_action);
637 open_softirq(HI_SOFTIRQ, tasklet_hi_action);
638 }

从示例代码 15.1.2.4 可以看出,softirq_init 函数默认会打开 TASKLET_SOFTIRQ 和HI_SOFTIRQ

2.2 下半部机制——tasklet(建议)

在软中断和 tasklet 之间,建议大家使用 tasklet。tasklet_struct 结构体如下所示:

示例代码 15.1.2.5 tasklet_struct 结构体
542 struct tasklet_struct
543 {
544 struct tasklet_struct *next; /* 下一个 tasklet */
545 unsigned long state; /* tasklet 状态 */
546 atomic_t count; /* 计数器,记录对 tasklet 的引用数 */
547 void (*func)(unsigned long); /* tasklet 执行的函数 */
548 unsigned long data; /* 函数 func 的参数 */
549 };

第 547 行的 func 函数就是 tasklet 要执行的处理函数,用户实现具体的函数内容,相当于中断处理函数。
如果要使用 tasklet,必须先定义一个 tasklet_struct 变量,然后使用 tasklet_init 函数对其进行初始化,taskled_init 函数原型如下:

void tasklet_init(struct tasklet_struct *t,
void (*func)(unsigned long), 
unsigned long data);

函数参数和返回值含义如下:
t&#x

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

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

相关文章

美洽工作台3.0,全新发布!

美洽工作台3.0&#xff0c;全新发布 想要效率翻倍&#xff0c;就要一步到位&#xff01; 工作台 3.0&#xff0c;为效率而生 1. 更丰富的外观选择&#xff0c;让界面焕然一新&#xff0c;新增导航主题色选择&#xff0c;深色 Dark、浅色 Light 随意切换 2. 自定义你的专属导…

Python 识别图片形式pdf的尝试(未解决)

想识别出pdf页面右下角某处的编号。pdf是图片形式页面。查了下方法&#xff0c;有源码是先将页面提取成jpg&#xff0c;再用pytesseract提取图片文件中的内容。 直接用图片来识别。纯数字的图片&#xff0c;如条形码&#xff0c;可识别。带中文的不可以&#xff0c;很乱。 识别…

[12] 使用 CUDA 加速排序算法

使用 CUDA 加速排序算法 排序算法被广泛用于计算应用中有很多排序算法,像是枚举排序或者说是秩排序、冒泡排序和归并排序,这些排序算法具有不同的(时间和空间)复杂度,因此对同一个数组来说也有不同的排序时间,对于大数组而言,可能会很耗时如果排序算法能用 CUDA 加速,则…

吴恩达深度学习笔记:机器学习(ML)策略(1)(ML strategy(1))1.3-1.4

目录 第三门课 结构化机器学习项目&#xff08;Structuring Machine Learning Projects&#xff09;第一周 机器学习&#xff08;ML&#xff09;策略&#xff08;1&#xff09;&#xff08;ML strategy&#xff08;1&#xff09;&#xff09;1.3 单一数字评估指标&#xff08;S…

Linux|如何安装 Java

引言 Java是最受欢迎的编程语言之一&#xff0c;JVM&#xff08;Java的虚拟机&#xff09;是运行Java应用程序的运行时环境。这两个平台是许多流行软件所需的&#xff0c;包括Tomcat&#xff0c;Jetty&#xff0c;Cassandra&#xff0c;Glassfish和Jenkins。 本教程[1]将指导您…

实验名称:文件数据存储练习

一手好牌硬打。 目录 一、实验目的 二、实验环境 三、实验步骤 四、实验结果 1.图片备份 2.将文件中所有的小写字母转换成大写字母&#xff0c;将所有的大写字转换成小写字母 3.完成班级学生成绩的录入&#xff0c;并保存在csv文件中。 4.获得csv文件中的成绩&#xf…

java 若依框架使用介绍

若依框架是一个开源的后台管理系统&#xff0c;用了2周最大的感觉就是比较轻量级的&#xff0c;有多种不同的版本&#xff0c;如前后端分离、微服务、移动端版本&#xff0c;集成了简单的代码生成器&#xff0c;入门比起jeecgboot要稍微更加简单一些。 官网地址&#xff1a;ht…

2024年应用经济学、管理科学与社会国际学术会议(ICAEMSS 2024)

2024年应用经济学、管理科学与社会国际学术会议&#xff08;ICAEMSS 2024&#xff09; 会议简介 2024年应用经济学、管理科学与社会国际学术会议将聚焦应用经济学和管理科学的前沿问题&#xff0c;深入探讨社会变革中的经济管理与科学应用。参会者将分享最新研究成果&#xf…

短剧小程序App系统源码:打造个性化追剧体验

随着数字媒体的迅猛发展&#xff0c;短剧作为一种新兴的娱乐形式&#xff0c;越来越受到广大观众的喜爱。为了满足用户对短剧内容的个性化需求&#xff0c;短剧小程序App系统应运而生。本文将深入探讨短剧App源码的核心功能&#xff0c;以及如何通过多语言支持和国际支付等技术…

超声波洗眼镜机是智商税吗?四款不能错过的超声波清洗机实力种草

在日常生活中&#xff0c;眼镜成为了我们不可或缺的伙伴&#xff0c;无论是阅读书籍、工作还是享受自然风光&#xff0c;清晰的视野总是至关重要。然而&#xff0c;眼镜上不可避免地会沾染灰尘、油脂甚至细菌&#xff0c;影响我们的视觉体验。传统的眼镜清洗方法虽然简单&#…

雷池WAF《动态防护》功能体验

一、雷池简介&#xff08;官方&#xff09; 自 2016 年起&#xff0c;长亭就开源了雷池的语义分析算法自动机引擎&#xff0c;随后又陆续开源了雷池相关风控插件和引擎通信协议。雷池的商业版本自发布以来&#xff0c;得到了各大咨询机构和众多顶级企业的认可。然而&#xff0…

MT3050 区间最小值

思路&#xff1a; 使用ST表 ST模板可参考MT3024 maxmin 代码&#xff1a; 1.暴力9/10&#xff1a; #include <bits/stdc.h> using namespace std; const int N 1e5 10; int n, m; int a[N]; int main() {ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);cin …

Java的垃圾回收算法详解

在Java编程语言中&#xff0c;垃圾回收&#xff08;Garbage Collection, GC&#xff09;是一个至关重要的概念&#xff0c;它负责自动管理内存&#xff0c;释放不再使用的对象所占用的空间&#xff0c;从而防止内存泄漏和溢出。下面我们将从技术难点、面试官关注点、回答吸引力…

2024精选热门骨传导耳机推荐,你不会还不挑选吧?

骨传导耳机作为最近两年来才兴起的耳机品类&#xff0c;在街头的出现频率并不是很高&#xff0c;很多人对骨传导耳机不够了解甚至没听说过。骨传导耳机不入耳的设计&#xff0c;安全性、舒适性和稳定性都更高&#xff0c;既然有这么多的优势&#xff0c;那就为大家挑选几款高性…

leetcode-[704]二分查找[27]移除元素

一、[704]二分查找 //二分法&#xff1a;有序 //[left,right] 故判定条件为left < right,等于此时有意义&#xff1b; //缩小范围 leftmid1&#xff1b; //right nums.length-1; //不要忘了修改mid 的值class Solution {public int search(int[] nums, int target) {int le…

16. 最接近的三数之和 - 力扣

1. 题目 给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数&#xff0c;使它们的和与 target 最接近。 返回这三个数的和。 假定每组输入只存在恰好一个解。 2. 示例 3.分析 做这道题目前&#xff0c;先做这道&#xff1a;三数之和 &#x…

【归档】git使用

教材 廖雪峰博客 时间 2022年8月11日 13:39:52 - 2022年8月11日 15:59:53 学习过程 在开始学习之前&#xff0c;我首先对Git的不同区域概念进行了深入理解&#xff1a; 工作区&#xff1a;这是我们进行编辑和修改的地方&#xff0c;但这些修改尚未被跟踪。暂存区&#xf…

手动操作Telnet不嫌累?要不试一下我自制的自动执行指令Telnet工具吧!

网管小贾 / sysadm.cc 昨天发生了一件事&#xff0c;我现在仍记忆犹新。 一大早我就被秘书喊进了胡总的办公室…… 一进门&#xff0c;只见我们部门的赖经理也在。 我打完招呼&#xff0c;胡总就问我&#xff0c;最近调到我们部门实习的小王表现如何。 我偷偷瞥了一眼赖经理…

【已有项目版】uniapp项目发版pda -- Android Studio

必备资料清单&#xff1a; 构建完成的app项目 在HBuilderX开发的uniapp项目 .keystore文件 文章目录 1. 安装Android Studio&#xff1a;https://developer.android.google.cn/studio?hlzh-cn2. 安装Android 离线SDK&#xff1a;https://nativesupport.dcloud.net.cn/AppDocs…

短期业绩波动较大被券商不予评级,金种子酒背靠华润如何发力?

《港湾商业观察》施子夫 王璐 虽然一季度成功实现了扭亏为盈&#xff0c;但从近些年年报来看&#xff0c;金种子酒&#xff08;600199.SH&#xff09;的业绩压力依然不容小觑。白酒主业萎靡不振时&#xff0c;金种子酒开始了剥离非主营业务。 这些措施能否有利于主业向好&am…