linux驱动中断绑定核,Linux驱动中断学习

中断注册函数request_irq() 用来注册中断服务。在 2.4 内核中,需要包含的头文件是 #include ,2.6 内核中需要包含的头文件则是#include 。函数原型如下:

2.4 内核

intrequest_irq (unsignedintirq,void(*handler)(int,void*,structpt_regs *), unsignedlongfrags,constchar*device,void*dev_id);

2.6 内核

request_irq(unsignedintirq, irq_handler_t handler, unsignedlongflags,constchar*name,void*dev);

参数说明:

在发生对应于第 1个参数 irq 的中断时,则调用第 2 个参数 handler 指定的中断服务函数(也就是把 handler() 中断服务函数注册到内核中 )。第 3 个参数 flags 指定了快速中断或中断共享等中断处理属性。

在 2.6 教新的内核里(我的是 2.6.27 ~ 2.6.31 ),在 linux/interrupt.h 中定义操作这个参数的宏如下:

/*

* These flags used only by the kernel as part of the

* irq handling routines.

*

* IRQF_DISABLED - keep irqs disabled when calling the action handler

* IRQF_SAMPLE_RANDOM - irq is used to feed the random generator

* IRQF_SHARED - allow sharing the irq among several devices

* IRQF_PROBE_SHARED - set by callers when they expect sharing mismatches to occur

* IRQF_TIMER - Flag to mark this interrupt as timer interrupt

* IRQF_PERCPU - Interrupt is per cpu

* IRQF_NOBALANCING - Flag to exclude this interrupt from irq balancing

* IRQF_IRQPOLL - Interrupt is used for polling (only the interrupt that is

* registered first in an shared interrupt is considered for

* performance reasons)

*/

#define IRQF_DISABLED 0x00000020

#define IRQF_SAMPLE_RANDOM 0x00000040

#define IRQF_SHARED 0x00000080

#define IRQF_PROBE_SHARED 0x00000100

#define IRQF_TIMER 0x00000200

#define IRQF_PERCPU 0x00000400

#define IRQF_NOBALANCING 0x00000800

#define IRQF_IRQPOLL 0x00001000

第 4 个参数 name 通常是设备驱动程序的名称。改值用在 /proc/interrupt 系统 (虚拟) 文件上,或内核发生中断错误时使用。

第 5 个参数 dev_id 可作为共享中断时的中断区别参数,也可以用来指定中断服务函数需要参考的数据地址。

返回值:

函数运行正常时返回 0 ,否则返回对应错误的负值。

对于使用open firmware的系统中,驱动程序在执行ruquest_irq之前要先进行软硬件中断号的映射,具体通过如下函数实现:

irq_of_parse_and_map(struct device_node * dev, int index);

以PowerPC中的mpc83xx_sync.c为例:

staticintsync_ptp_init(void)

{

intresult;

structdevice_node *np;

np = of_find_compatible_node(NULL, NULL, "fsl,ucc-ptp");

if(!np) {

return-ENODEV;

}

ptp_virq = irq_of_parse_and_map(np, 1);  /* PTP2 IRQ */

ptp_rtc_virq = irq_of_parse_and_map(np, 2); /* RTC_IRQ */

...

returnresult;

}

通过函数

structdevice_node *of_find_compatible_node(structdevice_node *from,constchar*type,constchar*compatible);

根据compatible属性,获得设备结点。遍历Device Tree中所有的设备结点,看看哪个结点的类型、compatible属性与本函数的输入参数匹配,大多数情况下,from、type为NULL。再进行软硬中断号的映射。

staticinlineintenable_ptp(intport)

{

...

result = request_irq(ptp_virq, ptp_intr,

0, "ptp", &ptp_reg);

if(result 

printk(KERN_ERR "kjb::%s: register irq failed %d\n",

__FUNCTION__, result);

}

...

returnresult;

}

完成映射之后进行中断注册,这里以ptp_virq为例。相应的中断处理函数

staticirqreturn_t ptp_intr(intirq,void* _ptp)

{

u32 events;

KSYNC_DEBUG("ptp intr\n");

events = ptp_reg->ptp_tmr_pevent;

if(events & PTP_QE_TS_TX_FRAME1) {

structptp_ts ts;

intport = (ucc_port - 1) / 2;

ts.ts_low = ptp_reg->tmr_ucc_tx_l[port].ts;

ts.ts_high = ptp_reg->tmr_ucc_tx_h[port].ts;

tx_push_ts(&ts);

}

ptp_reg->ptp_tmr_pevent |= events;

returnIRQ_HANDLED;

疑问:中断的进入条件是什么?

参考:

http://www.cnblogs.com/alfredzzj/archive/2012/04/03/2431514.html

http://www.linuxidc.com/Linux/2011-08/40710.htm

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值