itop-3568开发板驱动学习笔记(20)中断线程化

《【北京迅为】itop-3568开发板驱动开发指南.pdf》 学习笔记

文章目录

    • 中断线程化简介
    • 中断线程化 API
    • 中断线程化实验

中断线程化简介

中断线程化也是中断下文的一种方式,与工作队列和软中断不同的是,中断线程只用于这个中断,当发生中断的时候,会唤醒这个内核线程,然后由这个内核线程来执行中断下半部分的函数。

——原文

中断线程化 API

request_threaded_irq() 用来申请中断和中断线程,它和之前提到的 request_irq() 函数非常类似,仅仅多了一个 thread_fn 参数。

#include 
int request_threaded_irq(unsigned int irq, irq_handler_t handler, 
irq_handler_t thread_fn, unsigned long flags,const char *name, 
void *dev);

函数功能:向内核注册一个中断服务函数(当 irq 对应的中断发生时,会执行 handler 指向的中断服务函数)。

中断服务函数原型为:typedef irqreturn_t (*irq_handler_t)(int, void *)

函数参数

  • irq 中断号(在内核中是唯一的)
  • handler 中断服务函数指针
  • thread_fn 中断线程函数(为 NULL 表示不使用中断线程)
  • flags 中断标志,具体内容由中断源决定,如果中断源为外部中断,则存在上升沿和下降沿两种标志
  • name 中断名(会在 /proc/interrupts 下体现)
  • dev 中断服务函数的参数

返回值
返回 0 表示申请成功,失败返回负值。

中断线程化实验

实验代码

#include 
#include 
#include 
#include 
#include 

int irq;

//中断下文(中断线程函数)
irqreturn_t thread_func(int irq, void *args)
{
	msleep(1000);
	printk("This is inttrupt thread func.\n");
	return IRQ_RETVAL(IRQ_HANDLED);
}

//中断服务函数
irqreturn_t my_interrupt(int irq, void *args)
{
	printk("my interrupt handler.\n");	
	return IRQ_WAKE_THREAD; // 唤醒中断线程函数
	//return IRQ_RETVAL(IRQ_WAKE_THREAD); // 错误
}

static int interrupt_irq_init(void)
{
	int ret = 0;
	
	// 获取中断号
	irq = gpio_to_irq(101);
	printk("irq is %d\n", irq);

	// 申请中断(线程)
	ret = request_threaded_irq(irq, my_interrupt, thread_func, IRQF_TRIGGER_RISING, "inttrupt_test", NULL);
	if(ret < 0)
	{
		printk("request irq error.\n");
		return 0;
	}

	return 0;	
}

static void interrupt_irq_exit(void)
{
	printk("interrupt irq exit.\n");
	// 注销中断
	free_irq(irq, NULL);
}

module_init(interrupt_irq_init);
module_exit(interrupt_irq_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("xiaohui");

实验结果

和之前的软中断实验类似,在中断上文执行完成后,继续执行中断下文(中断线程函数)。

itop-3568开发板驱动学习笔记(20)中断线程化_第1张图片

你可能感兴趣的:(#,驱动开发(学习笔记),linux,驱动开发)