高级字符驱动程序操作之异步通知IO(实践篇)基于内核2.6.35-30

转载 2012年03月21日 08:58:36
 async.c 主要展示异步通知机制在驱动程序中的实现

  1. #include <linux/module.h>  
  2. #include <linux/init.h>  
  3.   
  4. #include <linux/fs.h>     /* everything... */  
  5. #include <linux/types.h>  /* size_t */  
  6. #include <linux/cdev.h>  
  7. #include <linux/fcntl.h>  
  8. #include <asm/uaccess.h> /* copy user */  
  9. #include <linux/poll.h> /* POLL_IN */  
  10.   
  11. #include <linux/sched.h>  
  12. #include <linux/slab.h>  
  13.   
  14. MODULE_AUTHOR("victorsummer");  
  15. MODULE_LICENSE("Dual BSD/GPL");  
  16.   
  17.   
  18. static int async_major = 0;  
  19. struct fasync_struct *async_queue;  
  20. static char *buffer = NULL;  
  21.   
  22. ssize_t async_read (struct file *filp, char __user *buf, size_t count, loff_t *pos)  
  23. {  
  24.     if(buffer)  
  25.         copy_to_user(buf, buffer, count);   
  26.   
  27.     return count;   
  28. }  
  29.   
  30. ssize_t async_write (struct file *filp, const char __user *buf, size_t count,  
  31.         loff_t *pos)  
  32. {  
  33.     if(buffer)  
  34.         copy_from_user(buffer, buf, count);  
  35.     if(async_queue)  
  36.         kill_fasync(&async_queue, SIGIO, POLL_IN);  
  37.     return count;  
  38. }  
  39.   
  40. static int async_fasync(int fd, struct file *filp, int mode)  
  41. {  
  42.     return fasync_helper(fd, filp, mode, &async_queue);  
  43. }  
  44.   
  45. int async_release(struct inode *inode, struct file *filp)  
  46. {  
  47.     async_fasync(-1, filp, 0);  
  48.     return 0;  
  49. }  
  50.   
  51. static int async_open(struct inode *inode, struct file *filp)  
  52. {  
  53.     return nonseekable_open(inode, filp);  
  54. }  
  55.   
  56.   
  57. struct file_operations async_fops = {  
  58.     .owner = THIS_MODULE,  
  59.     .read =  async_read,  
  60.     .write = async_write,  
  61.     .fasync = async_fasync,  
  62.     .release = async_release,  
  63.     .open = async_open,  
  64. };  
  65.   
  66. int async_init(void)  
  67. {  
  68.     int result;  
  69.     dev_t dev = 0;  
  70.     
  71.     struct cdev *async_cdev = cdev_alloc();  
  72.   
  73.     if (async_major) {  
  74.         dev = MKDEV(async_major, 0);  
  75.         result = register_chrdev_region(dev, 1, "async");  
  76.     } else {  
  77.         result = alloc_chrdev_region(&dev, 0, 1, "async");  
  78.         async_major = MAJOR(dev);  
  79.     }  
  80.     if (result < 0) {  
  81.         return result;  
  82.     }  
  83.   
  84.     if(!buffer)  
  85.         buffer = kmalloc(1024*sizeof(char), GFP_KERNEL);  
  86.   
  87.     cdev_init(async_cdev, &async_fops);  
  88.     async_cdev->owner = THIS_MODULE;  
  89.     cdev_add(async_cdev, dev, 1);  
  90.   
  91.     return 0;  
  92. }  
  93.   
  94. void async_cleanup(void)  
  95. {  
  96.     dev_t devno;  
  97.     if(buffer)  
  98.     {  
  99.         kfree(buffer);  
  100.         buffer = NULL;  
  101.     }  
  102.     devno = MKDEV(async_major, 0);  
  103.     unregister_chrdev_region(devno, 1);  
  104. }  
  105.   
  106. module_init(async_init);  
  107. module_exit(async_cleanup);  
2. Makefile

  1. KERNELDIR = /usr/src/linux-headers-2.6.35-30-generic  
  2. PWD := $(shell pwd)  
  3.   
  4. obj-m := async.o   
  5.   
  6. modules:  
  7.     $(MAKE) -C $(KERNELDIR) M=$(PWD) modules  
3. async_testr.c 异步读取程序

  1. #include <unistd.h>  
  2. #include <sys/stat.h>  
  3. #include <fcntl.h>  
  4. #include <stdlib.h>  
  5. #include <stdio.h>  
  6. #include <signal.h>  
  7. #include <string.h>  
  8.   
  9. int async_fd;  
  10. void sig_handler(int signo)  
  11. {  
  12.     int code;  
  13.   
  14.         if (signo==SIGIO)  
  15.         {  
  16.         char *buf = malloc(30*sizeof(char));  
  17.   
  18.         if ((code=read(async_fd, buf, 24)) == -1)   
  19.             printf("read err! code=%d /n", code);  
  20.   
  21.         else     
  22.             printf("read ok! code=%d /n", code);  
  23.         printf("Read %s from async module /n", buf);  
  24.         free(buf);  
  25.         }  
  26.         return;  
  27. }  
  28.   
  29. int main()  
  30. {  
  31.         struct sigaction action;  
  32.   
  33.         memset(&action, 0, sizeof(action));  
  34.         action.sa_handler = sig_handler;  
  35.         action.sa_flags = 0;      
  36.   
  37.     sigaction(SIGIO, &action, NULL);  
  38.   
  39.     async_fd = open("/dev/async", O_RDONLY);  
  40.     fcntl(async_fd, F_SETOWN, getpid());  
  41.     fcntl(async_fd, F_SETFL, fcntl(STDIN_FILENO, F_GETFL) | FASYNC);  
  42.   
  43.     while(1)  
  44.     {  
  45.             sleep(86400);  
  46.     }  
  47.   
  48.     close(async_fd);  
  49.     exit(0);  
  50. }  
4. async_testw.c 写入程序

  1. #include <unistd.h>  
  2. #include <sys/stat.h>  
  3. #include <fcntl.h>  
  4. #include <stdlib.h>  
  5. #include <stdio.h>  
  6.   
  7. int main()  
  8. {  
  9.     char *write_buffer = "Hello, Character driver!";  
  10.   
  11.     int async_fd;  
  12.   
  13.     int code;  
  14.   
  15.       
  16.   
  17.     async_fd = open("/dev/async",O_WRONLY );  
  18.   
  19.   
  20.   
  21.     while(*write_buffer != '\0')  
  22.     {    
  23.         code = write(async_fd , write_buffer , 24);  
  24.         printf("Write %d bytes to async_fd/n", code);  
  25.         write_buffer += code;  
  26.     }  
  27.   
  28.     close(async_fd);  
  29.   
  30.     exit(0);  
  31. }  
5. Makefile

  1. all : async_testw.o async_testr.o  
  2.         gcc -o async_testw.o async_testw.c  
  3.         gcc -o async_testr.o async_testr.c  

6. 开始测试

 

装载驱动程序

sudo insmod ./async.ko

查看主设备号,假设为249

cat /proc/devices

建立设备节点

sudo mknod /dev/async c 249 0

更改权限

sudo chgrp staff /dev/async

sudo chmod 664 /dev/async

 

在终端1中打开异步读取程序,程序开始sleep

sudo ./async_testr.o

在终端2中打开写入程序

sudo ./async_testw.o

 

结果:

终端2打印:

Write 24 bytes to async_fd

终端1打印:

read ok! code=24
Read Hello, Character driver! from async module


相关文章推荐

高级字符驱动程序操作之异步通知IO(实践篇)基于内核2.6.35-30

1. async.c 主要展示异步通知机制在驱动程序中的实现 #include #include #include /* everything... */ #includ...

【Linux 驱动】第六章 高级字符驱动程序操作----异步通知

一,概念          异步通知:一旦设备就绪,则主动通知应用程序,应用程序根本就不需要查询设备状态。(类似于中断)信号是异步的,一个进程不必通过任何操作来等待信号的到达       ...

Linux设备驱动程序第三版学习(8)- 高级字符驱动程序操作(续3)- 异步通知

第六章:高级字符驱动程序操作(续3) 以下为第四部分:异步通知 使用poll轮询方式的时候,相当于应用程序在需要的时候询问设备“准备好了吗?”,如果有这样一种情况,一个进程在低优先级正在执行长的循...

07-S3C2440驱动学习(一)嵌入式linux字符设备驱动-按键驱动程序之异步通知机制+原子操作+互斥信号量+阻塞与非阻塞+定时器去抖

一、异步通知机制 从按键的实现方式来说,可以分为以下几种方式 查询方式,极度耗费CPU资源中断方式,平时休眠,按键按下,唤醒休眠poll机制,不需要一直read,根据poll返回值来决定是否rea...

【Linux设备驱动程序(第三版)】----异步通知

【Linux设备驱动程序(第三版)】----异步通知scullp.c#include #include #include #include #include //file_operat...

异步通知《来自Linux驱动程序开发实例》

您所在的位置:读书频道 > 操作系统 > Linux > 1.2.8 异步通知 1.2.8 异步通知 2012-05-22 13:38 冯国进 机械工业出版社 我要评论(0) 字号:T |...

linux驱动程序之增加按键异步通知机制

目的:按下按键时驱动程序通知应用程序 大体框架: 1、应用程序:注册信号处理函数 2、驱动程序发送信号 3、应用程序通知驱动 PID 4、驱动程序发送如何发送信号

驱动程序异步通知应用程序,数据是否可读

当我们驱动程序当中有数据可读的时候,可以通过驱动程序中的异步通知机制来通知应用程序数据是否可读,从而提高读取数据的效率。 主要实现思路是:设备I/O驱动如果准备好数据(用户可读或者可写),向...

字符设备驱动第八课----异步通知(信号驱动IO)

概述类比运用程序中的kill-----signal,在运用程序中常常一个进程用kill(pid,sig)向另一 进程发信号,另一个进程用signal(sig,handler)绑定相应的处理函数,实现了...

高级字符驱动程序操作之休眠(理论篇)

1. 休眠的原则   第一条: "永远不要在原子上下文中进入休眠" (LDD3 p149) 第二条: 当线程被唤醒时,应当检查等待的条件是否为真 第三条: 确保即将休眠的线程一定会被唤醒  ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)