linux驱动之中断处理过程C程序部分

当发生中断之后,linux系统在汇编阶段经过一系列跳转,最终跳转到asm_do_irq()函数,开始C程序阶段的处理。在汇编阶段,程序已经计算出发生中断的中断号irq,这个关键参数最终传递给asm_do_irq()。linux驱动中断处理C程序部分,主要涉及linux中断系统数据结构的初始化和C程序的具体执行跳转。

一、中断处理数据结构

linux内核将所有的中断统一编号,使用一个irq_desc[NR_IRQS]的结构体数组来描述这些中断:每个数组项对应着一个中断源(可能是一个中断,也可能是一组中断),记录了中断的入口处理函数(不是用户注册的处理函数)、中断标记,并提供了中断的底层硬件访问函数(中断清除、屏蔽、使能)。另外,通过这个结构体数组项成员action,能够找到用户注册的中断处理函数。结构体irq_desc的数据类型在include/linux/irq.h中定义,内容如下:

struct irq_desc {
    irq_flow_handler_t    handle_irq;   /* 当前中断的处理函数入口 */
    struct irq_chip        *chip;       /* 低层的硬件访问 */
    struct msi_desc        *msi_desc;
    void            *handler_data;
    void            *chip_data;
    struct irqaction    *action;        /* 用户提供的中断处理函数链表 */
    unsigned int        status;         /* IRQ状态 */

    unsigned int        depth;          /* nested irq disables */
    unsigned int        wake_depth;     /* nested wake enables */
    unsigned int        irq_count;      /* For detecting broken IRQs */
    unsigned int        irqs_unhandled;
    spinlock_t        lock;
    const char        *name;            /* 中断名称 */
} ____cacheline_internodealigned_in_smp;

irq_desc成员变量handle_irq是这个或这组中断的入口处理函数,成员变量chip结构体包含了这个中断的清除、屏蔽或者使能等底层函数,结构体类型irq_chip的定义也在include/linux/irq.h中,内容如下:

struct irq_chip {
    const char    *name;
    unsigned int    (*startup)(unsigned int irq);
    void        (*shutdown)(unsigned int irq);
    void        (*enable)(unsigned int irq);
    void        (*disable)(unsigned int irq);

    void        (*ack)(unsigned int irq);
    void        (*mask)(unsigned int irq);
    void        (*mask_ack)(unsigned int irq);
    void        (*unmask)(unsigned int irq);
    const char    *typename;
};

irq_desc成员变量action记录了用户注册的中断处理函数、中断标志等等内容,其类型irqaction类型定义在include/linux/interrupt.h中,内容如下:

struct irqaction {
    irq_handler_t handler;       /* 用户注册的中断处理函数 */
    unsigned long flags;         /* 中断标志,是否共享中断,电平触发还是边沿触发等 */
    cpumask_t mask;              /* 用于SMP */
    const char *name;            /* 用户注册的中断名字,/proc/interrupts */
    void *dev_id;                /* 用户传递给handler的参数,还可以用来区分共享中断 */
    struct irqaction *next;      /* 指向下一个irqaciton结构体指针 */
    int irq;                     /* 中断号 */
    struct proc_dir_entry *dir;
};

用户注册的每个中断处理函数对应一个irqaciton结构体,一个中断源可以有多个处理函数(共享终端),它们的irqaciton结构体可以构成一个单项链表,irq_desc[irqn].action则是表头。irq_desc[NR_IRQS]结构体数组的构成情况如下图所示:

时间: 2024-12-18 19:27:59

linux驱动之中断处理过程C程序部分的相关文章

linux驱动之中断处理过程汇编部分

linux系统下驱动中,中断异常的处理过程,与裸机开发中断处理过程非常类似.通过简单的回顾裸机开发中断处理部分,来参考学习linux系统下中断处理流程. 一.ARM裸机开发中断处理过程 以S3C2440的裸机开发启动文件中,有关irq中断部分代码为例进行说明: .extern main .text .global _start _start: b Reset HandleUndef: b HandleUndef HandleSWI: b HandleSWI HandlePrefetchAbort

Linux内核system_call中断处理过程

在相应的test.c中添加getpid和getpid-asm的函数,使Menu实现getpid和getpid-asm的命令. 添加完成后,修改menu目录下的Makefile文件中的 qemu -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img变为qemu-system-i386 -kernel linux-3.18.6/arch/x86/boot/bzImage -initrd rootfs.img 然后执行在menu目录

第1个linux驱动___应用程序才是大Boss

