Linux字符设备驱动——Linux2.6标准字符设备驱动模型

本文详细介绍了Linux2.6标准字符设备驱动模型,包括设备特征、定义、结构体、头文件、设备号、核心结构初始化、注册与注销函数等。还概述了编写字符设备驱动的步骤,强调了设备号的动态与静态注册,以及如何处理错误和注销设备。
摘要由CSDN通过智能技术生成

Linux2.6标准字符设备特征

  1. 使用一个核心结构体把需要的信息进行封装struct cdev;
  2. 安装驱动后,不会在/dev/目录下创建设备节点,需要使用mknod创建;
  3. 主设备号可以被注册多次,每次注册只会占用指定数量的次设备;
  4. 设备号使用要先使用专门的函数申请,分为静态和动态.

动态:不知道哪个号可以用,由内核分配
静态:用用户指定的号进行申请

Linux2.6标准字符设备定义

字符设备驱动结构体

struct cdev 
{
	struct kobject kobj;
	struct module *owner;
	const struct file_operations *ops;	//设备文件操作方法
	struct list_head list;
	dev_t dev;                    					//32位设备号,包含主次
	unsigned int count;							//需要占用的连续次设备号的个数
};

ops:文件操作集合指针
dev:起始设备号,(包含主次设备号,dev_t实际上是一个u32类型)

头文件

#include<linux/cdev.h>

设备号

使用32位数据类型表示,其中12位表示主设备号,低20位表示次设备号。
主:0~4096-1
次:0~1M-1
专门定义了dev_t类型来存放设备号类型,实际就是unsigned long类型

由于主次设备号都在一个数据中,内核提供了一些宏来合成设备号和分离设备号

MKDEV(ma,mi) ma主设备号,mi此设备号,这个宏是合成设备号
MAJOR(devnr) 从设备号devnr中得到主设备号
MANOR(devor) 从设备号devnr中得到次设备号

分配核心结构函数

struct cdev *cdev_alloc(void)
功能:在堆区空间中分配一个核心结构cdev,注意,不使用时候要使用 kfree 函数释放。

返回值:返回分配到struct cdev结构空间首地址。

注意:说明:用完记得释放,否则会造成内存泄漏。
如果在静态存储区中定义全局变量,可以不适用这个函数,需要输入以下代码:

struct cdev dev;
dev.count = 1;

如果想在堆空间中分配 cdev结构空间,就使用这个函数。出于内存利用率考虑建议使用这个函数进行分配核心结构空间。
输入以下代码实现:

  struct cdev *pdev;
  pdev = cdev_alloc();
  pdev->count = 1;

静态设备号注册函数


int register_chrdev_region(
    dev_t from         	    //起始设备号(主、次)
    unsigned count,         //连续的次设备号数量
    const char *name )    //设备名,不需要和/dev/的设备文件名相同

功能:注册一个设备号范围
参数:

from:	起始设备号(主、次)
count:	连续的次设备号数量
name:	设备名,不需要和/dev/的设备文件名相同,是/proc/device文件的名字

返回值:	成功;返回0,失败:返回负数

动态设备号注册函数

int alloc_chrdev_region(dev_t *dev, //存放分配到的第一个设备(包含主次)
unsigned baseminor,   //要分配起始次设备号 
unsigned count,       // 连续的次设备号数量
const char *name) 	  // 设备名,不需要和/dev/的设备文件名相同

功能: 注册一个设备号范围
参数:

dev      :存放分配到的第一个设备(包含主次设备号)
baseminor	:要分配起始次设备号
count    	:连续的次设备号数量
name    	:设备名,不需要和/dev/的设备文件名相同

返回值	:成功:返回0,失败:返回负数

设备号注销函数(释放设备号函数)


void unregister_chrdev_region( dev_t from, //起始设备号(主、次)
                               unsigned int count)  //连续的次设备号数量

功能: 释放一个范围的设备号
参数

from :起始设备号(主、次) (包含主次设备号)
count:连续的次设备号数量

返回值:无

核心结构初始化函数

void cdev_init( struct cdev *cdev,         //需要初始化的核心结构指针
                const struct file_operations *fops)    //文件操作集合

功能:初始化核心结构,具体做的是清0 核心结构,初始化核心结构的list,kobj,ops成员
参数:

cdev	:需要初始化的核心结构指针
fops	:文件操作方法结构指针

返回值	:无

注意:说明:写这种种驱动模型时候,不需要在定义struct cdev结合变量初始化,因为

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值