char device driver--随记

字符设备驱动了解

简介

linux驱动层次图:
在这里插入图片描述
用户程序和内核驱动、硬件数据交互方法:
1、利用/dev设备节点去读、写和ioctl操作
2、利用/proc和/sys伪文件系统
驱动程序分类:
1、字符设备驱动:按字节流访问操作,如鼠标、键盘
2、块设备驱动:按block访问操作,带有缓冲,如磁盘、U盘
3、网络设备驱动:如网卡

字符设备驱动操作

1、设备号:
设备编号是设备在linux下的标识ID,这个ID在系统中唯一
设备号 由 主设备号 和 此设备号组成
主设备号:表示一类设备,表示一个特定的设备驱动程序
次设备号:表示一个特定的设备
2、数据结构:
linux内核中,dev_t类型用来表示设备号,是一个无符号32位整形数据,
3、设备号的操作宏:

MKDEV(major, minor);				//生成一个dev_t的设备号,major是主设备号,高24位,minor是次设备号,低8位
MAJOR(devno);				//从设备号devno中获取主设备号
MINOR(devno);				//从设备号devno中获取次设备号

4、设备号申请:
静态申请:用于驱动开发者事先知道该驱动主设备号

/**
 * register_chrdev_region() - register a range of device numbers
 * @from: the first in the desired range of device numbers; must include
 *        the major number. 申请设备的第一个设备的设备编号
 * @count: the number of consecutive device numbers required  申请多少个设备编号
 * @name: the name of the device or driver.  设备的名字
 *
 * Return value is zero on success, a negative error code on failure.
 */

int register_chrdev_region (dev_t from, unsigned count, const char *name);

动态申请:这种方式由系统动态分配设备号

/**
 * alloc_chrdev_region() - register a range of char device numbers
 * @dev: output parameter for first assigned number  返回第一个设备编号的地址
 * @baseminor: first of the requested range of minor numbers  第一个设备编号的次设备号
 * @count: the number of minor numbers required  申请多少个设备编号
 * @name: the name of the associated device or driver  设备的名字
 *
 * Allocates a range of char device numbers.  The major number will be
 * chosen dynamically, and returned (along with the first minor number)
 * in @dev.  Returns zero or a negative error code.
 */
int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count,
			const char *name)
{
	struct char_device_struct *cd;
	cd = __register_chrdev_region(0, baseminor, count, name);
	if (IS_ERR(cd))
		return PTR_ERR(cd);
	*dev = MKDEV(cd->major, cd->baseminor);
	return 0;
}

释放设备编号:

/**
 * unregister_chrdev_region() - unregister a range of device numbers
 * @from: the first in the range of numbers to unregister  要释放设备的第一个设备的设备编号
 * @count: the number of device numbers to unregister  释放多少个设备编号
 *
 * This function will unregister a range of @count device numbers,
 * starting with @from.  The caller should normally be the one who
 * allocated those numbers in the first place...
 */
 
void unregister_chrdev_region(dev_t from, unsigned count)

5、注册初始化字符设备
linux内核中对每一类设备都有相应的数据结构表示,字符设备使用struct cdev(linux/cdev.h)来表示,就会字符设备驱动必须申请struct cdev实例来表示

struct cdev {
	struct kobject kobj;	//kobject设备对象
	struct module *owner;	//数据哪个模块
	const struct file_operations *ops;		//文件操作
	struct list_head list;		//链表结构
	dev_t dev;		//设备号
	unsigned int count;		//字符设备的数量
} __randomize_layout;

cdev字符设备实例操作函数:

1、给字符设备申请空间
struct cdev *cdev_alloc (void);

2、初始化字符设备
void cdev_init (struct cdev *dev, const struct file_operation *fops);
dev:字符设备结构实例地址
fops:文件操作结构实例地址

3、注册字符设备
int cdev_add (struct cdev *dev, dev_t devno, unsigned count);
dev:字符设备结构实例地址
devno:设备编号
count:设备数量

6、创建设备节点
1、mknod:手动创建
mknod /dev/name c major minor
其中 “name”可以是任意符合unix下路径名的名字,不一定要是代码里定义的驱动或设备的名字;c 表示创建字符设备节点, major是成功申请的主设备号,minor是次设备号,这个可以是任意的(在次设备号范围内)

2、udev自动创建
需要在代码中创建一个设备类,然后在这个设备类的基础上,创建一个设备号,

定义全局变量:
struct class *gclass = NULL;
struct device *gdevice = NULL;
gclass = class_create (THIS_MODULE, "jiedian");    //创建一个设备类
gdevice = device_create (gclass, 
				NULL,    //父设备 parent
				devno,    //设备编号
				NULL,    //设备私有数据
				"jiedian");     //设备节点的名字
删除设备节点:
device_destroy (gdevice, devno);    //移除设备 自动删除已经创建的节点
class_destroy (gclass);    //移除设备类

总结:
Step 1:申请设备号(静态、动态)
Step 2:注册字符设备 (围绕struct cdev)
struct cdev *cdev_alloc(void);
void cdev_init(struct cdev *cdev, const struct file_operations *fops) ;
int cdev_add(struct cdev *p, dev_t dev, unsigned count);
Step 3:创建设备节点 (两种方式)
通过 mknod命令手动创建;
通过udev自动生成(后台跑udevd应用程序)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值