#include <linux/init.h>
#include <linux/module.h>
#include<linux/fs.h>
#include<linux/uaccess.h>
#include<linux/io.h>
#include<linux/device.h>
#include<linux/poll.h>
int major;
struct class *cls;
struct device *dev;
struct fasync_struct *fapp;
char kbuf[128]={0};
int mycdev_open(struct inode *inode, struct file *file)
{
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
return 0;
}
ssize_t mycdev_read(struct file *file, char *ubuf, size_t size, loff_t *off)
{
int ret;
//将进程2写到内核的数据传递给进程1
if(size>sizeof(kbuf))
size=sizeof(kbuf);
ret=copy_to_user(ubuf,kbuf,size);
if(ret)
{
printk("copy_to_user filed\n");
return -EIO;//拷贝失败返回错误码
}
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
return 0;
}
ssize_t mycdev_write(struct file *file, const char *ubuf, size_t size, loff_t *off)
{
int ret;
if(size>sizeof(kbuf))
size=sizeof(kbuf);
ret=copy_from_user(kbuf,ubuf,size);
if(ret)
{
printk("copy_from_user filed\n");
return -EIO;//拷贝失败返回错误码
}
//给进程发送信号
kill_fasync(&fapp, SIGIO, POLL_IN);
return 0;
}
//定义fasync操作方法
int mycdev_fasync(int fd, struct file *file, int on)
{
//完成发送信号之前的准备工作
return fasync_helper(fd, file, on, &fapp);
}
int mycdev_close(struct inode *inode, struct file *file)
{
printk("%s:%s:%d\n",__FILE__,__func__,__LINE__);
return 0;
}
//定义操作方法结构体变量并初始化
struct file_operations fops=
{
.open=mycdev_open,
.read=mycdev_read,
.write=mycdev_write,
.fasync=mycdev_fasync,
.release=mycdev_close,
};
//入口函数
static int __init mycdev_init(void)
{
int i;
//进行字符设备驱动的注册
major=register_chrdev(0,"mycdev",&fops);
if(major<0)
{
printk("字符设备驱动注册失败\n");
return major;
}
printk("字符设备驱动注册成功,major=%d\n",major);
//向上提交目录
cls=class_create(THIS_MODULE,"mycdev");
if(IS_ERR(cls))//指针指向预留空间,函数调用失败
{
printk("向上提交目录失败\n");
return PTR_ERR(cls);
}
printk("向上提交目录成功\n");
//向上提交设备节点
for(i=0;i<3;i++)
{
dev=device_create(cls,NULL,MKDEV(major,i),NULL,"mycdev%d",i);
if(IS_ERR(dev))//指针指向预留空间,函数调用失败
{
printk("向上提交目录失败\n");
return PTR_ERR(dev);
}
}
printk("设备节点向上提交成功\n");
return 0;
}
//出口函数
static void __exit mycdev_exit(void)
{
int i;
for(i=0;i<3;i++)
{
device_destroy(cls,MKDEV(major,i));
}
//删除目录信息
class_destroy(cls);
//字符设备驱动的注销
unregister_chrdev(major,"mycdev");
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
epoll实现并发服务器
于 2023-06-23 19:32:16 首次发布