内核代码
#include<linux/init.h>
#include<linux/module.h>
#include<linux/fs.h>
int major;
char kbuf[128] = {0};
int mycdev_open(struct inode *inode, struct file *filp)
{
printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
return 0;
}
ssize_t mycdev_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
int ret;
printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
if(count > sizeof(kbuf)) //如果用户空间传来的count大于kbuf的大小
count = sizeof(kbuf); //则只能读取kbuf的大小
// 如果kbuf中是1,kbuf的值改为“开灯”
if (kbuf[0] == '1')
strcpy(kbuf, "open the light\n");
// 如果kbuf中是0,打印“关灯”
else if (kbuf[0] == '0')
strcpy(kbuf, "close the light\n");
else
{
kbuf[strlen(kbuf) - 1] = '-';
// 在kbuf增加kernel标记,再拷贝到用户空间
strcat(kbuf, "kernel");
kbuf[strlen(kbuf) - 1] = '\n';
}
ret = copy_to_user(buf, kbuf, count); //将kbuf的数据拷贝到用户空间
if(ret)
{
printk("copy data to user error\n");
return -EIO;
}
//清空kbuf
memset(kbuf, 0, sizeof(kbuf));
return count;
}
ssize_t mycdev_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
int ret;
printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
if(count > sizeof(kbuf)) //如果用户空间传来的count大于kbuf的大小
count = sizeof(kbuf); //则只能读取kbuf的大小
ret = copy_from_user(kbuf, buf, count); //将用户空间的数据拷贝到kbuf
if(ret)
{
printk("copy data from user error\n");
return -EIO;
}
return count;
}
int mycdev_close(struct inode *inode, struct file *filp)
{
printk("%s:%s:%d\n", __FILE__, __func__, __LINE__);
return 0;
}
//定义file_operations结构体变量
struct file_operations mycdev_fops = {
.owner = THIS_MODULE,
.open = mycdev_open,
.read = mycdev_read,
.write = mycdev_write,
.release = mycdev_close,
};
static int __init mycdev_init(void)
{
major = register_chrdev(0, "mycdev", &mycdev_fops);
if(major < 0)
{
printk("register_chrdev failed\n");
return major;
}
printk("major = %d\n", major);
return 0;
}
static void __exit mycdev_exit(void)
{
unregister_chrdev(major, "mycdev");
}
module_init(mycdev_init);
module_exit(mycdev_exit);
MODULE_LICENSE("GPL");
测试代码
#include<stdlib.h>
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<unistd.h>
#include<string.h>
int main(int argc, char *argv[])
{
int fd;
int ret;
char buf[128];
fd = open("/dev/mycdev", O_RDWR);
if(fd < 0)
{
perror("open");
return -1;
}
while (1)
{
printf("please input: \n");
// 从终端读取数据,写入到设备文件
ret = read(0, buf, sizeof(buf));
if (ret < 0)
{
perror("read");
return -1;
}
write(fd, buf, ret);
// 从设备文件读取数据,写入到终端
ret = read(fd, buf, sizeof(buf));
if (ret < 0)
{
perror("read");
return -1;
}
write(1, buf, ret);
}
close(fd);
return 0;
}
测试结果