嵌入式Linux驱动开发(三)新字符设备驱动
创始人
2025-05-30 07:00:55

  前面字符设备用register_chrdev注册设备,用unregister_chrdev注销设备。新的字符设备驱动使用linux推荐的新API。此外,前面测试的时候要自己建立设备节点,本节学习如何在加载驱动的时候自动新建节点。

1. 新字符设备驱动原理

旧方法缺陷:
  register_chrdev注册只需要给一个主设备号,但是这样就导致该主设备号下的次设备号全都归属该设备,比如led,太浪费资源。

解决方案:

<未给定设备号,向内核申请并注册设备号  PARA:设备号指针,起始设备号,申请个数,设备名>
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name)
<给定主设备号,注册设备号 通常用这个 para:起始设备号(上一行给定的),申请个数,设备名>
int register_chrdev_region(dev_t from, unsigned count, const char *name)
<注销设备号>
void unregister_chrdev_region(dev_t from, unsigned count)
/---------------------------------------------------------------/
int major;        <主设备号>
int minor;        <次设备号>
dev_t devid;      <设备号>if (major) {      <定义了主设备号>devid = MKDEV(major, 0);     <大部分驱动次设备号都选择 零>register_chrdev_region(devid, 1, "test");
} else {          <没有定义设备号>alloc_chrdev_region(&devid, 0, 1, "test");    <申请设备号>major = MAJOR(devid);                <获取分配号的主设备号>minor = MINOR(devid);                <获取分配号的次设备号>
}unregister_chrdev_region(devid, 1);      <注销设备号>

2. 新字符设备注册方法

2.1 新字符设备结构

使用cdev结构体表示一个字符设备。

struct cdev {struct kobject kobj;struct module *owner;const struct file_operations *ops;    <操作函数集合>struct list_head list;dev_t dev;       <设备号>unsigned int count;
};struct cdev test_cdev  <定义了一个字符设备test_dev>

2.2 cdev_init

用于初始化字符设备。

<函数原型>
void cdev_init(struct cdev *cdev, const struct file_operations *fops)
--------------------------------------------------------------------struct cdev testcdev;
<设备操作函数>
static struct file_operations test_fops = {.owner = THIS_MODULE,/* 其他具体的初始项 */
};testcdev.owner = THIS_MODULE;
cdev_init(&testcdev, &test_fops);   <初始化cdev结构体变量>

2.3 cdev_add

向linux系统添加字符设备。

<函数原型 Para:字符设备,设备号,添加个数>
int cdev_add(struct cdev *p, dev_t dev, unsigned count)
-------------------------------------------------------cdev_add(&testcdev, devid, 1);

2.4 cdev_del

卸载驱动时删除字符设备。
结合unregister_chrdev_region相当于unregister_chrdev。

<函数原型>
void cdev_del(struct cdev *p)
---------------------------------cdev_del(&testcdev);

3. 自动创建设备节点

3.1 mdev机制

  前面使用modprobe加载模块之后会自动在/dev下创建设备节点文件,rmmod后就会删除文件。这其实是mdev用户程序完成的,该程序可以根据系统中硬件设备状态来创建或者删除设备文件。mdev是BusyBox根据Linux下的udev构建的简化版,用于嵌入式Linux。热插拔事件也是mdev管理的
  下面学习如何用mdev实现自动管理节点。

1)创建和删除类
位置:驱动入口函数,cdev_add之后。

<创建:>

struct class *class_create (struct module *owner, const char *name)<删除:>
void class_destroy(struct class *cls);

2)创建设备
位置:驱动出口函数。

<创建:>


struct device *device_create(struct class *class, struct device *parent,dev_t devt, void *drvdata, const char *fmt, ...)
<删除:>							 
void device_destroy(struct class *class, dev_t devt)

3)设置文件私有数据
其实就是写成结构体封装一下,再open函数中作为私有数据添加到设备文件:

<设备结构体>
struct test_dev{dev_t devid;            <设备号>struct cdev cdev;       struct class *class;    <类>struct device *device;  <设备>int major;              <主设备号>int minor;              <次设备号>
};static int test_open(struct inode *inode, struct file *filp)
{filp->private_data = &testdev; /* 设置私有数据 */return 0;
}

相关内容

热门资讯

玩家实测“微乐陕西挖坑其实有挂... 您好:微乐陕西挖坑这款游戏可以开挂,确实是有挂的,需要软件加微信【4770480】,很多玩家在微乐陕...
科普实测“天天休闲到底是不是有... 您好:天天休闲这款游戏可以开挂,确实是有挂的,需要了解加客服微信【5951795】很多玩家在天天休闲...
(今日资讯)“道游牛牛.开挂辅... (今日资讯)“道游牛牛.开挂辅助神器@原来真的有挂亲,道游牛牛这个游戏其实有挂的,确实是有挂的,需要...
重磅分享“中至赣州麻将到底能开... 您好:中至赣州麻将这款游戏可以开挂,确实是有挂的,需要了解加客服微信【3636476】很多玩家在这款...
了解详情“GMG大联盟究竟有没... 你好:GMG大联盟这个游戏其实有挂的,确实是有挂的,需要了解十客服微【7676943】1.了解加微【...