linux设备文件生成,Linux设备文件自动生成

第一种是使用mknod手工创建:# mknod

第二种是自动创建设备节点:利用udev(mdev)来实现设备文件的自动创建,首先应保证支持udev(mdev),由busybox配置。

具体udev相关知识这里不详细阐述,可以移步Linux 文件系统与设备文件系统 —— udev 设备文件系统,这里主要讲使用方法。

在驱动用加入对udev 的支持主要做的就是:在驱动初始化的代码里调用class_create(...)为该设备创建一个class,再为每个设备调用device_create(...)创建对应的设备。

内核中定义的struct class结构体,顾名思义,一个struct class结构体类型变量对应一个类,内核同时提供了class_create(…)函数,可以用它来创建一个类,这个类存放于sysfs下面,一旦创建好了这个类,再调用 device_create(…)函数来在/dev目录下创建相应的设备节点。

这样,加载模块的时候,用户空间中的udev会自动响应 device_create()函数,去/sysfs下寻找对应的类从而创建设备节点。

下面是两个函数的解析:

支持字符设备文件自动生成

linux/device.h

struct class *class_create(struct module *owner, const char *name);

/*

功能:在/sys/class目录下创建一个目录,目录名是name指定的

参数:

struct module *owner - THIS_MODULE

const char *name - 设备名

返回值:

成功:class指针

失败: - bool IS_ERR(const void *ptr)  判断是否出错

long PTR_ERR(const void *ptr)  转换错误码

*/

void class_destroy(struct class *cls);

/*

功能:删除class指针指向的目录

参数:

struct class *cls - class指针

*/

struct device *device_create(struct class *cls, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...);

/*

功能:

在class指针指向的目录下再创建一个目录,目录名由const char *fmt, ...指出、并导出设备信息(dev_t)

参数:

struct class *cls - class指针

struct device *parent - 父对象,NULL

dev_t devt - 设备号

void *drvdata - 驱动私有数据

const char *fmt, ... - fmt是目录名字符串格式,...就是不定参数

返回值:

成功 - device指针

失败 - bool IS_ERR(const void *ptr)  判断是否出错

long PTR_ERR(const void *ptr)   转换错误码

*/

void device_destroy(struct class *cls, dev_t devt);

/*

功能:删除device_create创建的目录

参数:

struct class *cls - class指针

dev_t devt - 设备号

*/

创建次序

struct class *class_create(struct module *owner, const char *name);

struct device *device_create(struct class *cls, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...);

删除次序

void device_destroy(struct class *cls, dev_t devt);

void class_destroy(struct class *cls);

实例:

#include

#include

#include

#include

#include

#include

#include

#include

#include

MODULE_LICENSE("GPL");

static struct class *cls = NULL;

static int major = ;

static int minor = ;

const int count = ;

#define DEVNAME "demo"

static struct cdev *demop = NULL;

//打开设备

static int demo_open(struct inode *inode, struct file *filp)

{

//get command and pid

printk(KERN_INFO "%s : %s : %d\n", __FILE__, __func__, __LINE__);return ;

}

//关闭设备

static int demo_release(struct inode *inode, struct file *filp)

{

//get major and minor from inode

printk(KERN_INFO "%s : %s : %d\n", __FILE__, __func__, __LINE__);

return ;

}

static struct file_operations fops = {

.owner = THIS_MODULE,

.open = demo_open,

.release= demo_release,

};

static int __init demo_init(void)

{

dev_t devnum;

int ret, i;

struct device *devp = NULL;

//1. alloc cdev obj

demop = cdev_alloc();

if(NULL == demop){

return -ENOMEM;

}

//2. init cdev obj

cdev_init(demop, &fops);

ret = alloc_chrdev_region(&devnum, minor, count, DEVNAME);

if(ret){

goto ERR_STEP;

}

major = MAJOR(devnum);

//3. register cdev obj

ret = cdev_add(demop, devnum, count);

if(ret){

goto ERR_STEP1;

}

cls = class_create(THIS_MODULE, DEVNAME);

if(IS_ERR(cls)){

ret = PTR_ERR(cls);

goto ERR_STEP1;

}

for(i = minor; i < (count+minor); i++){

devp = device_create(cls, NULL, MKDEV(major, i), NULL, "%s%d", DEVNAME, i);

if(IS_ERR(devp)){

ret = PTR_ERR(devp);

goto ERR_STEP2;

}

}

return ;

ERR_STEP2:

for(--i; i >= minor; i--){

device_destroy(cls, MKDEV(major, i));

}

class_destroy(cls);

ERR_STEP1:

unregister_chrdev_region(devnum, count);

ERR_STEP:

cdev_del(demop);

//get command and pid

printk(KERN_INFO "%s : %s : %d - fail.\n", __FILE__, __func__, __LINE__);

return ret;

}

static void __exit demo_exit(void)

{

int i;

//get command and pid

printk(KERN_INFO "%s : %s : %d - leave.\n", __FILE__, __func__, __LINE__);

for(i=minor; i < (count+minor); i++){

device_destroy(cls, MKDEV(major, i));

}

class_destroy(cls);

unregister_chrdev_region(MKDEV(major, minor), count);

cdev_del(demop);

}

