主题 : mini2440按键驱动中的终端申请函数的困恼 复制链接 | 浏览器收藏 | 打印
春有百花秋有月,夏有凉风冬有雪。若无闲事挂心头,便是UBUNTU好时节。。。。
级别: 侠客
UID: 24947
精华: 2
发帖: 63
金钱: 430 两
威望: 86 点
综合积分: 166 分
注册时间: 2010-07-16
最后登录: 2019-04-27
楼主  发表于: 2010-08-03 17:40

 mini2440按键驱动中的终端申请函数的困恼

我在学习linux 驱动中中断处理的时候,看到mini2440 自带的按键驱动中的终端申请函数的,flag形参为什么是 IRQ_TYPE_EDGE_BOTH(中断触发方式)?

代码如下:

static int s3c24xx_buttons_open(struct inode *inode, struct file *file)
{
    int i;
    int err = 0;
    
    for (i = 0; i < sizeof(button_irqs)/sizeof(button_irqs[0]); i++) {
    if (button_irqs.irq < 0) {
        continue;
    }
   err = request_irq(button_irqs.irq, buttons_interrupt, IRQ_TYPE_EDGE_BOTH,
                          button_irqs.name, (void *)&button_irqs);


        if (err)
            break;
    }

    if (err) {
        i--;
        for (; i >= 0; i--) {
        if (button_irqs.irq < 0) {
        continue;
        }
        disable_irq(button_irqs.irq);
            free_irq(button_irqs.irq, (void *)&button_irqs);
        }
        return -EBUSY;
    }

    ev_press = 1;
    
    return 0;
}

最为一个菜鸟现在不知如何是好啊,请各位大虾指点指点
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
1楼  发表于: 2010-08-04 13:07

 回 楼主(小荷尖尖) 的帖子

那你觉得应该填什么比较好:)
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
春有百花秋有月,夏有凉风冬有雪。若无闲事挂心头,便是UBUNTU好时节。。。。
级别: 侠客
UID: 24947
精华: 2
发帖: 63
金钱: 430 两
威望: 86 点
综合积分: 166 分
注册时间: 2010-07-16
最后登录: 2019-04-27
2楼  发表于: 2010-08-04 18:00

 回 1楼(kasim) 的帖子

因为我才学,教材普遍都是用中断配置函数和中断申请函数结合,而该驱动里只用到了申请函数就把两项工作完成了,这让我很困惑,它是怎么实现的呢?
   又比如说我要分享中断号该怎么办?
级别: 骑士
UID: 9169
精华: 0
发帖: 249
金钱: 1330 两
威望: 299 点
综合积分: 498 分
注册时间: 2009-09-19
最后登录: 2017-08-14
3楼  发表于: 2010-08-05 08:56
是双边沿触发方式,你自己可以更改的
春有百花秋有月,夏有凉风冬有雪。若无闲事挂心头,便是UBUNTU好时节。。。。
级别: 侠客
UID: 24947
精华: 2
发帖: 63
金钱: 430 两
威望: 86 点
综合积分: 166 分
注册时间: 2010-07-16
最后登录: 2019-04-27
4楼  发表于: 2010-08-05 12:45

 回 3楼(libailiang) 的帖子

是的,这个我明白,不明白的是这个形参不是优先级的标志吗,如IRQF_SHARED,IRQF_DISABLED.......,为什么可以成为触发方式的选择呢?他是怎么实现的,分析源代码也搞不清楚
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
5楼  发表于: 2010-08-06 16:28

 Re:回 3楼(libailiang) 的帖子

引用第4楼小荷尖尖于2010-08-05 12:45发表的 回 3楼(libailiang) 的帖子 :
是的,这个我明白,不明白的是这个形参不是优先级的标志吗,如IRQF_SHARED,IRQF_DISABLED.......,为什么可以成为触发方式的选择呢?他是怎么实现的,分析源代码也搞不清楚

我假设你用的是2.6.32.2的内核,这些flag在__setup_irq()中处理
复制代码
  1.   718                /* Setup the type (level, edge polarity) if configured: */
  2. 719                if (new->flags & IRQF_TRIGGER_MASK) {
  3. 720                        ret = __irq_set_trigger(desc, irq,
  4. 721                                        new->flags & IRQF_TRIGGER_MASK);
  5. 722
  6. 723                        if (ret)
  7. 724                                goto out_thread;


完整的代码参考http://lxr.linux.no/#linux+v2.6.32.2/kernel/irq/manage.c#L608
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
春有百花秋有月,夏有凉风冬有雪。若无闲事挂心头,便是UBUNTU好时节。。。。
级别: 侠客
UID: 24947
精华: 2
发帖: 63
金钱: 430 两
威望: 86 点
综合积分: 166 分
注册时间: 2010-07-16
最后登录: 2019-04-27
6楼  发表于: 2010-08-06 18:37

 回 5楼(kasim) 的帖子

谢谢斑竹把我的焦点引到这里来,之前看着这些代码一点头绪也没有,现在似乎明朗些了,在request_irq()函数里大概依次调用了这些函数:request_threaded_irq,__setup_irq() ,__irq_set_trigger() ,irq_chip结构体中的回调函数set_type()。
我现在还没找到set_type()所指的函数,是这个吗:
struct irq_desc *irq_to_desc(unsigned int irq)
{
    if (irq_desc_ptrs && irq < nr_irqs)
        return irq_desc_ptrs[irq];

    return NULL;
}

有时间的话麻烦斑竹解决一下
*無鈳取玳
级别: 论坛版主
UID: 27
精华: 12
发帖: 5398
金钱: 40120 两
威望: 17929 点
综合积分: 11036 分
注册时间: 2008-01-16
最后登录: 2014-11-22
7楼  发表于: 2010-08-06 22:18
在内核中,硬件中断是以irq_chip结构的形式管理的,各个不同的硬件平台通过set_irq_chip()为不同的硬件中断指定相应的irq_chip结构.
以S3C2440为例,在arch/arm/plat-s3c24xx/irq.c中就为GPIO外部中断定义了s3c_irq_eint0t4和s3c_irqext_chip两个irq_chip结构分别对应EINT0~4和其他的EINT中断。每个irq_chip结构中定义有set_type成员,这是一个指向设定某一硬件中断触发类型的函数指针。以s3c_irq_eint0t4和s3c_irqext_chip为例,由于它们所对应的外部中断设定触发的方式相同,因此它们的set_type都指向s3c_irqext_type().
"If you have an apple and I have an apple and we exchange apples, then you and I will
still each have one apple. But if you have an idea and I have an idea and we exchange
these ideas, then each of us will have two ideas."
春有百花秋有月,夏有凉风冬有雪。若无闲事挂心头,便是UBUNTU好时节。。。。
级别: 侠客
UID: 24947
精华: 2
发帖: 63
金钱: 430 两
威望: 86 点
综合积分: 166 分
注册时间: 2010-07-16
最后登录: 2019-04-27
8楼  发表于: 2010-08-07 00:52
哦,原来irq_chip结构体中的回调函数set_type指向s3c_irqext_type(),从而在申请中断的过程中实现了中断寄存器的配置,要实现硬件寄存器的设置最终要落实在各个平台所提供的函数。这点像应用程序调用驱动,而驱动屏蔽了底部硬件细节。
    
  很感谢斑竹解决了我的问题,令我很有信心搞下去。。