开始学习驱动的时候,是将驱动程序编译成模块然后用mknod命令手动建立设备节点以提供给应用程序调用。这对于刚开始调试驱动程序的时候常用的一种方法。但是,当有种需要必须在系统启动的时候就将驱动程序就绪,来供应用层程序调用。这时就不能再手动的建立设备节点了,而必须自动的创建设备节点(不需要人为的操作)。

★注册类

注册类的目的是为了使mdev可以在/dev/目录下建立设备节点。

首先要定义一个类,利用struct class结构体。这个结构体定义在头文件include/linux/device.h中

struct class {

const char* name;

struct module* owner;

struct subsystemsubsys;

struct list_headchildren;

struct list_headdevices;

struct list_headinterfaces;

struct semaphoresem;/* locks both the children and interfaces lists */

struct kobject*virtual_dir;

struct class_attribute* class_attrs;

struct class_device_attribute* class_dev_attrs;

struct device_attribute* dev_attrs;

int(*uevent)(struct class_device *dev, char **envp,

int num_envp, char *buffer, int buffer_size);

int(*dev_uevent)(struct device *dev, char **envp, int num_envp,

char *buffer, int buffer_size);

void(*release)(struct class_device *dev);

void(*class_release)(struct class *class);

void(*dev_release)(struct device *dev);

int(*suspend)(struct device *, pm_message_t state);

int(*resume)(struct device *);

}

然后使用

完成对类的注册。其中第一个参数一般为:THIS_MODULE。第二个参数为:设备节点的名称

举个例子:

★创建设备节点

创建设备节点的函数:

struct device *device_create(struct class *class, struct device *parent,dev_t devt, const char *fmt, ...)

{

va_list args;

struct device *dev = NULL;

int retval = -ENODEV;

if (class == NULL || IS_ERR(class))

goto error;

dev = kzalloc(sizeof(*dev), GFP_KERNEL);

if (!dev) {

retval = -ENOMEM;

goto error;

}

dev->devt = devt;

dev->class = class;

dev->parent = parent;

dev->release = device_create_release;

va_start(args, fmt);

vsnprintf(dev->bus_id, BUS_ID_SIZE, fmt, args);

va_end(args);

retval = device_register(dev);

if (retval)

goto error;

return dev;

error:

kfree(dev);

return ERR_PTR(retval);

}

该函数的四个参数从左到右以此为:创建设备节点所属的类、该设备的父节点(若果没有就指定为NULL)、设备号、设备名称、次设备号。

★销毁类和设备节点

注意不要忘记了还要销毁类和销毁设备节点。

销毁类:参数为用struct class结构体定义的变量

void class_destroy(struct class *cls)

{

if ((cls == NULL) || (IS_ERR(cls)))

return;

class_unregister(cls);

}销毁设备节点:

void device_destroy(struct class *class, dev_t devt)

{

struct device *dev = NULL;

struct device *dev_tmp;

down(&class->sem);

list_for_each_entry(dev_tmp, &class->devices, node) {

if (dev_tmp->devt == devt) {

dev = dev_tmp;

break;

}

}

up(&class->sem);

if (dev)

device_unregister(dev);

}

★例子(自己写的延时驱动)

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define NAME"ralink_drive_delay"

#define RALINK_GPIO_DEVNAME "my_delay"

#define delay_us 0 //most least is 10 US

#define delay_ms 1 //Ms

int delay_MAJOR = 109;

MODULE_LICENSE("Dual BSD/GPL");

static long Ralink_delay_ioctl(struct inode * inode, struct file * file, unsigned int cmd,unsigned long arg)

{

switch(cmd)

{

case delay_us:

udelay(10 * arg);

return 0;

case delay_ms:

udelay(1000);

return 0;

default:

return -1;

}

}

static struct file_operations My_delay_fops =

{

.owner = THIS_MODULE,

.ioctl = Ralink_delay_ioctl,

};

static struct class *delay_class;

static int __init my_delay_init(void)

{

int ret = 0;

ret = register_chrdev(delay_MAJOR, RALINK_GPIO_DEVNAME,&My_delay_fops);

if(ret < 0)

{

printk("unable to register character device\n");

return ret;

}

if (delay_MAJOR == 0)

{

delay_MAJOR = ret;

printk(KERN_DEBUG NAME ": got dynamic major %d\n", ret);

}

//注册一个类,使mdev可以在"/dev/目录下建立设备节点"

delay_class = class_create(THIS_MODULE, RALINK_GPIO_DEVNAME);

if(IS_ERR(delay_class))

{

printk("failed in My_led class.\n");

return -1;

}

device_create(delay_class, NULL, MKDEV(delay_MAJOR, 0),RALINK_GPIO_DEVNAME 0);//

//第一个参数是所要创建的设备所从属的类

//第二个参数是这个设备的父节点,没有指定就是NULL

//第三个参数是设备号

//第四个参数是设备名称

//第五个参数是从设备号

printk("my_delay driver initialized\n");

return 0;

}

void __exit my_delay_exit(void)

