您的位置:首页 > 其它

第一个驱动程序之中断处理

2015-07-25 13:17 323 查看

一,初始化工作并创建工作队列。

概念:工作队列(work queue )是一种将工作推后执行的形式。我们把推后执行的任务叫做工作(work),描述它的数据结构为work_struct

,这些工作以队列结构组织成工作队列(workqueue),其数据结构为workqueue_struct,而工作线程就是负责执行工作队列中的工作。

使用场景:创建自己的工作队列来添加工作。

step1:声明工作处理函数、一个指向工作队列的指针以及工作变量:

void my_func();
struct workqueue_struct *p_queue;
struct work_struct my_work;


step2:创建自己的工作队列和工作结构体变量并初始化:

p_queue=create_workqueue("my_queue")或者使用p_queue=create_singlethread_workqueue("my_queue");
INIT_WORK(&my_work,my_func,&data);
说明:以上两个工作一般在request_irq函数申请中断前完成。


step3:将工作添加入自己创建的工作队列等待执行

queue_work(p_queue,&my_work);
说明:这个工作一般在request_irq函数中的中断处理函数中执行。


第四步:删除自己的工作队列

destroy_workqueue(p_queue);


二:中断函数定义。

中断函数中主要完成两个任务:保存当前中断寄存器数据和当前边沿触发方式以及清除这两个寄存器。

static void ralink_gpio7140_save_clear_intp(void);    //函数防止重复不断地进入中断处理函数。
queue_work(p_queue,&my_work);    //函数添加入自己创建的工作队列等待执行。
//共享中断中需要增加gpio num的判断.
if(!(ralink_gpio7140_intp & (1<<(g_gpio67.gpio_num - 40))))   {
printk("Have no key pressed...\n");
return -1;
}
if (ralink_gpio7140_edge & (1<<(g_gpio67.gpio_num - 40))) {
printk("set gpio value..\n");
//上升沿才有效,具体需要根据硬件设计。
g_gpio67.edge = e_gpio_rising;
g_gpio67.key_value = 1;
}


三:Work函数定义。

说明:由中断函数的queue_work进入my_work函数中并在此函数中实现具体的中断操作处理。

msp430按键中断:

1,通过i2c_smbus_read_byte_data接口读取msp430按键的中断event。

2,在1的条件下通过i2c_smbus_read_byte_data接口读取touch key的返回值。

3,转换为对应键值(msp430可识别的值)上报输入子系统。

四:中断申请。

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


第一个参数irq表示要分配的中断号,就我目前所接触的都是预先已经预定好的,还没试着通过探测或者动态来确定中断号

第二个参数handler是一个指针,指向处理这个中断的实际中断处理程序,只要操作系统一接收到中断,该函数就被调用,这个函数稍后讨论

第三个参数flags中断处理程序的标志,这个标志可以是一个也可以是多个,列举几个最重要的标志:

IRQF_DISABLED: 该标志被设置后,意味内核在处理中断处理程序本身的时候,禁止了其他所有的中断。如果不设置,中断处理程序可 以与除本身之外的其他任何中断同时运行。显而易见我们一般不去这么野蛮的设置这个标志

IRQF_TIMER:为系统定时器的中断处理而准备的

IRQF_SHARED:这个中断标志经常能遇见,这个标志意思就是多个中断处理程序之间可以共享中断线,概括起来就是没有这个标志就

只能独自一个人占用,标志了,就是很多人可以占用这个中断号来

第四个才参数就是自定义与中断设备相关的文本了

第五个参数dev,看到第三个参数中IRQF_SHARED时候,你会不会有这样的疑问,假如现在我要释放当前共享的指定这个中断程序时候,我如何

释放?会不会把其他占用也会删除掉,这就是第五个参数的意义,如果中断线是共享的,那么就必须传递能够代表当前设备的唯一信息

中断处理标志可以并用以下标志:

/*linux-2.6.29/include/linux/interrupt.h*/
29 #define IRQF_TRIGGER_NONE 0x00000000
30 #define IRQF_TRIGGER_RISING 0x00000001 //上升沿触发中断
31 #define IRQF_TRIGGER_FALLING 0x00000002 //下降沿触发中断
32 #define IRQF_TRIGGER_HIGH 0x00000004 //高电平触发中断
33 #define IRQF_TRIGGER_LOW 0x00000008 //低电平触发中断
34 #define IRQF_TRIGGER_MASK (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW | \
35 IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)
36 #define IRQF_TRIGGER_PROBE 0x00000010


request_irq()成功返回0,如果返回非0,就表示有错误发生,这个时候你可以考虑当前中断是否被占用了,所以可以加上IRQF_SHARED标志。

五:中断申请成功后初始化配置,启动中断模式。

set_7160_gpio_mode();             //set RGMII2_GPIO_MODE to gpio mode
set_7140_dir(0x01<<(67-40),0);     //set gpio67 to input
enable_intp();           //set pio enable interrupt
gpio_reg_irq(67);        //set Edge Interrupt mode



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: