高级字符驱动程序操作之异步通知IO(实践篇)
2010-12-29 13:49
447 查看
1. async.c 主要展示异步通知机制在驱动程序中的实现
2. Makefile
3. async_testr.c 异步读取程序
4. async_testw.c 写入程序
5. Makefile
6. 开始测试
装载驱动程序
sudo insmod ./async.ko
查看主设备号,假设为250
cat /proc/devices
建立设备节点
sudo mknod /dev/async c 250 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
#include <linux/module.h> #include <linux/init.h> #include <linux/fs.h> /* everything... */ #include <linux/types.h> /* size_t */ #include <linux/cdev.h> #include <linux/fcntl.h> #include <asm/uaccess.h> /* copy user */ #include <linux/poll.h> /* POLL_IN */ MODULE_AUTHOR("victorsummer"); MODULE_LICENSE("Dual BSD/GPL"); static int async_major = 0; struct fasync_struct *async_queue; static char *buffer = NULL; ssize_t async_read (struct file *filp, char __user *buf, size_t count, loff_t *pos) { if(buffer) copy_to_user(buf, buffer, count); return count; } ssize_t async_write (struct file *filp, const char __user *buf, size_t count, loff_t *pos) { if(buffer) copy_from_user(buffer, buf, count); if(async_queue) kill_fasync(&async_queue, SIGIO, POLL_IN); return count; } static int async_fasync(int fd, struct file *filp, int mode) { return fasync_helper(fd, filp, mode, &async_queue); } int async_release(struct inode *inode, struct file *filp) { async_fasync(-1, filp, 0); return 0; } static int async_open(struct inode *inode, struct file *filp) { return nonseekable_open(inode, filp); } struct file_operations async_fops = { .owner = THIS_MODULE, .read = async_read, .write = async_write, .fasync = async_fasync, .release = async_release, .open = async_open, }; int async_init(void) { int result; dev_t dev = 0; struct cdev *async_cdev = cdev_alloc(); if (async_major) { dev = MKDEV(async_major, 0); result = register_chrdev_region(dev, 1, "async"); } else { result = alloc_chrdev_region(&dev, 0, 1, "async"); async_major = MAJOR(dev); } if (result < 0) { return result; } if(!buffer) buffer = kmalloc(1024*sizeof(char), GFP_KERNEL); cdev_init(async_cdev, &async_fops); async_cdev->owner = THIS_MODULE; cdev_add(async_cdev, dev, 1); return 0; } void async_cleanup(void) { dev_t devno; if(buffer) { kfree(buffer); buffer = NULL; } devno = MKDEV(async_major, 0); unregister_chrdev_region(devno, 1); } module_init(async_init); module_exit(async_cleanup);
2. Makefile
KERNELDIR = /usr/src/linux-headers-2.6.31-14-generic PWD := $(shell pwd) obj-m := async.o modules: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules
3. async_testr.c 异步读取程序
#include <unistd.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> #include <signal.h> #include <string.h> int async_fd; void sig_handler(int signo) { int code; if (signo==SIGIO) { char *buf = malloc(30*sizeof(char)); if ((code=read(async_fd, buf, 24)) == -1) printf("read err! code=%d /n", code); else printf("read ok! code=%d /n", code); printf("Read %s from async module /n", buf); free(buf); } return; } int main() { struct sigaction action; memset(&action, 0, sizeof(action)); action.sa_handler = sig_handler; action.sa_flags = 0; sigaction(SIGIO, &action, NULL); async_fd = open("/dev/async", O_RDONLY); fcntl(async_fd, F_SETOWN, getpid()); fcntl(async_fd, F_SETFL, fcntl(STDIN_FILENO, F_GETFL) | FASYNC); while(1) { sleep(86400); } close(async_fd); exit(0); }
4. async_testw.c 写入程序
#include <unistd.h> #include <sys/stat.h> #include <fcntl.h> #include <stdlib.h> #include <stdio.h> int main() { char *write_buffer = "Hello, Character driver!"; int async_fd; int code; async_fd = open("/dev/async",O_WRONLY ); while(*write_buffer != '/0') { code = write(async_fd , write_buffer , 24); printf("Write %d bytes to async_fd/n", code); write_buffer += code; } close(async_fd); exit(0); }
5. Makefile
all : async_testw.o async_testr.o gcc -o async_testw.o async_testw.c gcc -o async_testr.o async_testr.c
6. 开始测试
装载驱动程序
sudo insmod ./async.ko
查看主设备号,假设为250
cat /proc/devices
建立设备节点
sudo mknod /dev/async c 250 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
- 高级字符驱动程序操作之异步通知IO(实践篇)基于内核2.6.35-30
- 高级字符驱动程序操作之异步通知IO(理论篇)
- 【Linux 驱动】第六章 高级字符驱动程序操作----异步通知
- LDD高级字符驱动程序操作-异步通知
- ldd3学习之十二(3):高级字符驱动程序操作--poll/select、异步通知
- Linux设备驱动程序第三版学习(8)- 高级字符驱动程序操作(续3)- 异步通知
- Linux设备驱动程序第三版学习(8)- 高级字符驱动程序操作(续3)- 异步通知 .
- Linux设备驱动程序学习(6)-高级字符驱动程序操作[(4)异步通知fasync]
- 高级字符驱动程序操作之poll(实践篇)
- 07-S3C2440驱动学习(一)嵌入式linux字符设备驱动-按键驱动程序之异步通知机制+原子操作+互斥信号量+阻塞与非阻塞+定时器去抖
- 高级字符驱动程序操作之休眠(实践篇)
- 高级字符驱动程序操作之ioctl(实践篇)
- Linux设备驱动程序学习 高级字符驱动程序操作[阻塞型I/O和非阻塞I/O]【转】
- Linux设备驱动程序学习(6) -高级字符驱动程序操作[(3)设备文件的访问控制]
- Linux设备驱动程序第三版学习(9)- 高级字符驱动程序操作(续4) - llseek定位设备
- 高级字符驱动程序操作--增加了async功能
- 韦东山驱动视频笔记——4.字符设备驱动程序之异步通知
- ldd3学习之十二(1):高级字符驱动程序操作--ioctl
- LDD3读书笔记(第11章 高级字符驱动程序操作)