Linux系统驱动(四)自动创建设备节点

自动创建设备节点

(一)创建设备节点的机制

1. mknod

将驱动编译到内核中,在内核启动时驱动自动被安装执行

2.devfs(2.4内核)

3. udev(2.6内核至今)

在这里插入图片描述

  • 注:hotplug — 热插拔

(二)API

1. 向上提交目录

#include <linux/device.h>
struct class * class_create(owner, name)
功能:向上提交目录
参数:
 @owner:THIS_MODULE 这个宏和模块安装卸载相关,并且会记录模块的引用计数值。
 @name:目录名
返回值:成功返回结构体指针,失败返回错误码指针
  • 补:
  • 通过IS_ERR(cls)来判断是否失败。该宏定义在在cls是错误码指针时返回真,否则为假
  • 当cls是错误码指针时,可以通过PTR_ERR(cls)来获得失败返回的错误码

2. 销毁目录

#include <linux/device.h>
void class_destroy(struct class *cls)
功能:销毁向上提交目录后产生的结构体
参数:
	@cls:结构体指针
返回值:无

3. 向上提交创建节点的信息

struct device *device_create(struct class *class, struct device *parent,
        dev_t devt, void *drvdata, const char *fmt,...)
功能:向上提交创建节点的信息
参数:
 @class:指向目录的句柄
 @parent:填写为NULL
 @devt:设备号 (241,0=>(241<<20|0)
        MKDEV(major,minor) //将主和次设备号合成设备号
  		MAJOR(devno);  //从设备号中获取主设备号
  		MINOR(devno);  //从设备号中获取次设备号
 @drvdata:驱动的私有数据,一般填写为NULL。
 @fmt,...:创建节点的名字  "myled%d",i
返回值:成功返回结构体指针,失败返回错误码指针
  • 注:
  • MKDEV(ma,mi) 将主次设备号拼接成设备号
  • MAJOR(devno) 从设备号中获取主设备号
  • MINOR(devno) 从设备号中获取次设备号

4. 销毁节点的信息

void device_destroy(struct class *class, dev_t devt)
功能:销毁节点的信息
参数:
 @class:指向目录的句柄
 @devt:设备号 (241,0=>(241<<20|0)
返回值:无

5. IS_ERR(cls)的实现机制

(三)使用示例

功能需求:在上一篇驱动的基础上加入自动创建设备节点,而无需使用mknod来手动创建
需求分析
设备文件是需要在应用层的open函数就需要使用,因此在驱动中自动创建节点就必须要在mydev_open函数之前实现,因此在mydev_init函数中进行自动创建设备节点,在mydev_exit函数中进行销毁创建的设备节点
代码实现(此处只展示有修改的代码部分):
LED.c

static int __init myioctl_init(void){
    //入口注册设备
    major=register_chrdev(0,CHRNAME,&myfops); //第一个参数为0,表示由系统分配主设备号,此时返回值就是系统分配的主设备号
    if(major < 0){//说明出错,返回了错误码,错误码均为负数
        pr_err("register_chrdev error:%d\n",major);
        return major; //失败返回错误码
    }
    printk("major=%d\n",major);
    //向上提交目录
    mycls = class_create(THIS_MODULE,"class_name");
    if(IS_ERR(mycls)){//成功返回结构体指针,失败返回错误码指针
        //为真则说明是错误码指针
        pr_err("class create error:%ld\n",PTR_ERR(mycls));
        return PTR_ERR(mycls); //出错返回错误码
    }
    //向上提交节点信息
    mydev = device_create(mycls,NULL,MKDEV(major,0),NULL,"myioctl");
    if(IS_ERR(mydev)){//成功返回结构体指针,失败返回错误码指针
        //为真则说明是错误码指针
        pr_err("class create error:%ld\n",PTR_ERR(mydev));
        return PTR_ERR(mydev); //出错返回错误码
    }
    return 0; //成功返回0
}

static void __exit myioctl_exit(void){
    //销毁节点信息
    device_destroy(mycls,MKDEV(major,0));
    //销毁目录信息
    class_destroy(mycls);
    //出口销毁设备
    unregister_chrdev(major,CHRNAME);
}
  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值