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

linux驱动学习——自动创建设备节点

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

linux驱动学习——自动创建设备节点

文章目录
    • 7.1、udev
    • 7.2、函数说明
    • 7.3、示例代码

7.1、udev

linux传统上使用静态设备创建方法,因此大量设备节点在/dev下创建(有时上千个),而不管相应的硬件设备是否真正存在。

采用udev的方法,只有被内核监测到的设备,才会去为它们创建设备节点。

当插入新设备——加入驱动模块——在sysfs上注册新的数据后,udev会创建新的设备节点。


linux系统中/sys/devices/virtual/input/xxx路径下,dev文件和uevent文件会存储驱动的设备号以及设备的名称。

7.2、函数说明
  • class_create 创建一个类
#define class_create(owner, name)		
({						
	static struct lock_class_key __key;	
	__class_create(owner, name, &__key);	
})

参数:

  • @owner:THIS_MOUDLE
  • @name:类名字

返回值

定义一个struct class的指针变量cls接受返回值,然后通过IS_ERR(cls)判断是否失败;

如果成功这个宏返回0,失败返回非0值;可以通过PTR_ERR(cls)来获得失败返回的错误码。

  • class_destroy 注销类
void class_destroy(struct class *cls)
{
	if ((cls == NULL) || (IS_ERR(cls)))
		return;

	class_unregister(cls);
}
  • device_create 导出设备信息到用户空间
struct device *device_create(struct class *class, struct device *parent,
			     dev_t devt, void *drvdata, const char *fmt, ...)
{
	va_list vargs;
	struct device *dev;

	va_start(vargs, fmt);
	dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs);
	va_end(vargs);
	return dev;
}
  • 参数:
    • @class:class_create创建的类;
    • @parent:父节点,可以为NULL
    • @devt:设备号
    • @drvdata:参数,可以为NULL
    • @fmt:可变参数

  • device_destroy 注销设备信息
void device_destroy(struct class *class, dev_t devt)
{
	struct device *dev;

	dev = class_find_device(class, NULL, &devt, __match_devt);
	if (dev) {
		put_device(dev);
		device_unregister(dev);
	}
}
7.3、示例代码
#include 
#include 
#include 
#include 
#include 

static int major = 230;
static int minor = 0;
static dev_t devno;
static struct class *cls = NULL;
static struct device *class_dev = NULL;
static int hello_open(struct inode *inode, struct file *file)
{
	printk("hello_open n");
	return 0;
}

static int hello_release(struct inode *inode, struct file *file)
{
	printk("hello_release n");
	return 0;
}

static struct file_operations fops = {
	.open = hello_open,
	.release = hello_release,
};
static int hello_init(void)
{
	int ret;
	printk("hello_init() n");
	ret = register_chrdev(major, "hello_test", &fops);

	if(ret < 0)
	{
		printk("register_chrdev() filen");
		return ret;
	}

	cls = class_create(THIS_MODULE,"hello_cls");
	if (IS_ERR(cls )) {
		ret = PTR_ERR(cls );
		goto out_err_0;
	}
	devno = MKDEV(major, minor);
	class_dev = device_create(cls, NULL, devno, NULL,"hello_dev");
	if (IS_ERR(class_dev)) {
		printk("device_create failedn");
		ret = PTR_ERR(class_dev);
		goto out_err_1;
	}
	return 0;
out_err_1:
	class_destroy(cls);
out_err_0:
	unregister_chrdev(major, "hello_test");
	return ret;

}
static void hello_exit(void)
{
	printk("hello_exit() n");
	device_destroy(cls,devno);
	class_destroy(cls);
	unregister_chrdev(major, "hello_test");
	return ;
}

MODULE_LICENSE("GPL");
module_init(hello_init);
module_exit(hello_exit);
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/510700.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

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

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