Linux自己编写一个字符设备驱动的实例(+代码)

字符设备驱动

Linux字符设备提供连续的数据流,应用程序可以顺序读取,通常不支持随机存取。相反,此类设备支持按字节/字符来读写设备。举例来说,键盘,串口,调制解调器都是典型的字符设备。

设备分类

linux系统将设备分为3类:字符设备、块设备、网络设备。

  • 字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后数据。字符设备是面向流的设备,常见的字符设备有鼠标、键盘、串口、控制台和LED设备等。
  • 块设备:是指可以从设备的任意位置读取一定长度数据的设备。块设备包括硬盘、磁盘、U盘和SD卡等。
  • 网络设备:网络设备比较特殊,不在是对文件进行操作,而是由专门的网络接口来实现。应用程序不能直接访问网络设备驱动程序。在/dev目录下也没有文件来表示网络设备。

每一个字符设备或块设备都在/dev目录下对应一个设备文件。linux用户程序通过设备文件(或称设备节点)来使用驱动程序操作字符设备和块设备。

相关函数调用

struct cdev 描述字符设备的结构体

struct cdev {
   
	struct kobject kobj;//内嵌的内核对象.  
	struct module *owner;//该字符设备所在的内核模块(所有者)的对象指针,一般为THIS_MODULE主要用于模块计数  
	const struct file_operations *ops;//该结构描述了字符设备所能实现的操作集(打开、关闭、读/写、...),是极为关键的一个结构体
	struct list_head list;//用来将已经向内核注册的所有字符设备形成链表
	dev_t dev;//字符设备的设备号,由主设备号和次设备号构成(如果是一次申请多个设备号,此设备号为第一个)
	unsigned int count;//隶属于同一主设备号的次设备号的个数
};

cdev_alloc 动态申请(构造)cdev内存(设备对象)

struct cdev *cdev_alloc(void);  

struct cdev *cdev_alloc(void)
{
   
	struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL);
    //为设备申请内核内存,并对申请到的内存内容清零,GFP_KERNEL —— 正常分配内存。
	if (p) {
   
		INIT_LIST_HEAD(&p->list);//初始化链表
		kobject_init(&p->kobj, &ktype_cdev_dynamic);//初始化内核对象
	}
	return p;
}

成功的话返回值为cdev对象首地址

cdev_init 初始化cdev的成员,并建立cdev和file_operations之间关联起来

void cdev_init(struct cdev *p, const struct file_operations *p);
/* 参数:
    struct cdev *p - 被初始化的 cdev对象
    const struct file_operations *fops - 字符设备操作方法集 */
void cdev_init(struct cdev *cdev, const struct file_operations *fops)
{
   
	memset(cdev, 0, sizeof *cdev);
    //将为cdev设置的内存空间初始化,全设为0.
	INIT_LIST_HEAD(&cdev->list);
	kobject_init(&cdev->kobj, &ktype_cdev_default);
	cdev->ops = fops;//建立cdev和file_operations之间的关系
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值