如何在驱动中使用中断Word文档格式.docx

上传人:b****6 文档编号:16274536 上传时间:2022-11-22 格式:DOCX 页数:7 大小:18.57KB
下载 相关 举报
如何在驱动中使用中断Word文档格式.docx_第1页
第1页 / 共7页
如何在驱动中使用中断Word文档格式.docx_第2页
第2页 / 共7页
如何在驱动中使用中断Word文档格式.docx_第3页
第3页 / 共7页
如何在驱动中使用中断Word文档格式.docx_第4页
第4页 / 共7页
如何在驱动中使用中断Word文档格式.docx_第5页
第5页 / 共7页
点击查看更多>>
下载资源
资源描述

如何在驱动中使用中断Word文档格式.docx

《如何在驱动中使用中断Word文档格式.docx》由会员分享,可在线阅读,更多相关《如何在驱动中使用中断Word文档格式.docx(7页珍藏版)》请在冰豆网上搜索。

如何在驱动中使用中断Word文档格式.docx

中断时系统的稀缺资源,一旦不再使用,最好将中断号释放。

释放中断通过free_irq()实现。

与request_irq()一样,free_ire()函数在<

中声明,其函数原型如下:

voidfree_irq(unsignedintirq,void*dev_id)

第一个参数是将要释放的irq中断号。

第二个参数标志设备。

如果中断是该设备独占的,这里设置为NULL;

如果是共享中断,需要设置为中断处理程序指针。

3.设置触发条件

中断需要设置触发条件,如上升沿中断或者下降沿中断等。

Linux提设置触发条件的接口函数为irq_set_irq_type(),在<

linux/irq.h>

定义,函数原型为:

externintirq_set_irq_type(unsignedintirq,unsignedinttype);

irq为中断号,type为终端类型。

在<

中定义了如下中断类型:

IRQ_TYPE_NONE 

 

=0x00000000,

IRQ_TYPE_EDGE_RISING 

=0x00000001,

IRQ_TYPE_EDGE_FALLING 

=0x00000002,

IRQ_TYPE_EDGE_BOTH 

=(IRQ_TYPE_EDGE_FALLING|IRQ_TYPE_EDGE_RISING),

IRQ_TYPE_LEVEL_HIGH 

=0x00000004,

IRQ_TYPE_LEVEL_LOW 

=0x00000008,

IRQ_TYPE_LEVEL_MASK 

=(IRQ_TYPE_LEVEL_LOW|IRQ_TYPE_LEVEL_HIGH),

IRQ_TYPE_SENSE_MASK 

=0x0000000f,

IRQ_TYPE_PROBE 

=0x00000010,

通常情况下,一般采用边沿触发和电平触发类型,具体如何设置,还需与实际硬件匹配。

4.使能和禁止中断

如果没有在系统中使能中断,就算设置了触发条件,即使满足了触发条件也是不会产生中断的。

Linux下使能中断的函数为enable_irq(),在<

linux/interrupt.h>

中定义,函数原型如下:

externvoidenable_irq(unsignedintirq);

irq为需要使能的中断号。

5.禁止中断

如果一个中断使用完毕不再使用,可以将该中断禁止。

禁止中断的函数为disable_irq(),在<

externvoiddisable_irq(unsignedintirq);

irq为要禁止的中断号。

1.1.2中断处理程序编写

中断处理程序返回值irqreturn_t,接受两个参数:

中断号irq和dev_id,dev_id就是request_irq时传递给系统的参数dev:

typedefirqreturn_t(*irq_handler_t)(intirq,void*dev_id);

中断处理完毕,通常返回IRQ_HANDLED。

通常,一个中断处理程序如程序清单2.24所示。

程序清单2.24中断处理程序

staticirqreturn_txxxx_interrupt(intirq,void*dev_id)

{

...中断处理代码

returnIRQ_HANDLED;

/*中断已经处理完毕*/

}

至于中断处理程序要做些什么,应当做些什么,取决于具体系统的具体应用,没有统一的要求,但是中断处理程序应当尽量短,处理只能在中断上下文中处理的事情,能放到进程上下文的工作都不要放到中断上下文中处理。

1.1.3按键驱动

1.背景交代

本节提供的按键驱动范例基于EPC-28x工控主板。

EPC-28x硬件上有不少用户可用GPIO,本节选取其中一个GPIO,用作按键,并编写驱动,用于演示中断的基本用法。

本节范例按键对应的GPIO为GPIO2_6,对应IO在系统中的编号为70。

IO端口平时处于高电平,按键按下后为低电平。

Linux系统为每个中断都分配了一个编号。

i.MX28x处理器的每个IO端口都可以产生中断,IO引脚编号GPIOn和中断号IRQn之间的换算公式为:

IRQn=GPIOn+128,在代码中可通过gpio_to_irq函数来完成转换。

2.驱动实现

按键通常来说无需进行读写操作,也无需进行其它ioctl操作,因此,这些方法都无需实现。

范例程序仅仅实现了open、release和close三种方法,参考程序清单2.25。

第10~13的3个宏定义分别行定义了IO端口、中断编号和设备名称。

第20~26行列举了可用的中断触发条件,在代码中根据实际需要来使用。

根据硬件情况,代码中实际使用下降沿中断IRQ_TYPE_EDGE_FALLING。

范例代码中有一点需要说明一下,就是代码中使用了GPIO申请和释放函数,见第59行和108行。

