微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > arm驱动linux异步通知与异步IO

arm驱动linux异步通知与异步IO

时间:11-19 来源:互联网 点击:

register_chrdev_region(devno, 1, "myfasync_drv");
}else{
result = alloc_chrdev_region(&devno, 0, 1, "myfasync_drv");
VirtualDisk_major = MAJOR(devno);
}
if(result < 0 ){
return result;
}
VirtualDiskp = kmalloc(sizeof(struct VirtualDisk), GFP_KERNEL);
if(!VirtualDiskp){
result = -ENOMEM;
goto fail_malloc;
}
memset(VirtualDiskp, 0, sizeof(struct VirtualDisk));
VirtualDisk_setup_cdev(VirtualDiskp, 0);
myfasync_class = class_create(THIS_MODULE, "myfasync_drv");
if (IS_ERR(myfasync_class))
return PTR_ERR(myfasync_class);
myfasync_class_dev = class_device_create(myfasync_class, NULL, MKDEV(VirtualDisk_major, 0), NULL, "myfasync_drv"); /* /dev/xyz */
if (IS_ERR(myfasync_class_dev))
return PTR_ERR(myfasync_class_dev);
return 0;
fail_malloc:
unregister_chrdev_region(devno, 1);
return result;

}
static void myfasync_drv_exit(void)
{
cdev_del(&VirtualDiskp->cdev);
kfree(VirtualDiskp);
unregister_chrdev_region(MKDEV(VirtualDisk_major, 0), 1);
class_device_unregister(myfasync_class_dev);
class_destroy(myfasync_class);
}
module_init(myfasync_drv_init);
module_exit(myfasync_drv_exit);
MODULE_LICENSE("GPL");

Makefile

#myfasync_drv.c
KERN_DIR = /workspacearm/linux-2.6.2.6
all:
make -C $(KERN_DIR) M=`pwd` modules
cp myfasync_drv.ko /opt/fsmini/
clean:
make -C $(KERN_DIR) M=`pwd` modules clean
rm -rf timerlists.order
obj-m += myfasync_drv.o

实例三)驱动程序对应的测试的应用程序部分

#include
#include
#include
#include
#include
int myfd;
int lenthe;
void input_handler(int num)
{
char data[80];
int len;
lseek(myfd, -lenthe, SEEK_CUR);//移动偏移量到写之前位置
len = read(myfd, data, lenthe);
//data[len] = ;
printf("myfd = %d, len = %d buffuer input available :%s\n",myfd, len, data);
}
void setFdAsync(int fd){
int oflags;
//当前进程变成文件的主人
fcntl(fd, F_SETOWN, getpid());
//本程序中fd = STDIN_FILENO标准输入设备设备文件描述符号;普通文件内核中没有实现FASYNC,不能使用异步通信
oflags = fcntl(fd, F_GETFL);//
//FASYNC在glibc 的fcntl.h文件中可以看到这样的定义 #define FASYNC O_ASYNC
fcntl(fd, F_SETFL, oflags | FASYNC);
}
int main(){
myfd = open("/dev/myfasync_drv", O_RDWR);//STDIN_FILENO输入输出设备描述符号,一般是键盘
printf("fd = %d,pid = %d", myfd, getpid());
signal(SIGIO,input_handler);//设置好目标设备的SIGIO信号处理程序;等待内核kill_fasync()释放 SIGIO 信号
setFdAsync(myfd);
printf("before while\n");
while(1){
char buffer[80];
lenthe = read(STDIN_FILENO, buffer, 80);
write(myfd, buffer, lenthe);
}
return 0;
}

我的Makefile

objs := $(patsubst %c, %o, $(shell ls *.c))
myarmgcc := /workspacearm/armlinuxgcc2626/bin/arm-linux-gcc
mybutton.bin:$(objs)
$(myarmgcc) -o $@ $^
cp *.bin /opt/fsmini/
%.o:%.c
$(myarmgcc) -c -o $@ $
clean:
rm -f *.bin *.o

实验结果

# insmod myfasync_drv.ko
# ./mybutton.bin
myfasync_drv open//对应应用程序myfd = open("/dev/myfasync_drv",调用了内核驱动open函数
myfasync_drv_fasync 3//对应应用程序fcntl(fd, F_SETFL, oflags | FASYNC);调用了内核驱动的myfasync_drv_fasync()函数
//
fd = 3,pid = 793before while//while前的进程信息输出
hello//键盘输入hello
myfasync_drv write//调用驱动程序write函数
written 6 bytes(s) from0, buffer is hello//驱动程序write函数内部输出
write kill_fasync//内涵write函数中,执行kill_fasync(&async_queue, SIGIO, POLL_IN);释放SIGIO信号
myfasync_drv read//此时应用程序收到中断,应用程序执行read函数,read对应内核驱动的read
read 6 bytes(s) is 0//内核驱动read打印输出
bytes(s) is hello //内核驱动read打印输出

myfd = 3, len = 6 buffuer input available :hello//应用程序input_handler函数输出驱动的写入值
//下面是while第二次执行
it is ok
myfasync_drv write
written 9 bytes(s) from6, buffer is hello
it is ok

write kill_fasync
myfasync_drv read
read 9 bytes(s) is 6
bytes(s) is hello
it is ok

myfd = 3, len = 9 buffuer input available :it is ok
//按ctrl+c退出程序,会执行myfasync_drv_release中myfasync_drv_fasync(-1, file, 0),释放本进程的异步通知
myfasync_drv release
myfasync_drv_fasync -1

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top