Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4524023
  • 博文数量: 1148
  • 博客积分: 25453
  • 博客等级: 上将
  • 技术积分: 11949
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-06 21:14
文章分类

全部博文(1148)

文章存档

2012年(15)

2011年(1078)

2010年(58)

分类: LINUX

2011-12-29 12:56:04



LDD3 P169
驱动程序怎样实现异步信号???从驱动程序的角度考虑

1. F_SETOWN被调用时对filp->f_owner赋值,此外什么也不做
2. 在执行F_SETFL启动FASYNC时,调用驱动程序的fasync方法。只要filp->f_flags中的FASYNC标志发生了变化,就会调用该方法,以便把这个变化通知驱动程序。  文件打开时,FAYSNC标志被默认是清除的。
3. 当数据到达时,所有注册为异步通知的进程都会被发送一个SIGIO信号。


驱动程序中异步通知编程用到:一个数据结构和两个函数,头文件
  1. 1284  struct fasync_struct {
  2. 1285    spinlock_t fa_lock;
  3. 1286 int magic;
  4. 1287    int fa_fd;
  5. 1288 struct fasync_struct *fa_next; /* singly linked list */
  6. 1289 struct file *fa_file;
  7. 1290 struct rcu_head fa_rcu;
  8. 1291  };
  1. fs.h  linux-2.6.35
  2. 1296 extern int fasync_helper(int fd, struct file *filp, int mode, struct fasync_struct **fa);
  3. 1297/* can be called from interrupts */
  4. 1298 extern void kill_fasync(struct fasync_struct **fa, int sig, int band);

pp182 在globalmem驱动中增加异步通知
下面的程序是在”3 阻塞 add_wait_queue wait_event wake_up “修改
附件代码: globalmem_fifo_async.rar   将rar修改为 tar.bz2

内容修改增加如下:
  1. struct globalmem_dev{
  2.         struct cdev cdev;
  3.         unsigned char mem[GLOBALMEM_SIZE];////全局内存
  4.         unsigned int current_len;//fifo有效数据长
  5.         struct semaphore sem;//并发控制的信号量
  6.         wait_queue_head_t r_wait; // read //阻塞读用的等待队列头
  7.         wait_queue_head_t w_wait; // write
  8.         struct fasync_struct *async_queue;////异步结构体指针,用于读
  9. };
  1. static int globalmem_fasync(int fd,struct file *filp,int mode)
  2. {
  3.         struct globalmem_dev *dev=filp->private_data;
  4.         return fasync_helper(fd,filp,mode,&dev->async_queue);
  5. }
  1. write函数中
  2. ////产生异步读信号
  3.                 if(dev->async_queue)
  4.                         kill_fasync(&dev->async_queue,SIGIO,POLL_IN);
在设备资源可以获得时,调用kill_fasync()释放SIGIO,可读时第三个参数设置为POLL_IN,可写时第三个参数设置为POLL_OUT

在ldd3 p171:当数据到达时,必须执行上述语句来通知异步读取进程。由于供给glebalmem的读取进程的新数据是由某个进程调用write产生的,所以这条语句在write方法中。

设备可写时,在read方法中实现,这时,kill_fasync必须是 POLL_OUT

  1. int globalmem_release(struct inode *inode,struct file *filp)
  2. {
  3.         ////将文件从异步列表中删除
  4.         globalmem_fasync(-1,filp,0);
  5.         return 0;
  6. }
  1. void input_handler(int signum)
  2. {
  3.     printf("receive a signal from globalmem fifo,signalnum:%d\n",signum);
  4. }

  5. int main(int argc, char **argv)
  6. {
  7.     int fd;
  8.     int oflags;

  9.     fd = open("/dev/globalmem",O_RDWR,S_IRUSR | S_IWUSR);
  10.     if(fd != -1)
  11.     {
  12.         ////
  13.         signal(SIGIO,input_handler);
  14.         fcntl(fd,F_SETOWN,getpid());
  15.         oflags = fcntl(fd,F_GETFL);
  16.         fcntl(fd,F_SETFL,oflags | FASYNC);
  17.         while(1)
  18.             sleep(1);
  19.     }
  20.     else
  21.     {
  22.         printf("device open faiure\n");
  23.         exit(EXIT_FAILURE);
  24.     }
  25. }

使用:
  1. sudo insmod ./globalmem.ko
  2. sudo mknod /dev/globalmem c 240 0
  1. root@ywx:/globalmem_fifo_async/application# ls
  2. app  app.c  app.o  Makefile
  3. root@ywx:/globalmem_fifo_async/application# ./app &
  4. [1] 6800
  5. root@ywx:/globalmem_fifo_async/application# echo 1 > /dev/globalmem
  6. receive a signal from globalmem fifo,signalnum:29
  7. 当有数据输入的时候,应用程序会返回信息,异步通知 实现了
  8. root@ywx:/globalmem_fifo_async/application# echo "i love linux" > /dev/globalmem
  9. receive a signal from globalmem fifo,signalnum:29
  10. root@ywx:/globalmem_fifo_async/application# ps -A | grep app  查找我们运行的应用程序
  11.  1705 ? 00:00:00 bluetooth-apple
  12.  1708 ? 00:00:00 nm-applet
  13.  1776 ? 00:00:01 wnck-applet
  14.  1784 ? 00:00:00 trashapplet
  15.  1824 ? 00:00:00 indicator-apple
  16.  1828 ? 00:00:04 clock-applet
  17.  1829 ? 00:00:00 indicator-apple
  18.  1881 ? 00:00:00 indicator-appli
  19.  1896 ? 00:00:00 applet.py
  20.  6800 pts/2 00:00:00 app 这是我们执行的应用程序

参考资料:
2.

总结:

信号异步通知 不会引起进程阻塞,而且进程也不知道什么时候信号会发出。

使用信号可以实现设备驱动与用户程序之间的异步通知,总体而言,设备驱动和用户空间要分别完成3项对应的工作,用户空间设置文件的拥有者、FASYNC标志及捕获信号,内核空间要对文件的拥有者、FASYNC标志的设置并在资源科获得时释放信号。




阅读(1900) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~