免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1027 | 回复: 0
打印 上一主题 下一主题

mini2440button驱动程序分析 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-07-05 15:21 |只看该作者 |倒序浏览

v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}

  Normal
  0
  
  7.8 磅
  0
  2
  
  false
  false
  false
  
   
   
   
   
   
   
   
   
   
   
   
   
  
  MicrosoftInternetExplorer4



st1\:*{behavior:url(#ieooui) }
/* Style Definitions */
table.MsoNormalTable
        {mso-style-name:普通表格;
        mso-tstyle-rowband-size:0;
        mso-tstyle-colband-size:0;
        mso-style-noshow:yes;
        mso-style-parent:"";
        mso-padding-alt:0cm 5.4pt 0cm 5.4pt;
        mso-para-margin:0cm;
        mso-para-margin-bottom:.0001pt;
        mso-pagination:widow-orphan;
        font-size:10.0pt;
        font-family:"Times New Roman";
        mso-ansi-language:#0400;
        mso-fareast-language:#0400;
        mso-bidi-language:#0400;}
mini2440button驱动程序分析
By
Jeefjiang JUL,5th,2009
开发板:友善之臂mini2440
开发环境:Fedora+arm-linux-gcc+NFS
内核版本:Linux2.6.29
参考程序:LDD3的SCULL模块程序,友善之臂本身提供的button驱动
知识准备以及参考资料:
驱动程序方面:内核中断处理 LDD3 CHAP10
              poll和异步通知:LDD3 CHAP06
测试程序方面:poll :UNIX环境高级编程 chap12
              异步通知:UNIX环境高级编程 chap10
网络资源:《使用异步 I/O
大大提高应用程序的性能》 IBM中文技术网站
硬件引脚配置:  
S3C2410_GPG0,
       S3C2410_GPG3,
       S3C2410_GPG5,
       S3C2410_GPG6,
       S3C2410_GPG7,
       S3C2410_GPG11,
设备结构体:
struct button_dev{
       unsigned long button_tab[6];
       unsigned long irq_tab[6];
       unsigned long button_cfg_tab[6];
       char *btn_name[6];
       struct cdev button_cdev;
       struct fasync_struct *async_queue; /* asynchronous readers */
//     struct semaphore sem;
       wait_queue_head_t outq;
};
采用LDD3中常用的嵌入cdev的方法。
中断处理:
1)  注册:我们按照LDD3的要求,在打开设备时进行注册,这样可以充分利用有限的中断线,注意这个程序是有缺陷的,如果在注册中出现问题,没有进行释放,表明我们的按键是随机产生的
static int
minibtb_open(struct inode *inode, struct file *filp)
{
       struct button_dev  *dev;
/* device information */
       int result,i;
       dev = container_of(inode->i_cdev, struct
button_dev,button_cdev);
       filp->private_data = dev; /* for other methods */
       for(i=0;i
              result = request_irq(dev->irq_tab,
minibtn_interrupt,
                            IRQF_SAMPLE_RANDOM|IRQ_TYPE_EDGE_BOTH,dev->btn_name,
                             (void *)dev);
//dev成员是在ISR中需要用到的设备的私有结构

              if (result) {
                     printk(KERN_INFO "button: can't get
assigned irq key-%i\n", i);
               }
       }
       return 0;          /*
success */
}
释放:
static int
minibtn_release(struct inode *inode, struct file *filp)
{
       ……..
           for
(i = 0; i
       free_irq(dev->irq_tab, (void *)dev);
    }
}
这样当设备文件打开时,才会在/proc/interrupt下观察到已经注册的中断,关闭设备文件时就没了。
POLL/SELECT
POLL/SELECT轮询是属于异步阻塞 I/O
带有阻塞通知的非阻塞
I/O。在这种模型中,配置的是非阻塞 I/O,然后使用阻塞 select 系统调用来确定一个 I/O 描述符何时有操作。使 select 调用非常有趣的是它可以用来为多个描述符提供通知,而不仅仅为一个描述符提供通知。对于每个提示符来说,我们可以请求这个描述符可以写数据、有读数据可用以及是否发生错误的通知。

       
        文件:Button.rar
        大小:4KB
        下载:
下载
       


  
  
  
  
  
  
  
  
  
  
  
  




注意这里的带有阻塞的通知时指当轮询时发现没有一个驱动程序可以进行非阻塞I/O,则POLL调用就进入休眠。
POLL驱动实现
static unsigned int
minibtn_poll(struct file *filp, poll_table *wait)
{
       struct button_dev  *dev
= filp->private_data;
       unsigned int mask = 0;
       poll_wait(filp, &dev->outq,  wait);
//在等待队列上调用poll_wait,则内核使该进程在传递到该系统调用的所有文件描叙符上等待对应得队列

       if
(ev_press )//轮询条件满足时,设置掩码,表示可读
              mask |= POLLIN | POLLRDNORM; /* readable */
              
            return mask;
}
POLL/SELECT的主要问题是它的效率不是非常高。尽管这是异步通知使用的一种方便模型,但是对于高性能的
I/O 操作来说不建议使用。因为老在轮询啊,这很浪费资源。

异步通知:
这种机制类似于中断,当有数据可读时,发出一个信号,通知进程可以去取按键值。应用程序需要定义信号处理程序,在产生指定的信号时就会调用这个处理程序。应用程序然后配置一个异步请求将在请求完成时产生一个信号。
这种情况下,IO可以是非阻塞的,通知也是非阻塞的。
异步通知的驱动实现:
static int minibtn_fasync(int fd, struct file *filp, int mode)
{
       struct button_dev *dev
= filp->private_data;

       return
fasync_helper(fd, filp, mode, &dev->async_queue);
}
当数据到达时必须发信号:
  if (dev->async_queue)
              kill_fasync(&dev->async_queue,
SIGIO, POLL_IN); (在中断服务程序中)
POLL_IN表示有数据可读了
关闭文件时需要做的善后工作:
static int minibtn_release(struct inode *inode, struct file *filp)
{……….
   minibtn_fasync(-1, filp,
0);
………….
}
测试:附件中有两个测试程序,分别对异步通知和轮询进行测试
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/69999/showart_1986143.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP