Linux 字符设备驱动开发详解:cdd_demo 示例

本示例代码演示了如何创建一个简单的 Linux 字符设备驱动,名为 cdd_demo

代码解析

#define CDD_MAJOR 200
#define CDD_MINOR 0
#define CDD_COUNT 1
dev_t dev;
struct cdev cdev;
struct class *cdd_class;//设备类指针
struct device *cdd_device;//设备文件指针

int cdd_open(struct inode *inode,struct file *filp)
{
	printk('enter cdd_open\n');
}

ssize_t  cdd_read(struct file *filp,char __user *buf,size_t size ,loff_t  loff)
{
	printk('cdd_read\n');
}

ssize_t  cdd_write(struct file *filp,const char __user *buf,size_t size ,loff_t  loff)
{
	printk('cdd_write\n');
}


long cdd_ioctl (struct file *filp,unsigned int cmd,unsigned long data)
{
	printk('cdd_ioctrl\n');
}

struct file_operations cdd_fops={
.owner=THIS_MODULE,
.open=cdd_open,
.read=cdd_read,
.write=cdd_write,
unlocked_ioctl=cdd_ioctl,//oictl接口
.release=cdd_release,
}

int myinit(void)
{
int ret;
ret=alloc_chrdev_region(&dev,CDD_MINOR,CDD_COUNT,'cdd_demo');
if(ret<0) {printk('device init error.\n');return ret;}
cdev_init(&cdd_cdev,&cdd_fops);
ret=cdev_add(&cdd_cdev,dev,CDD_COUNT);
if(ret<0) {printk('device init error.\n');unregister_chrdev_region(dev,CDD_COUNT);return ret;}
printk('succeed.\n');
cdd_class=class_create(THIS_MODULE,'cdd_class');
if(IS_ERR(cdd_class)){
	cdev_del(&cdd_cdev);
	unregister_chrdev_region(dev,CDD_COUNT);
	printk('class_create failed.\n');
	ret=PTR_ERR(cdd_class);
	return ret;}
// 4创建设备文件
cdd_device=device_create(cdd_class,NULL,dev,NULL,'cdd');
if(IS_ERR(cdd_device)){
	class_destroy(cdd_class,dev);
	cdev_del(&cdd_cdev);
	unregister_chrdev_region(dev,CDD_COUNT);
	printk('class_create faile.\n');
	ret=PTR_ERR(cdd_device);
	return ret;}
return 0;	
}
void myExit(void)
{
	device_destroy(cdd_device);// 4
	class_destroy(cdd_class,dev);// 3
	cdev_del(&cdd_cdev);// 2
	unregister_chrdev_region(dev,CDD_COUNT);// 1
}
	module_init(myinit);
	module_exit(myExit);

MODULE_LICENSE('GPL');
MODULE_AUTHOR('xxxxx');
MODULE_VERSION('1.0');
MODULE_DESCRIPTION('A symbol TEST');

每行代码的功能解释:

  1. 定义设备号:

    • #define CDD_MAJOR 200: 定义主设备号为 200。
    • #define CDD_MINOR 0: 定义次设备号为 0。
    • #define CDD_COUNT 1: 定义设备数量为 1。
  2. 定义设备结构体变量:

    • dev_t dev: 定义设备号变量。
    • struct cdev cdev: 定义字符设备结构体变量。
    • struct class *cdd_class: 定义设备类指针。
    • struct device *cdd_device: 定义设备文件指针。
  3. 实现设备操作函数:

    • cdd_open():设备打开函数。
    • cdd_read():设备读函数。
    • cdd_write():设备写函数。
    • cdd_ioctl():设备 ioctl 函数。
  4. 定义设备文件操作结构体变量:

    • struct file_operations cdd_fops: 定义设备文件操作结构体变量,包含对应的函数指针。
  5. 实现设备初始化函数:

    • myinit()
      • alloc_chrdev_region(): 分配设备号。
      • cdev_init(): 初始化字符设备结构体。
      • cdev_add(): 注册字符设备。
      • class_create(): 创建设备类。
      • device_create(): 创建设备文件。
  6. 实现设备退出函数:

    • myExit()
      • device_destroy(): 销毁设备文件。
      • class_destroy(): 销毁设备类。
      • cdev_del(): 删除字符设备。
      • unregister_chrdev_region(): 注销设备号。
  7. 定义模块初始化和退出函数:

    • module_init(myinit): 定义模块初始化函数。
    • module_exit(myExit): 定义模块退出函数。
  8. 定义模块信息:

    • MODULE_LICENSE('GPL'): 定义模块许可证类型。
    • MODULE_AUTHOR('xxxxx'): 定义模块作者。
    • MODULE_VERSION('1.0'): 定义模块版本。
    • MODULE_DESCRIPTION('A symbol TEST'): 定义模块描述。

总结

本示例代码展示了如何创建、注册和使用 Linux 字符设备驱动,为开发者提供了一个基础框架,可以根据实际需要进行扩展和修改。

Linux 字符设备驱动开发详解:cdd_demo 示例

原文地址: https://www.cveoy.top/t/topic/oUw9 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录