Linux Kernel threaded irq

Linux源代码阅读:request_irq() 本文尝试阅读Linux kernel 5.0 + ARM64上中断申请过程的源代码,但并非逐字逐句地解析,只是梳理一些关键点(在工作中经常可能会用到的知识点)。 为了提升Linux的实时性,kernel引入了中断线程化概念。其实就是将中断的下半部放在内核线程(FIFO,也称实时进程)中执行,这样可以减少中断对高优先级进程的饥饿感。因为传统的中断上半部执行完成后,需要通过tasklet,或者softirq来执行中断下半部,这些都属于中断上下文,会被内核优先处理,这样就会导致进程产生饥饿,即使是优先级比较高的 阅读详情

1.How-to

request_threaded_irq()
{
action->handler = handler;
action->thread_fn = thread_fn;
->__setup_irq()
{
/*
* Create a handler thread when a thread function is supplied
* and the interrupt does not nest into another interrupt
* thread.
*/
if (new->thread_fn && !nested) {
struct task_struct *t;


t = kthread_create(irq_thread, new, "irq/%d-%s", irq,
  new->name);

adb shell ps -P -p
可以看到创建的 irq thread:
USER     PID   PPID  VSIZE  RSS   PRIO  NICE  RTPRI SCHED  PCY  WCHAN    PC        NAME
root      57    2     0      0     -51   0     50    1     fg  c0100ac8 00000000 S irq/102-msm_iom
root      58    2     0      0     -51   0     50    1     fg  c0100ac8 00000000 S irq/102-msm_iom
root      59    2     0      0     -51   0     50    1     fg  c0100ac8 00000000 S irq/102-msm_iom
root      60    2     0      0     -51   0     50    1     fg  c0100ac8 00000000 S irq/79-msm_iomm
root      61    2     0      0     -51   0     50    1     fg  c0100ac8 00000000 S irq/78-msm_iomm
root      62    2     0      0     -51   0     50    1     fg  c0100ac8 00000000 S irq/78-msm_iomm
root      63    2     0      0     -51   0     50    1     fg  c0100ac8 00000000 S irq/74-msm_iomm
root      64    2     0      0     -51   0     50    1     fg  c0100ac8 00000000 S irq/75-msm_iomm
root      65    2     0      0     -51   0     50    1     fg  c0100ac8 00000000 S irq/75-msm_iomm
root      66    2     0      0     -51   0     50    1     fg  c0100ac8 00000000 S irq/273-msm_iom
root      67    2     0      0     -51   0     50    1     fg  c0100ac8 00000000 S irq/273-msm_iom
root      68    2     0      0     -51   0     50    1     fg  c0100ac8 00000000 S irq/273-msm_iom
root      69    2     0      0     -51   0     50    1     fg  c0100ac8 00000000 S irq/97-msm_iomm
root      70    2     0      0     -51   0     50    1     fg  c0100ac8 00000000 S irq/97-msm_iomm
root      71    2     0      0     -51   0     50    1     fg  c0100ac8 00000000 S irq/97-msm_iomm
root      77    2     0      0     -51   0     50    1     fg  c0100ac8 00000000 S irq/402-mba
root      78    2     0      0     -51   0     50    1     fg  c0100ac8 00000000 S irq/530-wcnss
root      134   2     0      0     -51   0     50    1     fg  c0100ac8 00000000 S irq/335-main_tt

2.什么时候执行

产生中断之后先执行中断对应的 hard handler, 之后根据hard handler中断服务程序是否返回 IRQ_WAKE_THREAD flag决定是否执行中断对应的thread_fn。
(下半部tasklet 也是在hard handler 中断服务程序中执行tasklet_schedule()触发的)
执行流程是下面这个样子的:
 

handle_irq_event_percpu()
->
trace_irq_handler_entry(irq, action);
res = action->handler(irq, action->dev_id);
trace_irq_handler_exit(irq, action, res);
->
switch (res) {
case IRQ_WAKE_THREAD:
/*
* Catch drivers which return WAKE_THREAD but
* did not set up a thread function
*/
if (unlikely(!action->thread_fn)) {
warn_no_thread(irq, action);
break;
}


irq_wake_thread(desc, action);


->static void irq_wake_thread(struct irq_desc *desc, struct irqaction *action)
{
wake_up_process(action->thread);




->
/*
 * Interrupt handler thread
 */
static int irq_thread(void *data)
{
static const struct sched_param param = {
.sched_priority = MAX_USER_RT_PRIO/2,
};
sched_setscheduler(current, SCHED_FIFO, &param);//irq thread 优先级比ksoftirqd/N 高很多
->
ret = action->thread_fn(action->irq, action->dev_id);

 

3. 一个threaded irq 典型的例子

static irqreturn_t ads7846_hard_irq(int irq, void *handle)
{
	struct ads7846 *ts = handle;

	return get_pendown_state(ts) ? IRQ_WAKE_THREAD : IRQ_HANDLED;
}


static irqreturn_t ads7846_irq(int irq, void *handle)
{
	struct ads7846 *ts = handle;

	/* Start with a small delay before checking pendown state */
	msleep(TS_POLL_DELAY);

	while (!ts->stopped && get_pendown_state(ts)) {

		/* pen is down, continue with the measurement */
		ads7846_read_state(ts);

		if (!ts->stopped)
			ads7846_report_state(ts);

		wait_event_timeout(ts->wait, ts->stopped,
				   msecs_to_jiffies(TS_POLL_PERIOD));
	}

	if (ts->pendown) {
		struct input_dev *input = ts->input;

		input_report_key(input, BTN_TOUCH, 0);
		input_report_abs(input, ABS_PRESSURE, 0);
		input_sync(input);

		ts->pendown = false;
		dev_vdbg(&ts->spi->dev, "UP\n");
	}

	return IRQ_HANDLED;
}


static int __devinit ads7846_probe(struct spi_device *spi)
{
err = request_threaded_irq(spi->irq, ads7846_hard_irq, ads7846_irq,
  irq_flags, spi->dev.driver->name, ts);

这个驱动既申请了 hard handler(ads7846_hard_irq) 也申请了thread_fn(ads7846_irq)。

Linux中断子系统(五)之中断线程化与共享中断的实战解析 本文深入解析Linux中断子系统中的中断线程化与共享中断机制。通过对比传统中断处理,详细阐述了request_threaded_irq如何将中断处理分为快速响应的硬中断和可调度的内核线程,以提升系统实时性。同时,结合IRQF_SHARED与IRQF_ONESHOT标志,剖析了多设备共享同一中断线的实现原理、潜在问题与ARM平台实战配置策略。 阅读详情

相关推荐

【RK3588 Linux 5.x 内核编程】-内核中断与ThreadedIRQ

ThreadIRQ为Linux内核下半部分处理机制之一。本文将详细介绍如何使用ThreadIRQ。

视觉与物联智能 722

RT_Thread按键中断学习笔记

以下通过pin驱动来大概介绍rtthread驱动程序的编写方法 1. RT_thread提供了下面的几个函数(PIN设备管理接口)来访问GPIO,如下: 函数 描述 rt_pin_mode() 设置引脚模式 rt_pin_write() 设置引脚电平 rt_pin_read() 读取引脚电平 rt_pin_attach_irq() 绑定引脚中断回调函数 rt_pin_irq_enable() 使能引脚中断 rt_pin_detach_irq() 脱离引脚中...

lbaihao的专栏 3513

HI3403烧录全流程:从ToolPlatform安装到eMMC配置避坑指南

本文详细介绍了海思HI3403芯片的完整烧录流程,涵盖从ToolPlatform工具安装、驱动配置到eMMC分区策略的实战指南。文章深入解析了BurnTool工具的使用方法、关键配置项,并提供了烧录过程中的常见问题排查与解决方案,旨在帮助开发者高效、稳定地完成HI3403嵌入式系统的部署。

weixin_29279101的博客 333

Linux内核-中断知识汇总(重温)

TODO。

静虚待令,有物混成 3103

QGIS基于快鸟(QuickBird)影像统计小麦种植面积

​01数据情况 本次选用某地4月份快鸟(QuickBird)影像为例,使用QGIS演示提取小麦播种情况,并按照200米*200米分区计算种植面积的过程。 注:本文对应的操作视频作为今天第二篇推送同时发布,习惯看视频的朋友可以点击观看。 附数据压缩包: 链接:https://pan.baidu.com/s/1JVUS8uAOR61RxC1n9Or9_w 提取码:qgis 含快鸟影像QB_subset.tif和200*200米分区矢量图层200Mgrid.shp。 ...

QGISClass的博客 1979

【数学模型】灰色关联分析

数学模型-灰色关联分析

suic009的博客 1万+

Linux下的内核线程threaded irq机制分析与应用

我们知道,工作队列可以用来处理中断的一些耗时的事情,但是他又一个缺点,就是如果有多个事件同时放入工作队列中,如果前面的事件处理得太久,那么就会影响到后面的事件的执行,因为内核线程事一个个依次执行的,如果一个事件真的非常耗时间,那么我们可以用 threaded irq来处理,大概意思就是中断上半部不变,中断的下半部用一个内核线程来替代tasklet,这个内核线程专门负责来执行某一个中断。...

szembed的博客 737

LTE 中设置voice/data centric的差异

1. 什么是voice centric和data centric Voice centric和data centric的差别在于以语音为中心还是以数据为中心。这里的以某某为中心可不是说说而已。举个栗子,UE一般搜网注册都会按照LUG(LTE->UMTS->GSM)或者LC(LTE->CDMA)的顺序进行,如果UE(未开通VOLTE)注册到LTE时,网络提示不支持语音,比如CSFB。UE就必须disable LTE后回到GU或者CDMA,否则留在不能语音的网络下,UE就会...

alimingh的博客 5234

申请中断request_irq()与request_threaded_irq()之间的不同?

在linux里,中断处理分为顶半(top half),底半(bottom half),在顶半里处理优先级比较高的事情,要求占用中断时间尽量的短,在处理完成后,就激活底半,有底半处理其余任务。底半的处理方式主要有soft_irq, tasklet, workqueue三种,他们在使用方式和适用情况上各有不同。soft_irq用在对底半执行时间要求比较紧急或者非常重要的场合,主要为一些subsystem用,一般driver基本上用不上。 tasklet和work queue在普通的driver里用的相对较多,主

gnnulzy的博客 3251

Ubuntu18.04黑屏救急指南:从tty到图形界面的5种恢复方法(附网络配置技巧)

本文针对Ubuntu 18.04系统启动后出现黑屏并进入tty命令行的问题,提供了一套从紧急诊断到完全恢复图形化界面的系统性实战指南。文章详细讲解了五种核心恢复方法,包括重启显示管理器、重装ubuntu-desktop桌面环境、手动安装Xorg与LightDM等,并重点解决了纯命令行环境下的网络配置难题,帮助用户快速修复系统,恢复工作环境。

weixin_29243279的博客 359

STM32入门教程:车牌识别

在本文中,我们介绍了如何使用STM32实现车牌识别功能,并提供了详细的代码案例。通过以上步骤,你可以开始开发自己的车牌识别系统了。希望本文对你有所帮助!

2401_85258012的博客 874

request_threaded_irq()

http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=21977330&id=3755609 在linux里,中断处理分为顶半(top half),底半(bottom half),在顶半里处理优先级比较高的事情,要求占用中断时间尽量的短,在处理完成后,就激活底半,有底半处理其余任务。底半的处理方式主要有soft_irq, taskle

xiaopohaibebo的专栏 600

【2025CSPJ普及组】T4. 多边形

【2025CSPJ普及组】T4. 多边形【题目描述】小 R 喜欢玩小木棍。小 R 有 n 根小木棍,第i(1≤i≤n) 根小木棍的长度为 ai。

lybc2019的博客 849

Linux kernel中断子系统之(五):驱动申请中断API

一、前言 本文主要的议题是作为一个普通的驱动工程师,在撰写自己负责的驱动的时候,如何向Linux Kernel中的中断子系统注册中断处理函数?为了理解注册中断的接口,必须了解一些中断线程化(threaded interrupt handler)的基础知识,这些在第二章描述。第三章主要描述了驱动申请 interrupt line接口API request_threaded_irq的规格。第四章

新时代农民工 871

最新Python爬虫实战(入门爬虫篇)——案例13:某乎热榜数据采集(详细爬虫思路截图+抓包动图演示+完整爬虫代码+详细注释)

本次案例通过Python爬虫技术,成功实现了基于Cookies认证的某乎热榜数据爬取与Excel保存。代码采用模块化设计,包含Cookies解析、HTML请求、结构化解析、Excel持久化等完整流程;通过配置浏览器请求头+Cookies认证,有效突破某乎基础反爬策略,保证请求稳定性。整个爬虫逻辑遵循“Cookies认证 → 页面请求 → HTML解析 → 数据清洗 → 保存到Excel”的标准流程,与需要会话验证的网站爬取范式高度一致。Cookies解析与认证。

努力让自己发光,对的人才能迎着光而来 33万+

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

linux中断流程

启动内核函数: init/main.c start_kernel 函数 里面有 trap_init(); //设置异常处理向量,包括中断,某些linux 版本是 setup_arch——early_trap_init init_IRQ(); //初始化中断 我们看下 early_trap_init 中间我们省略了很多,我们可以看到 void __init early_tra...

连志安 882

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

linux AArch64异常(中断)处理流程

linux ARM V8异常/中断处理流程1 异常向量表1.1 Vector table offsets from vector table base address1.2 linux arm64 异常向量表代码1.2.1 异常向量表1.2.2 kernel_ventry2 中断处理2.1 硬件中断号和软件中断号的区别2.2 中断注册函数2.2.1 request_irq2.2.2 request_threaded_irq2.3 中断上半部处理流程2.3.1 el1_irq2.3.2 kernel_entr

天使之翼 2382

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Linux中断子系统框架流程详解(基于Kernel 3.16,arm,设备树)

这里主要讲3点,1. 中断的初始化详细过程;2. request_irq、request_threaded_irq等中断函数的注册;3. 硬件中断产生时从中断向量入口开始的处理流程。写博客不易,如若转载,请注明出处。 一、中断控制器的初始化详细过程 从main.c (init) 中的 asmlinkage __visible void __init start_kernel(void)开始,看...

ZHONGkunjia的专栏 1284

《Linux 设备驱动开发详解:基于最新的 Linux 4.0 内核》 第 10 章 Linux 设备驱动中的中断与时钟

参考:宋宝华 著,机械工业出版社,2015年版。

qq_40843427的博客 728

linux中断申请之request_threaded_irq

在linux里,中断处理分为顶半(top half),底半(bottomhalf),在顶半里处理优先级比较高的事情,要求占用中断时间尽量的短,在处理完成后,就激活底半,有底半处理其余任务。底半的处理方式主要有soft_irq,tasklet,workqueue三种,他们在使用方式和适用情况上各有不同。soft_irq用在对底半执行时间要求比较紧急或者非常重要的场合,主要为一些subsystem用,

pillarbuaa的专栏 1473

kernel bug汇总

开发过程中,遇到的kernel bug汇总 中断响应不及时,中断信号丢失 使用request_threaded_irq代替request_irq 参考博文:https://blog.youkuaiyun.com/mcsbary/article/details/103728816 BUG: scheduling while atomic BUG: scheduling while atomic 分析 B...

卓越之路 2002

linux kernel的中断子系统之(九):tasklet

转载:http://www.wowotech.net/irq_subsystem/tasklet.html 一、前言 对于中断处理而言,linux将其分成了两个部分,一个叫做中断handler(top half),属于不那么紧急需要处理的事情被推迟执行,我们称之deferable task,或者叫做bottom half,。具体如何推迟执行分成下面几种情况: 1、推迟到top half执

ls152121349的专栏 336

Linux中断关于 request_threaded_irq

--------------------------------------------------------------------- 1. 重要接口 内核维护了一个中断信号线的注册表,该注册表类似于I/O端口的注册表。模块在使用中断前要先请求一个中断通道(或者中断请求IRQ),然后在使用后释放该通道。 撇开系统如何遍历各个设备进行初始化,上面两句话说的实际上就是指两个接口函数:

L_zy的专栏 5002

request_threaded_irq与request_irq

request_threaded_irq 先来看头文件的申明。 文件:include/linux/interrupt.h extern int __must_check request_threaded_irq(unsigned int irq, irq_handler_t handler, irq_handler_t thread_fn, unsigned long flags, const char *name, void *dev); static inline int

bruk_spp的博客 1398

申请中断request_irq()与request_threaded_irq()之间的区别?

一、申请中断函数原型 int request_threaded_irq(unsigned int irq, irq_handler_thandler, irq_handler_t thread_fn,                        unsigned long irqflags,const char *devname, void *dev_id) ======》 reque

Fybon的专栏 1万+
上一篇: Linux Kernel 下半部 软中断 tasklet
下一篇: linux kernel ftrace 之wakeup tracer and wakeup_rt tracer
windtakers
博客等级 码龄17年 94粉丝 197原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值