栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

Linux驱动——实现对设备文件的读写操作和ioctl操作

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Linux驱动——实现对设备文件的读写操作和ioctl操作

#include 
#include 
#include 
#include 
#include 
#include 

#define DEV_MINOR 0
#define DEV_CNT 1
#define DEV_DATA_SIZE 127
#define DEV_ONE _IO('j', 0)
#define DEV_TWO _IO('j', 1)

char data[DEV_DATA_SIZE + 1] = {0};

ssize_t myread (struct file * fp, char __user * buf, size_t size, loff_t * offset)
{
	int ret;
	printk("enter myreadn");
	if(size > DEV_DATA_SIZE) {
		size = DEV_DATA_SIZE;
	}

	ret = copy_to_user(buf, data, size);
	if(ret) {
		printk("copy to user error.n");
		return -EFAULT;
	}
	return 0;
}

int myrelease (struct inode * pnode, struct file * fp)
{
	printk("enter myreleasen");
	return 0;
}


int myopen (struct inode * pnode, struct file * fp)
{
	printk("enter myopenn");
	return 0;
}
ssize_t mywrite (struct file * fp, const char __user *buf, size_t size, loff_t *offset)
{
	int ret;
	printk("enter writen");
	if(size > 127) {
		printk("size is invalid.n");
		return -ENOMEM;
	}
	ret = copy_from_user(data, buf, size);
	if(ret) {
		printk("copy from user error.n");
		return -EFAULT;
	}
	return 0;
}

long myioctl (struct file * fp, unsigned int cmd, unsigned long data)
{
	switch(cmd) {
		case DEV_ONE:
			printk("DEV ONEn");
			break;
		case DEV_TWO:
			printk("DEV WTOn");
			break;
		default:
			printk("invalid input.n");
			break;
	}
	return 0;
}

dev_t dev;
const struct file_operations myfops ={
	.owner = THIS_MODULE,
	.open = myopen,
	.read = myread,
	.write = mywrite,
	.release = myrelease,
	.unlocked_ioctl = myioctl
};
struct cdev mycdev;
struct class *chrdev_class;
struct device *mydevice;

int chrdev_init(void)
{
	int ret;
	ret = alloc_chrdev_region(&dev, DEV_MINOR, DEV_CNT, "chrdev");
	if(ret < 0) {
		printk("alloc_chrdev_region failed!n");
		goto alloc_chrdev_fail;
	}
	cdev_init(&mycdev, &myfops);
	ret = cdev_add(&mycdev, dev, DEV_CNT);
	if(ret < 0) {
		printk("cdev_add failed!n");
		goto alloc_chrdev_region_fail;
	}
	chrdev_class = class_create(THIS_MODULE, "chrdevs");
	if(IS_ERR_OR_NULL(chrdev_class)) {
		printk("class_create failed.n");
		goto class_create_fail;
		
	}
	mydevice = device_create(chrdev_class, NULL, dev, NULL, "mydevice" );
	if(IS_ERR_OR_NULL(mydevice)) {
		printk("device_create failed.n");
		goto device_create_fail;
	}
	printk("chrdev init completed.n");
	return 0;
	
device_create_fail:
	class_destroy(chrdev_class);
class_create_fail:
	cdev_del(&mycdev);
alloc_chrdev_region_fail:
	unregister_chrdev_region(dev, DEV_CNT);
alloc_chrdev_fail:
	return -ENODEV;
}

void chrdev_exit(void)
{
	device_destroy(chrdev_class, dev);
	class_destroy(chrdev_class);
	cdev_del(&mycdev);
	unregister_chrdev_region(dev, DEV_CNT);
	printk("device unregister completed.n");
}
module_init(chrdev_init);
module_exit(chrdev_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("David-Woo");
MODULE_DEscriptION("char device driver example");

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/342243.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号