我们的驱动模块已经可以被自动分配主设备号了,可以说到目前为止,一个驱动模块所具备的一些"基础设施"它都具备了,就像是养兵前日,用兵一时,已经可以让first_drv这个驱动模块出去打仗了. 那么说是出去打仗,总得有个发号施令的首长吧,在linux系统中,这位调兵遣将的首长就是应用程序,应用程序才是大Boss,我们"一直精雕细琢的驱动模块"说白了只是个跑腿的. 这就是为什么我们的专题是第1个linux驱动却要讲应用程序的原因,因为应用程序是让驱动程序能够被应用的,而驱

两篇让我理解linux驱动的文章及我的精练总结

第一篇 转载自csdn vipclx 编写Linux驱动八步骤 一.建立Linux驱动框架(装载.卸载Linux驱动) Linux内核在使用驱动时首先要装载驱动,在装载过程中进行一些初始化动作(建立设备文件.分配内存等),在驱动程序中需提供相应函数来处理驱动初始化工作,该函数须使用module_init宏指定:Linux系统在退出是需卸载Linux驱动,卸载过程中进行一些退出工作(删除设备文件.释放内存等),在驱动程序中需提供相应函数来处理退出工作,该函数须使用module_exit宏指定.Li

嵌入式Linux驱动开发实战视频教程

嵌入式Linux驱动开发实战教程(内核驱动.看门狗技术.触摸屏.视频采集系统)适合人群:高级课时数量:109课时用到技术:嵌入式 Linux涉及项目:驱动开发.看门狗技术.触摸屏.视频采集咨询qq:1840215592 课程介绍:本课程即是针对有兴趣学习嵌入式linux驱动开发又不知道从何处着实开始学习嵌入式linux驱动开发的在校同学以及社会在职人员.本课程采用理论教学与实验相结合的方式,软件与硬件相结合的方式,重点给大家讲解嵌入式linux驱动开发的方法,系统地介绍嵌入式linux驱动开发的

嵌入式Linux驱动开发实战教程

嵌入式Linux驱动开发实战教程(内核驱动.看门狗技术.触摸屏.视频采集系统) http://www.ibeifeng.com/goods-475.html 咨询QQ2110053820 课程讲师:韩老师 课程分类:Linux 适合人群:高级 课时数量:109课时 更新程度:完成 用到技术:嵌入式 Linux 涉及项目:驱动开发.看门狗技术.触摸屏.视频采集 课程简介:    嵌入式软件开发无疑是当今最热门的行业,嵌入式软件工程师的薪资比普通的软件工 程师的薪资平均高50%以上.随着智能控制.物

Linux内核分析—实验五分析system_call中断处理过程

郑斌 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 实验要求: 使用gdb跟踪分析一个系统调用内核函数(您上周选择的那一个系统调用),系统调用列表参见http://codelab.shiyanlou.com/xref/linux-3.18.6/arch/x86/syscalls/syscall_32.tbl ,推荐在实验楼Linux虚拟机环境下完成实验. 根据本周所学知识分析系

Linux kernel的中断子系统之(六):ARM中断处理过程

一.前言 本文主要以ARM体系结构下的中断处理为例,讲述整个中断处理过程中的硬件行为和软件动作.具体整个处理过程分成三个步骤来描述: 1.第二章描述了中断处理的准备过程 2.第三章描述了当发生中的时候,ARM硬件的行为 3.第四章描述了ARM的中断进入过程 4.第五章描述了ARM的中断退出过程 本文涉及的代码来自3.14内核.另外,本文注意描述ARM指令集的内容,有些source code为了简短一些,删除了THUMB相关的代码,除此之外,有些debug相关的内容也会删除. 二.中断处理的准备过

Linux驱动之触摸屏程序编写

本篇博客分以下几部分讲解 1.介绍电阻式触摸屏的原理 2.介绍触摸屏驱动的框架(输入子系统) 3.介绍程序用到的结构体 4.介绍程序用到的函数 5.编写程序 6.测试程序 1.介绍电阻式触摸屏的原理 所谓的电阻式触摸屏,只不过是在LCD屏幕上贴了一层膜,这层膜的大小与LCD的尺寸刚好相同,它分为上下两层膜(假设上层为X膜,下层为Y膜),按下膜的不同位置,会产生不同的电压值,这样根据不同的电压值可以确定触点的位置,这就是触摸屏的基本原理.其实是利用了最简单的电阻分压原理. 下面的图是四线式电阻触摸