码迷,mamicode.com
首页 > 其他好文 > 详细

6410-混杂设备驱动模型

时间:2015-09-20 20:45:49      阅读:206      评论:0      收藏:0      [点我收藏+]

标签:

1.混杂设备驱动模型
a.混杂设备描述
混杂设备概念:
在Linux系统中,存在一类字符设备,它们拥有相同的主设备号(10),但次设备号不同,我们称这类设备为混杂设备(miscdevice)。所有的混杂设备形成一个链表,对设备访问时内核根据混杂设备形成一个链表,对设备访问时内核根据次设备号查找到相应的混杂设备。
设备描述:
struct miscdevice {
int minor;//次设备号
const char *name;//设备名
const struct file_operations *fops;//文件操作
struct list_head list;
struct device *parent;
struct device *this_device;
const char *nodename;
mode_t mode;
};

b.混杂设备注册
int misc_register(struct miscdevice * misc)
也就是分为两步:首先初始化混杂设备,然后利用misc_register去注册混杂设备。

2.linux中断处理
a.裸机中断处理程序流程回顾
a.1中断有一个统一的入口:在linux内核中同样有一个统一的入口,它在entry_armv.S里面的irq_svc:->拿到产生中断源的编号-》根据中断号找到irq_desc(对应的中断)->irq_desc中取出事先注册好的中断处理函数-》action->action会直接找到handler(里面存放有用户的中断处理程序)。
驱动程序做的事:1.实现中断处理程序;2.注册中断;3.注销处理

a.2事先注册中断处理程序
注册中断:
request_irq(unsigned int irq, irq_handler_t handler, unsigned long flags,const char *name, void *dev)
返回0表示成功,否则返回乱码.
unsigned int irq //中断号。
void (*handler)(int,void *) //中断处理函数。
unsigned long flags //与中断管理有关的各种选项。
const char * devname //设备名
void *dev_id //共享中断时使用

在flags参数中,可以选择一些与中断管理有关的选项,如:
? IRQF_DISABLED(SA_INTERRUPT)
如果设置该位,表示是一个“快速”中断处理程序;如果没有设置这位,那么是一个“慢速”中断处理程序。
? IRQF_SHARED(SA_SHIRQ)
该位表明该中断号是多个设备共享的

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

中断处理程序的特别之处是在中断上下文中运行的,它的行为受到某些限制:
1.不能使用可能引起阻塞的函数
2.不能使用可能引起调度的函数

a.3根据中断源编号调用中断处理程序
检查设备是否产生了中断-》清除中断产生标志-》相应的硬件操作。
注销中断:当设备不再需要使用中断时(通常在驱动卸载时), 应当把它们注销, 使用函数:
void free_irq(unsigned int irq, void *dev_id):对于共享中断,需要提供中断号和dev_id号。

b.linux中断处理流程分析
c.linux中断处理程序设计
irqreturn_t key_int(int irq,void *dev_id)
{
//1.检查是否发生了按键中断,因为此处只有一个中断,因此不需要进行检测。

//2.清除已经发生的按键中断,硬件内部的需要清除中断,但按键属于处理器级别,因此不需要清除中断。如网卡芯片就需要清除中断。

//3.打印按键值
}

3.按键驱动硬件操作实现
参考裸机中断的代码:button.c:gpio功能的选择,设为外部中断;硬件的初始化可以在open函数和模块初始化的函数中完成。

c.范例驱动分析
touch key.c
chmod 777 -R ./

#include<linux/module.h>
#include<linux/init.h>
#include<linux/miscdevice.h>
#include<linux/interrupt.h>
#include<linux/io.h>
#include<linux/fs.h>


#define GPFCON 0x7F880030 //驱动程序中不能使用物理地址,必须将其转化为虚拟地址。

irqreturn_t key_int(int irq,void *dev_id)//使用前面的类型需要加头文件
{
//1.检查是否发生了按键中断

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

//3.打印按键值
printk("key_down!\n");
}

void key_hw_init()
{
unsigned int = gpio_config;
unsigned short data;
//将物理地址转化为虚拟地址
gpio_config = ioremap(GPFCON,4);
data = readw(gpio_config);//取出寄存器中的值
data &= ~0b11;//对寄存器中的相应的位进行清除
data |= 0b10;//对相应的位进行设置
writew(data,gpio_config);将data的值写入寄存器中
}

int key_open(struct inode *node,struct file *file)
{
return 0;
}
stuct miscdevice key_miscdev = {
.minor = 200,
.name = "key",
.fops = &key_fops,
};

struct file_operations key_fops = //加头文件fs.h
{
.open = key_open,

};
static int key_init()
{
//注册混杂设备
misc_register(&key_miscdev);
//注册中断处理程序IRQF_TRIGGER_FALLING//表示中断是由高电平到低电平时产生的中断。也就是按键按下的时候产生的中断。中断号:不同于裸机,首先我们要找与开发板对应的irqs.h头文件,在头文件中有
register_irq(S3C_EINT(0),key_int,IRQF_TRIGGER_FALLING,"key",0);
//按键初始化
key_hw_init();
}

static void key_exit()
{
//注销混杂设备
misc_deregister(&key_miscdev);
//注销中断处理程序
free_irq(S3C_EINT(0),0);
}

module_init(key_init);
module_exit(key_exit);

6410-混杂设备驱动模型

标签:

原文地址:http://www.cnblogs.com/defen/p/4823969.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!