[RK3399][Android7.1] 调试笔记-中断(工作队列)

平台 内核版本 安卓版本
RK3399 Linux4.4 Android7.1

设备树

/ {
	my_test_node {
		compatible = "test_platform";
		irq_gpio = <&gpio0 GPIO_B1 IRQ_TYPE_EDGE_FALLING>;
	};
};

中断

中断底半部机制有三种:

  • 工作队列
  • tasklet
  • 软中断

三者的主要区别

机制 运行位置 特点
软中断、tasklet 软中断上下文 处理函数中不能睡眠
工作队列 进程上下文 处理函数中允许睡眠

设备树

/ {
	my_test_node {
		compatible = "test_platform";
		irq_gpio = <&gpio0 GPIO_B1 IRQ_TYPE_EDGE_FALLING>;
	};
};

工作队列

工作队列一般用来做滞后的工作,比如在中断里面要做很多事,但是比较耗时,这时就可以把耗时的工作放到工作队列。说白了就是系统延时调度的一个自定义函数。

static int int_probe(struct platform_device *pdev)
{
	int ret;
	int irq_pin;
	struct device_node *node = pdev->dev.of_node;

	/* 获取DeviceTree中配置的引脚 */
	irq_pin = of_get_named_gpio(node, "irq_gpio", 0);

	/* 引脚有效则将其转换为对应的IRQ */
	if (gpio_is_valid(irq_pin)) {
		printk("irq pin valid = %d\n", irq_pin);
		g_irq = gpio_to_irq(irq_pin);
	} else {
		printk("irq gpio NOT valid\n");
	}

	 /* 申请IQR,成功后可在/proc/interrupts里看到相关信息 */
	ret = request_irq(g_irq , test_irq_handler, IRQF_TRIGGER_LOW|IRQF_DISABLED , "my_test_irq", NULL);
	if (ret) {
		printk("request irq error\n");
		return -1;
	}
	/* 创建一个工作结构体变量,并将处理函数和参数的入口地址赋给这个工作结构体变量 */
	/* struct work_struct  g_irq_work */
	INIT_WORK(&g_irq_work, test_irq_work);

	printk("Probe ok\n");

	return 0;
}

其中
INIT_WORK会在你定义的_work工作队列里面增加一个工作任务,该任务就是_func

将工作结构体变量添加入系统的共享工作队列

static irqreturn_t test_irq_handler(int irq, void *data)
{
	disable_irq_nosync(irq);
	(void)schedule_work(&g_irq_work);
	return IRQ_HANDLED;
}

发布了270 篇原创文章 · 获赞 95 · 访问量 13万+

猜你喜欢

转载自blog.csdn.net/qq_33487044/article/details/104418807