70.linux驱动--中断

在之前的单片机入门的时候也是hello world,然后led,然后按键中断。

下面我们要开始中中断部分的学习。,在之前的裸机开发中,我们已经了解了中断的开发步骤,在内核中使用按键触发中断,会变的更容易一些,因为内核已经帮我们完成了很多工作,我们只需要理解整个调用及修改过程。

 

 

soc中有很多的中断,我们通过中断号进行区分是哪个中断,然后写对应的中断处理函数。

如何获取中断号?

1, 宏定义(中断相关的头文件)

                            IRQ_EINT(号码)

2,设备树文件中

                     arch/arm/boot/dts/exynos4412-fs4412.dts

一.怎么将按键中断添加到内核

在内核中,通过设备树对外设进行修改,关联。

1.

打开我们的设备树文件arch/arm/boot/dts/exynos4412-origen.dts

可以看到包含#include “exynos4412.dtsi”文件。打开这个文件。可以看到这个文件又包含

#include “exynos4x12.dtsi”,里面又包含#include “exynos4.dtsi”, “exynos4x12-pinctrl.dtsi”

我们打开exynos4x12-pinctrl.dtsi,

找到gpx1。

假如现在通过K3进行中断的相应,管脚对应EINT10,

在编程过程中,需要定义自己的节点--描述当前设备用的中断号

  arch/arm/boot/dts/exynos4412-origen.dts  //文件的64行添加自己的设备树节点。             

    key_int_node{
                compatible = "test_key";
                interrupt-parent = <&gpx1>;
                interrupts = <2 4>;//ENIT10 数据手册上标注是26,从设备树文件gpx1进行继承中我们    
                                     数是在第二组上,4是触发方式。
                };

2.

编译设备树文件:

              make dtbs

更新dtbs文件:

              cp -raf arch/arm/boot/dts/exynos4412- origen.dtb  /tftpboot/

3.

然后在串口终端中 /proc/device-tree/key

查看中断是否已经添加进来。

发现已经添加进来了。但是此时我们按按键,还是不会有任何反应的。

 

4.编写驱动

开始编写驱动之前先知道怎么通过程序获取中断号码?

(1)获取到设备树中到节点

      struct device_node *np = of_find_node_by_path("/key_int_node");

(2)通过节点去获取到中断号码

      int irqno = irq_of_parse_and_map(np, 0);

 如何申请中断?

函数(申请中断)  int request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags, const char * name, void * dev)
    参数

参数1: 设备对应的中断号

参数2: 中断的处理函数

                            typedef irqreturn_t (*irq_handler_t)(int, void *);

 参数3:触发方式

                            #define IRQF_TRIGGER_NONE    0x00000000  //内部控制器触发中断的时候的标志

                            #define IRQF_TRIGGER_RISING   0x00000001 //上升沿

                            #define IRQF_TRIGGER_FALLING 0x00000002 //下降沿

                            #define IRQF_TRIGGER_HIGH     0x00000004  // 高点平

                            #define IRQF_TRIGGER_LOW      0x00000008 //低电平触发

参数4:中断的描述,自定义,主要是给用户查看的

                            /proc/interrupts

参数5:传递给参数2中函数指针的值

              返回值: 正确为0,错误非0

  返回值:正确为0,错误非0

       

函数(释放中断)   void free_irq(unsigned int irq, void *dev_id)
    参数

参数1: 设备对应的中断号

参数2:与request_irq中第5个参数保持一致

代码实例:

key_dev.c

#include <linux/init.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_irq.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/fs.h>
#include <linux/device.h>

int irqno;

int get_irqno_from_node(void)
{
	// 获取到设备树中到节点
	struct device_node *np = of_find_node_by_path("/key_int_node");
	if(np){
		printk("find node ok\n");
	}else{
		printk("find node failed\n");
	}

	// 通过节点去获取到中断号码
	int irqno = irq_of_parse_and_map(np, 0);
	printk("irqno = %d\n", irqno);
	
	return irqno;
}
irqreturn_t key_irq_handler(int irqno, void *devid)
{
	printk("-------%s-------------\n", __FUNCTION__);

	return IRQ_HANDLED;
}

static int __init key_init(void)
{
	int ret;
	
	//获取中断号
	irqno = get_irqno_from_node();

	//申请中断
	ret = request_irq(irqno, key_irq_handler, IRQF_TRIGGER_FALLING|IRQF_TRIGGER_RISING, 
					"key3_eint10", NULL);
	if(ret != 0)
	{
		printk("request_irq error\n");
		return ret;
	}

	return 0;
}

static void __exit key_exit(void)
{
	free_irq(irqno, NULL);
}

module_init(key_init);
module_exit(key_exit);
MODULE_LICENSE("GPL");

Makefile

ROOTFS_DIR = /nfs/rootfs
#APP_NAME = chr_test

CROSS_COMPILE = /home/linux/Desktop/gcc-4.6.4/bin/arm-none-linux-gnueabi-
CC = $(CROSS_COMPILE)gcc

ifeq ($(KERNELRELEASE), )

KERNEL_DIR = /home/linux/mytest/linux-3.14
CUR_DIR = $(shell pwd)
 
all :
	make -C  $(KERNEL_DIR) M=$(CUR_DIR) modules
#	$(CC) $(APP_NAME).c  -o $(APP_NAME)
clean :
	make -C  $(KERNEL_DIR) M=$(CUR_DIR) clean
	
install:
	cp -raf *.ko   $(ROOTFS_DIR)/drv_module
 
else

obj-m += key_dev.o

endif

make 编译出ko文件

sudo make install //ko拷贝到nfs下

 

打开终端。

按下K3键

现在已经可以触发中断了,但是应用层想调用还是不行的,需要实现open read等函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux Wi-Fi驱动开发是一项高级技能,需要深入了解 Linux 内核和网络协议栈,以及具体的 Wi-Fi硬件设备和驱动程序。以下是一些步骤和技能,可以帮助你开始学习和开发 Linux Wi-Fi驱动程序: 1. 了解 Wi-Fi硬件和协议。Wi-Fi技术涉及到许多不同的标准和协议,包括 IEEE 802.11,WPA2加密等。了解这些协议和标准是必要的,以便理解 Wi-Fi驱动程序的工作原理。 2. 学习 Linux 内核网络协议栈。Wi-Fi驱动程序是内核的一个模块,它需要与网络协议栈紧密集成。因此,了解和熟悉 Linux 的网络协议栈是必要的。 3. 学习 Linux 内核编程。Wi-Fi驱动程序是内核的一个模块,因此需要掌握 Linux 内核编程的技能,包括模块编程、内存管理、进程管理等。 4. 学习 Wi-Fi驱动程序的开发技术。Wi-Fi驱动程序需要与具体的硬件设备紧密集成。因此,需要掌握如何编写和调试设备驱动程序、掌握硬件设备的 I/O 端口、中断处理和 DMA 等技术。 5. 学习 Wi-Fi驱动程序的调试技术。Wi-Fi驱动程序是一个非常复杂的系统,因此需要掌握如何使用调试工具(例如 GDB、SystemTap、LTTng 等)来调试和分析驱动程序的运行时错误。 总之,Linux Wi-Fi驱动开发需要掌握多个领域的知识和技能,包括网络协议、内核编程、硬件驱动程序等。如果你有相关的背景和经验,可以尝试学习和开发 Linux Wi-Fi驱动程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值