int request_irq(unsigned int irq,
irqreturn_t (*handler)(int,void*,struct pt_regs*),
unsigned long flags,
const char *dev_name,void*dev_id);
/*irq:要申请的中断号
* handler:中断处理函数
* flags:若值为SA_SHIRQ,表明是申请的共享中断
* dev_name:用来在/proc/interrutps文件中来现实中断的拥有者
* dev_id:驱动程序可以用它来指向驱动程序自己的私有数据(用来标识哪个设备产生中断),在没有使用共享方式时,可以为NULL,但若是共享方式,则必须赋值
*/
/*先来看个没有使用共享中断线的情况*/
int short_open(struct indoe*inode,struct file*filp)
{
struct short_dev *dev=hwinfo+MINOR(inode->i_rdev);
int short_irq=dev->irq;
if(short_irq>=0)
result=request_irq(short_irq,short_interrup,SA_INTERUTP,"short",NULL);/*flags为SA_INTERRUPT*/
.....;
}
irqreturn_t short_interrup(int irq,void*dev_id,struct pt_regs *regs)
{
struct timeval t; /*该中断处理函数主要是读取当前时间,然后把它输入到
某个缓冲区,然后唤醒任何一个读取进程,告诉该进程现
在有新的数据可以读了*/
int written;
do_gettimeofday(&tv);
written=sprintf((char*)short_head,"%08u.%06u\n",tv....);
....;
wake_up_interruptible(&short_queue);/*唤醒在short_queue上阻塞的进程
short_queue是驱动自己的队列
*/
return IRQ_HANDLED;/*正常返回*/
}
/*可以看到,没有共享的情况很简单,注册后直接调用handle处理就ok了
* 在来看共享irq的情况
*/
int short_open(struct indoe*inode,struct file*filp)
{
struct short_dev *dev=hwinfo+MINOR(inode->i_rdev);
int short_irq=dev->irq;
if(short_irq>=0)
result=request_irq(short_irq,short_interrup,SA_SHARD,"short",NULL);/*flags为共享标识*/
.....;
}
irqreturn_t short_interrup( int irq,void*dev_id,struct pt_regs *regs)
{
/*这里就通过dev_id来判断是否是本设备的有中断
*
* 注意,其实当这个共享的irq线上有中断来时,它所有的
*
* xxx_interrupt函数都会被调用(这里每个共享的irq都有一张表存放了它
*
* 有着那些xxx_interrupt函数,然后依次调用它们,知道有某个xxx_interrupt
* 返回IRQ_HANDLED,它就停止(不是的会快速返回IRQ_NONE)。
*/
int status=read_int_status();
/*上面是获取中断源,好用dev_id来比对*/
if(!is_myint(dev_id,status))/*判断到底是不是该设备的中断*/
return IRQ_NONE;
/*执行到这里说明是的,下面进行具体的处理,和先前的一样*/
struct timeval t; /*该中断处理函数主要是读取当前时间,然后把它输入到
某个缓冲区,然后唤醒任何一个读取进程,告诉该进程现
在有新的数据可以读了*/
int written;
do_gettimeofday(&tv);
written=sprintf((char*)short_head,"%08u.%06u\n",tv....);
....;
wake_up_interruptible(&short_queue);/*唤醒在short_queue上阻塞的进程
short_queue是驱动自己的队列
*/
return IRQ_HANDLED;/*正常返回*/
}
设备驱动之共享
最新推荐文章于 2023-07-05 00:00:00 发布