字符设备驱动的创建(code)

/******************************************************/

1、创建设备号 dev_t dev;
2、申请设备号
静态注册设备号 int register_chrdev_region(dev_t from, unsigned count, const char *name)
动态分配设备号 int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name)

3、定义一个字符设备
struct cdev chrdev_test;
4、定义一个文件操作集,并对文件操作集进行初始化
struct file_operations chdev_fops = {
.open = test_open,
.read = test_read,
.write = test_write,
.ioctl = test_ioctl,
.release = test_release,
};

5、字符设备的初始化 void cdev_init(struct cdev *cdev, const struct file_operations *fops)

6、将字符设备加入到内核 int cdev_add(struct cdev *p, dev_t dev, unsigned count)

//动态创建设备文件
7、创建设备类
//会在/sys/class目录下创建"cdd_class"为名的文件夹
dev_class = class_create(THIS_MODULE, "cdd_class");
if(IS_ERR(dev_class))
{
ret = PTR_ERR(dev_class);
goto failure_class_create;
}
8、创建设备文件
//会在/dev目录下创建对应的设备文件
dev_device = device_create(dev_class, NULL, dev, NULL, "cdd");
if(IS_ERR(dev_device))
{
ret = PTR_ERR(dev_device);
goto failure_device_create;
}

9、注销一个设备号 void unregister_chrdev_region(dev_t from, unsigned count)

10、注销一个字符设备 void cdev_del(struct cdev *p)

/******************************** cdd.c *************************/
#include <linux/init.h>
#include <linux/module.h>

#include <linux/fs.h>
#include <linux/cdev.h>
#include <linux/device.h>

MODULE_LICENSE("GPL v2");

#define CDD_MAJOR 100
#define CDD_MINOR 0
#define CDD_COUNT 1

dev_t dev;
u32 cdd_minor = 0;
//实例化cdev
struct cdev cdd_cdev;

struct class *dev_class = NULL;
struct device *dev_device = NULL;

int cdd_open(struct inode *inode, struct file *filp)
{
printk("enter cdd_open!\n");
return 0;
}

ssize_t cdd_read(struct file *filp, char __user *buf, size_t count, loff_t *offset)
{
printk("enter cdd_read!\n");
return 0;
}

ssize_t cdd_write(struct file *filp, const char __user *buf, size_t count, loff_t *offset)
{
printk("enter cdd_write!\n");
return 0;
}

int cdd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data)
{
printk("enter cdd_ioctl!\n");
return 0;
}

int cdd_release(struct inode *inode, struct file *filp)
{
printk("enter cdd_release!\n");
return 0;
}

struct file_operations cdd_fops =
{
.owner = THIS_MODULE,
.open = cdd_open,
.read = cdd_read,
.write = cdd_write,
.ioctl = cdd_ioctl,
.release = cdd_release,
};

int __init cdd_init(void)
{
int ret = 0;
if(cdd_minor)//静态分配
{
dev = MKDEV(CDD_MAJOR,CDD_MINOR);

//向内核申请
ret = register_chrdev_region(dev, CDD_COUNT, "cdd_demo");
}
else//动态分配
{
ret = alloc_chrdev_region(&dev, cdd_minor, CDD_COUNT, "cdd_demo");
}
if(ret<0)
{
printk("register_chrdev failed!\n");
goto faiure_register_chrdev;
}

//初始化cdev
cdev_init(&cdd_cdev, &cdd_fops);
//向内核注册cdev
ret = cdev_add(&cdd_cdev, dev, CDD_COUNT);
if(ret<0)
{
printk("cdev_add failed!\n");
goto failure_cdev_add;
}

/*动态创建设备文件*/
// 1.创建设备类
//会在/sys/class目录下创建"cdd_class"为名的文件夹
dev_class = class_create(THIS_MODULE, "cdd_class");
if(IS_ERR(dev_class))
{
ret = PTR_ERR(dev_class);
goto failure_class_create;
}
// 2.创建设备文件
//会在/dev目录下创建对应的设备文件
dev_device = device_create(dev_class, NULL, dev, NULL, "cdd");
if(IS_ERR(dev_device))
{
ret = PTR_ERR(dev_device);
goto failure_device_create;
}
return 0;

failure_device_create:
class_destroy(dev_class);
failure_class_create:
cdev_del(&cdd_cdev);
failure_cdev_add:
unregister_chrdev_region(dev, CDD_COUNT);
faiure_register_chrdev:
return ret;
}

void __exit cdd_exit(void)
{
//注销设备
device_destroy(dev_class, dev);
//注销设备类
class_destroy(dev_class);
//注销cdev
cdev_del(&cdd_cdev);
//注销设备号
unregister_chrdev_region(dev, CDD_COUNT);
}

module_init(cdd_init);
module_exit(cdd_exit);
/********************************* cdd_test.c ***********************************/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>

int fd;
char ch;
char buf[10];

int main()
{
fd = open("/dev/cdd",O_RDWR);
if(fd<0)
{
printf("open failed!\n");
return -1;
}

printf("open successwd fd = %d\n",fd);

while(1)
{
ch = getchar();
getchar();//读走回车
if(ch=='q')
break;

switch(ch)
{
case 'r':
read(fd,buf,0);
break;
case 'w':
write(fd,buf,0);
break;
case 'o':
ioctl(fd,buf,0);
break;
default:
printf("unknow input!\n");
break;
}
sleep(3);
}

close(fd);
return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值