linux 按键混杂设备,Linux混杂设备驱动--按键设备驱动

1. Linux混杂设备驱动模型

① 在Linux系统中,存在一类字符设备,它们拥有相同的主设备号(10),但次设备号不同,我们称这类设备为混杂设备(miscdevice)。所有混杂设备形成一个链表,对设备访问时内核根据次设备号查找相应的混杂设备。

② Linux中使用struct miscdevice来描述混杂设备

structmiscdevice {intminor;const char *name;const struct file_operations *fops;structlist_head list;struct device *parent;struct device *this_device;

};

③ Linux中使用misc_register函数来注册一个混杂设备驱动

int misc_register(struct miscdevice * misc)

④ Linux中使用misc_deregister函数来注销一个混杂设备驱动

int misc_deregister(struct miscdevice *misc)

2. Linux按键设备驱动

① request_irq函数用于注册中断

int request_irq(unsigned int irq, void(*handler)(int, void*, struct pt_reg*), unsigned long flags, const char* devname, void* dev_id);

(1)irq:中断号

(2)handler:中断处理函数

(3)flags:与中断管理有关的各种选项

(4)devname :设备名

(5)dev_id:共享中断是使用,区分不同中断

(6)返回0表示成功,或者返回一个错误码

② 在flags参数中,可以选择一些与中断管理有关的选项

(1)IRQF_DESABLED(SA_INTERRUPT):如果改位置位,表示是一个“快速”中断处理程序;如果没有置位该位,是一个“慢速”中断处理程序

(2)IRQF_SHARED(SA_SHIRQ):该位表明中断号是被多个中断源共享的

③ 快、慢速中断的主要区别在于:快速中断保证中断处理的原子性(不被打断),而慢速中断则不保证。换句话说,也就是“开启中断”标志位(处理器IF位)在运行快速中断处理程序时是关闭的,因此在服务该中断时,不会被其他类型的中断打断;而调用慢速中断处理时,其它类型的中断仍可以得到服务

④ 中断处理程序的特别之处是在中断上下文中运行的,它的行为受到某些限制:

(1)不能使用可能引起阻塞的函数

(2)不能使用可能引起调度的函数

⑤ 当设备不再需要使用中断时(通常在卸载驱动时),应当把它注销,使用函数:

void free_irq(unsigned int irq, void* dev_id);

⑥ 进程上下文和中断上下文

(1)进程上下文:用户空间的应用程序,通过系统调用,进入内核空间。这个时候用户空间的进程要传递很多变量、参数的值给内核,内核态运行的时候也要保存用户进程的一些寄存器的值、变量等。所谓的“进程上下文”,可以看做是用户传递给内核的这些参数以及内核要保存的那一整套变量和寄存器的值以及当时的环境。

(2)中断上下文:用户通过触发信号,导致内核调用中断处理程序,进入内核空间。这个过程中,硬件的一些变量和参数也要传递给内核,内核通过这些参数进行中断处理。所谓的“中断上下文”,其实可以看做就是硬件传递过来的这些参数和内核需要保存的一些其他环境(主要是当前被打断执行的进程环境)

⑦ Linux按键设备驱动简单示例

48304ba5e6f9fe08f3fa1abda7d326ab.png

#include #include #include #include #include #include

#define GPGCON 0x56000060irqreturn_t key_int(int irq, void *dev_id)

{

//1. 检测是否发生了按键中断

//2. 清除已经发生的按键中断

//3. 打印按键值

printk("key down!

");

return 0;

}

void key_hw_init(void)

{

unsigned shortdata;

unsigned int *gpio_config;

gpio_config = ioremap(GPGCON, 4);

data =readw(gpio_config);

data &= ~0b11;

data |=0b10;

writew(data, gpio_config);

}

int key_open(struct inode *node, struct file *filp)

{

return 0;

}

struct file_operations key_fops ={

.open =key_open,

};

struct miscdevice key_miscdev ={

.minor = 200,

.name = "Mini2440Key",

.fops = &key_fops,

};

static int button_init(void)

{

misc_register(&key_miscdev);

//按键硬件初始化

key_hw_init();

//注册中断处理程序

request_irq(IRQ_EINT8, key_int, IRQF_TRIGGER_LOW, "Mini2440Key", 0);

return 0;

}

static void button_exit(void)

{

free_irq(IRQ_EINT8, 0);

misc_deregister(&key_miscdev);

}

module_init(button_init);

module_exit(button_exit);

48304ba5e6f9fe08f3fa1abda7d326ab.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值