linux驱动学习-linux中断程序编写流程

本文介绍了Linux驱动中关于中断处理的知识,包括确定中断号、申请中断号、编写中断服务函数。强调中断的上下部分,上部分处理快速任务,下部分处理耗时任务。此外,还提到了软中断、Tasklet、工作队列和中断线程化的概念,这些都用于优化中断处理效率和响应时间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Linux中断:
1、确定中断号
2、申请中断号、request_irq 不用一定要释放free_irq
3、编写中断服务函数

request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,
            const char *name, void *dev)
{
    return request_threaded_irq(irq, handler, NULL, flags, name, dev);
}

中断的上下部:
request_irq 里的函数指针就是上部分
上部用于处理数度快的,系统占用不多的,这样可以使系统中断快进快出,下部分用于处理比较耗时的任务,类似于freertos中断中调用通知函数来通知任务函数来处理耗时任务,使得系统中断处理快速完成。
处理内容不能被打断,对时间敏感,与硬件相关这三类尽量放置在上部分,其他优先下部分。
软中断
谁先触发谁执行
softirq_action 结构体定义在文件 include/linux/interrupt.h
在 kernel/softirq.c 文件中一共定义了 10 个软中断
Tasklet

//上半部
irqfuc()
{
    tasklet_schedule(tasklet);
}
//下半部
tasklet_fuc()
{
    
}
//初始化
init_xxx()
{
    request_irq(irqfuc);
    tasklet_init(tasklet_fuc);
}

工作队列
将任务交给进程的上下文,交给内核的一个线程处理,对于任务可以休眠推后执行的可以使用工作队列,否则只能使用软中断

//上半部
irqfuc()
{
    schedule_work(workqueue);
}
//下半部
workqueue_fuc()
{
    //传入参数为 struct work_struct 没有私有数据,所以使用container_of 宏获取私有数据
}
//初始化
init_xxx()
{
    request_irq(irqfuc);
    INIT_WORK(workqueue, workqueue_fuc);
}

中断线程化

设备树中断节点信息 Documentation\devicetree\bindings\arm gic.tx下有详细介绍

1、Interrupt-cells<3> :每个interrupt有三个成员 
	gpio5: gpio@020ac000 {
	compatible = "fsl,imx6ul-gpio", "fsl,imx35-gpio";
	reg = <0x020ac000 0x4000>;
	interrupts = <GIC_SPI 74 IRQ_TYPE_LEVEL_HIGH>,
			 <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
	gpio-controller;
	#gpio-cells = <2>;
	interrupt-controller;//表示当前节点也为中断控制器
	#interrupt-cells = <2>;
};

fxls8471@1e {
		compatible = "fsl,fxls8471";
		reg = <0x1e>;
		position = <0>;
		interrupt-parent = <&gpio5>;
		interrupts = <0 8>;
	};
interrupt-parent表示父中断,interrupts 第一个是cells是gpio的编号即此时使用的是goio5_io00 第二个是中断触发方式 低电平触发
The 3rd cell is the flags, encoded as follows:
	bits[3:0] trigger type and level flags.
		1 = low-to-high edge triggered
		2 = high-to-low edge triggered (invalid for SPIs)
		4 = active high level-sensitive
		8 = active low level-sensitive (invalid for SPIs).

函数 unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
用于获取中断号,如果是使用gpio中断的话 int gpio_to_irq(unsigned int gpio) 来获取中断号

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值