{

unregister_chrdev(delay_MAJOR,RALINK_GPIO_DEVNAME);

device_destroy(delay_class,MKDEV(delay_MAJOR,0));//注销设备节点

class_destroy(delay_class);//销毁类

printk("my_delay driver exited\n");

}

module_init(my_delay_init);

module_exit(my_delay_exit);

原文:http://blog.csdn.net/xgsilence/article/details/35650849

linux 设备节点 驱动,【Linux驱动】自动创建设备节点相关推荐

  1. linux mdev 命令,linux设备驱动----利用mdev(udev)自动创建设备文件节点

    1.mdev的使用方法和原理: mdev是busybox 自带的一个简化版的udev,适合于嵌入式的应用埸合.其具有使用简单的特点.它的作用,就是在系统启动和热插拔或动态加载驱动程序时,自动产生驱动程 ...

  2. linux驱动:自动创建设备节点

    在加载驱动模块后,就要自己使用mknod创建设备节点,这样虽然是可行的,但是比较麻烦.我们可以在__init()函数里面添加一些函数,自动创建设备节点.创建设备节点使用了两个函数 class_crea ...

  3. linux字符驱动之自动创建设备节点

    上一节中,我们是手工创建设备节点,大家肯定也会觉得这样做太麻烦了. 上一节文章链接:https://blog.csdn.net/qq_37659294/article/details/10430270 ...

  4. Linux 字符设备驱动结构(二)—— 自动创建设备节点

    上一篇我们介绍到创建设备文件的方法,利用cat /proc/devices查看申请到的设备名,设备号. 第一种是使用mknod手工创建:mknod filename type major minor ...

  5. linux内核创建节点,Linux内核驱动自动创建设备节点文件

    Linux下生成驱动设备节点文件的方法有3个:1.手动mknod:2.利用devfs:3.利用udev 在刚开始写Linux设备驱动程序的时候,很多时候都是利用mknod命令手动创建设备节点,实际上L ...

  6. linux自动创建设备节点

    在有2.6系列版本中支持udev管理设备文件可以方便的创建设备节点,不必使用mknod来创建 //主要用到的四个方法在linux/device.h定义: //创建类和释放类的函数  创建成后将创建/s ...

  7. js添加多个子节点_JS创建DOM节点-使用document.createElement()创建子节点或同级节点...

    在一个Web页面中,需要弹出一个提示信息显示给用户.基于这个需求,要使用document.createElement()创建一个DOM节点.创建完节点后,还要使用appendChild()或inser ...

  8. zk pivottable java_zookeeper节点类型和java客户端创建zk节点

    0 znode节点类型: Znode有两种类型,短暂的(ephemeral)和持久的(persistent) Znode的类型在创建时确定并且之后不能再修改 短暂znode的客户端会话结束时,zook ...

  9. Linux模块(2) - 创建设备节点

    今天计划将之前写的模块Linux模块(1) - 加载与卸载填充一下,达到设备节点创建的功能. 1. 全局数据 模块中有许多数据结构是要动态申请和释放的,就少不了一些全局数据来标记这些信息,这里通过宏M ...

最新文章

  1. js和Java分别正则匹配小数点后多余的0
  2. 联合国粮农组织总干事屈冬玉 对话国际农民丰收节贸易会
  3. hashcode的理解
  4. 高性能平台设计—美团旅行结算平台实践
  5. SQL优化老出错,那是你没弄明白MySQL解释计划
  6. 设计灵感|春节新年到!充满年味的海报给你参考
  7. 面试题50. 第一个只出现一次的字符
  8. Spring-@Value
  9. Ubuntu系统上安装微信(legacy)
  10. UVa 253 Cube paiting
  11. ogre的主要渲染流程(转)
  12. Ransac算法--直线拟合
  13. java混淆器最好_使用混淆器,保护你的java程序
  14. pageoffice如何离线申请_pageoffice常见问题
  15. 比较两个记事本文件内容的差异
  16. 计算机主机箱工作电流,电脑使用常识
  17. iphone不显示wifi连接到服务器,iPhone出现无法连接到任何WiFi怎么办 WiFi故障解决方法...
  18. Zabbix入门学习课程——Zabbix_Server安装篇
  19. thinkphp使用阿里大鱼短信接口
  20. iOS Developer:真机测试

热门文章

  1. win10 安装程序错误,the setup files are corrupted.please obtain a new copy of the program
  2. Hive belline提交命令Error: org.apache.thrift.transport.TTransportException: java.net.SocketException:
  3. leetcode 782. Transform to Chessboard | 782. 变为棋盘(Java)
  4. 【MyBatis】Mybatis实现分页效果
  5. 在Java语言里 ==和equals的区别
  6. 使类和成员的可访问性最小化
  7. google怎么做(2.相似网页算法)
  8. 【已解决】Exception in thread “Thread-0“ redis.clients.jedis.exceptions.JedisConnectionException: java.n
  9. 【最后测试点超时】1063 Set Similarity (25 分)_22行代码AC
  10. 14行代码满分:1037 在霍格沃茨找零钱 (20分)