module_init(demo_init);

module_exit(demo_exit);

下面可以看几个class几个名字的对应关系:

14268c0c0af89ecc742021df9e529d1b.png

(转载)使用 udev 高效、动态地管理 Linux 设备文件

概述: Linux 用户常常会很难鉴别同一类型的设备名,比如 eth0, eth1, sda, sdb 等等.通过观察这些设备的内核设备名称,用户通常能知道这些是什么类型的设备,但是不知道哪一个设备是 ...

嵌入式 使用udev高效、动态地管理Linux 设备文件

本文以通俗的方法阐述 udev 及相关术语的概念.udev 的配置文件和规则文件,然后以 Red Hat Enterprise Server 为平台演示一些管理设备文件和查询设备信息的实例.本文会使那 ...

【转】使用 udev 高效、动态地管理 Linux 设备文件

简介: 本文以通俗的方法阐述 udev 及相关术语的概念.udev 的配置文件和规则文件,然后以 Red Hat Enterprise Server 为平台演示一些管理设备文件和查询设备信息的实例.本 ...

使用maven根据JSON文件自动生成Java POJO类(Java Bean)源文件

根据JSON文件自动生成Java POJO类(Java Bean)源文件 本文介绍使用程序jsonschema2pojo来自动生成Java的POJO类源文件,本文主要使用maven,其他构建工具请参考 ...

CCS 6新建文件自动生成注释

对于CCS6,可以通过配置,达到新建源文件或者头文件时,自动生成适当的注释: 一.新建源文件自动生成配置. 在某个文件夹下右击选择 New - Source File. 点击 Configure,再选 ...

使用 udev 高效、动态地管理 Linux 设备文件

本文转自:https://www.ibm.com/developerworks/cn/linux/l-cn-udev/index.html 概述: Linux 用户常常会很难鉴别同一类型的设备名,比如 ...

使用 udev 管理 Linux 设备文件

本文以通俗的方法阐述 udev 及相关术语的概念.udev 的配置文件和规则文件,然后以 Red Hat Enterprise Server 为平台演示一些管理设备文件和查询设备信息的实例.本文会使那 ...

文件参数化-utp框架之根据yaml文件自动生成python文件&plus;utp运行用例

根据yaml文件自动生成python文件 utp框架: bin目录:存放执行文件(run.py) cases目录:存放生成的用例的python文件(该目录下的文件为根据data目录下的测试用例生成的p ...

IntelliJ IDEA 创建的文件自动生成 Author 注释 签名

IntelliJ IDEA 创建的文件自动生成 Author 注释 签名1.打开 File --> Setting2.找到 Editor --> File and Code Templat ...

随机推荐

JAVA字符串格式化-String&period;format&lpar;&rpar;的使用

String类的format()方法用于创建格式化的字符串以及连接多个字符串对象.熟悉C语言的同学应该记得C语言的sprintf()方法,两者有类似之处.format()方法有两种重载形式. form ...

MongoDB 驱动以及分布式集群读取优先级设置

本文主要介绍使用MongoDB C驱动读取分布式MongoDB集群时遇到的坑,主要在读取优先级和匹配tag上:同时简单介绍Python驱动.Node.js驱动.Mongoose驱动如何使用读取优先级和 ...

Android studio &period;9图片造成的错误总结

前言,今天早晨遇到一个很奇葩的问题,导致我花费了很长的时间来解决.从eclipse 项目里复制过来4张.9图片,粘贴到android studio 项目里, 一运行发现报错,开始是 找不到这几张.9图 ...

ES questions

Be Careful of Cardinality Numeric and date fields are indexed in such a way that ranges are efficien ...

PHP学习笔记-3

PHP 数据类型: 字符串.整数.浮点数.逻辑.数组.对象.NULL. JavaScript数据类型: 字符串.数字.布尔.数组.对象.Null.Undefined. 从上面可以看出来,数据类型都是7 ...

fedora 使用 vnc 远程 fedora 28 主机

问题重述: 最近环境中需要使用 fedora 28 来进行远程桌面,于是就重新配置了一下vnc 在这里面做一下记录. 过程: yum 安装: 工作机上安装 vncviewer 远程主机上安装: vnc ...

java重写LinkedList

LinkedList重写类LinkList.java: import java.util.LinkedList;import java.util.List; public class LinkList ...

STM32 中 BIT&lowbar;BAND(位段&sol;位带)和别名区使用入门&lpar;转载&rpar;

一. 什么是位段和别名区 是这样的,记得MCS51吗? MCS51就是有位操作,以一位(BIT)为数据对象的操作,MCS51可以简单的将P1口的第2位独立操作: P1.2=0;P1.2=1 :这样就把 ...

IOS UI-键盘处理和UIToolbar

// // ViewController.m // IOS_0225-键盘处理和UIToolBar // // Created by ma c on 16/2/25. // Copyright © 2 ...

IOS Intro - UIWindow UIView and CALayer

UIWindow.UIView以及CALayer之间的关系2016-05-11 20:46 本站整理 浏览(16) UIWindow1.简介UIWindow是一种特殊的UIView,通常在一个app中 ...

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值