在Linux系统中,为了防止某个IO被在多个地方被重复使用,在使用之前需通过gpio_request_one()函数进行申请。

在没有被释放之前,其它驱动程序是不能获得该IO端口的,能有效防止资源混乱。

使用完毕,可通过gpio_free()函数释放该端口。

程序清单2.25按键驱动范例

1#include<

linux/init.h>

2#include<

linux/module.h>

3#include<

linux/fs.h>

4#include<

linux/cdev.h>

5#include<

linux/device.h>

6#include<

7#include<

8#include<

linux/gpio.h>

9

10#defineKEY_GPIO 

70 

/*GPIO2_6 

*/

11#defineKEY_GPIO_IRQ 

gpio_to_irq(KEY_GPIO) 

/*中断号 

12#defineDEVICE_NAME 

"

key_irq"

13

14staticintmajor;

15staticintminor;

16structcdev*key_irq;

/*cdev数据结构 

17staticdev_tdevno;

/*设备编号 

18staticstructclass*key_irq_class;

19

20charconstirq_types[5]={

21 

IRQ_TYPE_EDGE_RISING,

22 

IRQ_TYPE_EDGE_FALLING,

23 

IRQ_TYPE_EDGE_BOTH,

24 

IRQ_TYPE_LEVEL_HIGH,

25 

IRQ_TYPE_LEVEL_LOW

26};

27

28staticintkey_irq_open(structinode*inode,structfile*file)

29{

30 

try_module_get(THIS_MODULE);

31 

printk(KERN_INFODEVICE_NAME"

opened!

\n"

);

32 

return0;

33}

34

35staticintkey_irq_release(structinode*inode,structfile*file)

36{

37 

closed!

38 

module_put(THIS_MODULE);

39 

40}

41

42staticirqreturn_tkey_irq_irq_handler(unsignedintirq,void*dev_id)

43{

44 

printk("

KEYIRQHAPPENED!

45 

returnIRQ_HANDLED;

46}

47

48structfile_operationskey_irq_fops={

49 

.owner 

=THIS_MODULE,

50 

.open 

=key_irq_open,

51 

.release=key_irq_release,

52};

53

54staticint__initkey_irq_init(void)

55{

56 

intret;

57

58 

gpio_free(KEY_GPIO);

59 

ret=gpio_request_one(KEY_GPIO,GPIOF_IN,"

KEYIRQ"

/*申请IO 

60 

if(ret<

0){

61 

printk(KERN_ERR"

FailedtorequestGPIOforKEY\n"

62 

}

63

64 

gpio_direction_input(KEY_GPIO);

/*设置GPIO为输入 

65 

if(request_irq(KEY_GPIO_IRQ,key_irq_irq_handler,IRQF_DISABLED,"

key_irqirq"

NULL))

/*申请中断*/

66 

printk(KERN_WARNINGDEVICE_NAME"

:

Can'

tgetIRQ:

%d!

KEY_GPIO_IRQ);

67 

68 

set_irq_type(KEY_GPIO_IRQ,irq_types[1]);

69 

disable_irq(KEY_GPIO_IRQ);

70 

enable_irq(KEY_GPIO_IRQ);

71

72 

ret=alloc_chrdev_region(&

devno,minor,1,DEVICE_NAME);

/*从系统获取主设备号 

73 

major=MAJOR(devno);

74 

75 

cannotgetmajor%d\n"

major);

76 

return-1;

77 

78

79 

key_irq=cdev_alloc();

/*分配key_irq结构 

80 

if(key_irq!

=NULL){

81 

cdev_init(key_irq,&

key_irq_fops);

/*初始化key_irq结构 

82 

key_irq->

owner=THIS_MODULE;

83 

if(cdev_add(key_irq,devno,1)!

=0){ 

/*增加key_irq到系统中 

84 

addcdeverror!

85 

gotoerror;

86 

87 

}else{

88 

cdev_allocerror!

89 

90 

91

92 

key_irq_class=class_create(THIS_MODULE,"

key_irq_class"

93 

if(IS_ERR(key_irq_class)){

94 

printk(KERN_INFO"

createclasserror\n"

95 

96 

97

98 

device_create(key_irq_class,NULL,devno,NULL,DEVICE_NAME);

99 

100

101error:

102 

unregister_chrdev_region(devno,1);

/*释放已经获得的设备号*/

103 

returnret;

104}

105

106staticvoid__exitkey_irq_exit(void)

107{

108 

109 

110 

free_irq(KEY_GPIO_IRQ,NULL);

111 

cdev_del(key_irq);

/*移除字符设备 

112 

/*释放设备号 

113 

device_destroy(key_irq_class,devno);

114 

class_destroy(key_irq_class);

115}

116

117module_init(key_irq_init);

118module_exit(key_irq_exit);

119

120MODULE_LICENSE("

GPL"

121MODULE_AUTHOR("

Chenxibing,linux@"

3.驱动测试

编译驱动后,将驱动模块插入系统,然后按下按键,可以看到按键中断发生并打印提示信息:

[root@EPC-28xmnt]#insmodkey_irq.ko

此时,查看/proc/interrupts文件,可以看到中断的发生次数:

[root@EPC-28xmnt]#cat/proc/interrupts

CPU0

...

220:

26 

GPIO 

key_irqirq

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 外语学习 > 英语学习

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1