没有选择双面打印,还出来双面打印提示,每次复印还都出来一张白纸,怎么回事? 求迅速解答2天内要,谢谢
654
2022-05-30
由于中断信号的突发性,CPU要捕获中断信号,有两种方式。一是不断轮询是否有中断发生,这样有点傻;二是通过中断机制,过程如下:
中断源 ---> 中断信号 ---> 中断控制器 ---> CPU
中断源有很多,CPU拿到中断信号,如何区分是哪一个中断源产生?那么一定有一个序列,标识不同的中断源发出的信号,这就是中断号了。
在ARM裸机开发中,使用中断前需要进行不少配置,比较繁琐。而从内核的角度,我们只要明确两个目标
中断号
中断的处理方法
实验:在驱动中添加中断机制,按键触发外部中断,中断产生后,驱动打印中断信息。
步骤
定义中断号
在通过原理图,芯片手册查询,从硬件连接最终定位到中断号
通过源码,系统设备树描述中
每一个设备的节点都要有一个compatible属性 ,用来查找节点(也可以通过节点名或节点路径查找指定节点);interrupt-parent表示结点继承至gic。
root@linux:~/linux-3.14-fs4412# vim arch/arm/boot/dts/exynos4x12-pinctrl.dtsi
gpx1: gpx1 {
gpio-controller;
#gpio-cells = <2>;
interrupt-controller;
interrupt-parent = <&gic>;
interrupts = <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>,
<0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>;
#interrupt-cells = <2>;
};
手动定义设备树节点,参考上面的系统描述和硬件设备号。定义如下
root@linux:~/linux-3.14-fs4412# vim arch/arm/boot/dts/exynos4412-fs4412.dts
key_int_node{
compatible = "test_key";
interrupt-parent = <&gpx1>;
interrupts = <2 4>;
};
重新编译设备树,并更新tftp根目录下的设备树文件
make dtbs
cp -raf arch/arm/boot/dts/exynos4412-fs4412.dtb /tftpboot/
编写驱动代码
get_irqno_from_node函数通过设备树的路径到设备结点的中断号;然后request_irq申请中断,并设置触发方式是双边沿触发,key_irq_handler指定为中断处理函数;在key_irq_handler中只有一条打印信息,当中断产生,触发这条函数,打印信息;模块卸载时,通过free_irq释放掉之前申请的中断资源。
//key_drv.c
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
irqreturn_t key_irq_handler(int irqno, void *devid);
static 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;
}
static int __init key_drv_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_drv_exit(void)
{
//释放中断资源
free_irq(irqno, NULL);
}
irqreturn_t key_irq_handler(int irqno, void *devid)
{
printk("-------%s-------------\n", __FUNCTION__);
return IRQ_HANDLED;
}
module_init(key_drv_init);
module_exit(key_drv_exit);
MODULE_LICENSE("GPL");
Makefile文件
ROOTFS_DIR = /nfs/rootfs
ifeq ($(KERNELRELEASE), )
KERNEL_DIR = /mnt/hgfs/sharefolder/kernel/linux-3.14-fs4412
CUR_DIR = $(shell pwd)
all :
make -C $(KERNEL_DIR) M=$(CUR_DIR) modules
clean :
make -C $(KERNEL_DIR) M=$(CUR_DIR) clean
install:
cp -raf *.ko $(ROOTFS_DIR)/drv_module
else
obj-m += key_drv.o
endif
编译
Ubuntu环境编译,目标文件输出到nfs目录,nfs共享给开发板执行。
root@linux:/mnt/hgfs/sharefolder/kernel/linux-3.14-fs4412/drivers/mydrivers/chr_drv# make
root@linux:/mnt/hgfs/sharefolder/kernel/linux-3.14-fs4412/drivers/mydrivers/chr_drv# make install
实验结果
按下按键(1->0),触发一次中断。松下按键(0->1),又触发一次中断。
嵌入式
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。