通过上一节Linux设备驱动字符设备(一)了解了Linux设备驱动的分类,设备号的构成,设备号的申请以及设备号的释放。

在Linux内核中使用struct cdev结构来代码字符设备。

<include/linux/cdev.h>
--------------------------------------------------
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结构中成员,在以后会详细说明其作用。

struct kobject kobj
内核的内嵌对象,是Linux设备驱动模型的重要成员。
struct module *owner
字符设备驱动程序所在的内核模块指针
struct file_operations *ops
字符设备驱动程序文件操作函数集,是应用程序通过文件系统访问驱动的桥梁。
struct list_head
用来将系统中字符设备形成的链表
dev_t dev
字符设备的设备号,由主次设备号组成
unsigned int count
次设备号的个数,用于表示驱动程序管理的同类设备的个数。

字符设备的分配

字符设备的分配也就是struct cdev的分配,内核一般有两组方式。

  • 静态分配
static struct cdev chr_dev;
  • 动态分配
    内核提供一个函数,专门用来动态分配cdev结构
<fs/char_dev.c>
----------------------------------------------------
/*** cdev_alloc() - allocate a cdev structure** Allocates and returns a cdev structure, or NULL on failure.*/
struct cdev *cdev_alloc(void)
{struct cdev *p = kzalloc(sizeof(struct cdev), GFP_KERNEL);if (p) {INIT_LIST_HEAD(&p->list);kobject_init(&p->kobj, &ktype_cdev_dynamic);}return p;
}

可以看到是通过kzalloc分配一个struct cdev结构,并将此结构返回。

字符设备的初始化

既然分配一个struct cdev, 紧接着需要初始化struct cdev结构。内核同时也提供一个专门用来初始化struct cdev的函数cdev_init。

<fs/char_dev.c>
-----------------------------------------------------------
/*** cdev_init() - initialize a cdev structure* @cdev: the structure to initialize* @fops: the file_operations for this device** Initializes @cdev, remembering @fops, making it ready to add to the* system with cdev_add().*/
void cdev_init(struct cdev *cdev, const struct file_operations *fops)
{memset(cdev, 0, sizeof *cdev);INIT_LIST_HEAD(&cdev->list);kobject_init(&cdev->kobj, &ktype_cdev_default);cdev->ops = fops;
}

可以看到调用cdev_init,驱动程序需要传入file_operations结构的。

字符设备的注册

在前面知道了如何分配字符设备,以及初始化。接下来的任务就是将字符设备注册到系统中去。内核提供了cdev_add函数,用来将一个字符设备加入到系统中。

<fs/char_dev.c>
---------------------------------------------------------------------
/*** cdev_add() - add a char device to the system* @p: the cdev structure for the device* @dev: the first device number for which this device is responsible* @count: the number of consecutive minor numbers corresponding to this*         device** cdev_add() adds the device represented by @p to the system, making it* live immediately.  A negative error code is returned on failure.*/
int cdev_add(struct cdev *p, dev_t dev, unsigned count)
{int error;p->dev = dev;p->count = count;error = kobj_map(cdev_map, dev, count, NULL,exact_match, exact_lock, p);if (error)
        return error;kobject_get(p->kobj.parent);
return 0;
}

此函数就是将一个字符设备加入到系统中去。第一个参数p代表加入到系统的字符设备的指针,第二个参数dev代表该设备的设备号,第三个参数count代表次设备的个数。

函数主要的部分kobj_map实现了如何将一个字符设备加入到系统的。该部分在后面Linux字符设备框架一节会详细分析,目前只要明白主要流程即可。

字符设备的注销

当驱动程序需要从系统卸载的时候,就需要使用cdev_del释放字符设备占用的内存。

<fs/char_dev.c>
----------------------------------------------------------
/*** cdev_del() - remove a cdev from the system* @p: the cdev structure to be removed** cdev_del() removes @p from the system, possibly freeing the structure* itself.*/
void cdev_del(struct cdev *p)
{cdev_unmap(p->dev, p->count);kobject_put(&p->kobj);
}

此函数就是从卸载一个字符设备,参数p代表的是字符设备的指针。

目前为止,已经了解了设备号,设备号的构成,字符设备分配,字符设备的初始化,字符设备的注册以及字符设备的注销。将在下一节通过一个简单的字符设备驱动程序来再次熟悉整个流程,然后总结字符设备驱动的编写模型。

Linux设备驱动之字符设备(二)相关推荐

  1. linux的驱动开发——字符设备驱动

    1.字符设备驱动 \qquad字符设备驱动是最基本,最常用的设备.它将千差万别的硬件设备采用统一的接口封装起来,屏蔽了硬件的差异,简化了应用层的操作. 2.描述所有字符设备的结构体 \qquad描述所 ...

  2. 设备驱动,字符设备驱动、(总线)设备驱动模型、sysfs文件系统、平台设备驱动

    以下内容转载于微信公众号:嵌入式企鹅圈.如有侵权,请告知删除. 学习Linux设备驱动开发的过程中自然会遇到字符设备驱动.平台设备驱动.设备驱动模型和sysfs等相关概念和技术. 对于初学者来说会非常 ...

  3. linux PCI驱动调用字符设备驱动方式

    上一篇文章写了字符设备驱动的基本结构及访问方式,在实际应用时首先需要绑定自己的硬件设备.本篇主要描述字符设备驱动与PCI接口类型的设备访问方式(内核为2.6.24及以上的方法,测试内核为2.6.32) ...

  4. 深入浅出:Linux设备驱动之字符设备驱动

    一.linux系统将设备分为3类:字符设备.块设备.网络设备.使用驱动程序: 字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后数据.字符设备是面向流 ...

  5. 蜕变成蝶~Linux设备驱动之字符设备驱动

    一.linux系统将设备分为3类:字符设备.块设备.网络设备.使用驱动程序: 字符设备:是指只能一个字节一个字节读写的设备,不能随机读取设备内存中的某一数据,读取数据需要按照先后数据.字符设备是面向流 ...

  6. 嵌入式linux驱动之———字符设备驱动(一)

    一.简介: 在Linux内核驱动中,字符设备是最基本的设备驱动.字符设备是能够像字节流(比如文件)一样被访问的设备,就是说对它的读写是以子为单位的.比如串口在进行收发数据时就是一个字节一个字节进行的. ...

  7. Linux驱动之字符设备驱动

    系列文章目录 第一章 Linux入门之驱动框架 第二章 Linux驱动之字符设备驱动 文章目录 系列文章目录 前言 一.认识字符设备驱动 1.基本概念 2.基本概念 二.字符设备旧框架 1.注册和注销 ...

  8. 字符设备驱动、平台设备驱动、设备驱动模型、sysfs的比较和关联

    参考原文:https://www.kancloud.cn/yueqian_scut/emlinux/106829 对原文笔误地方做了修改.重新排版 目录 字符设备驱动.平台设备驱动.设备驱动模型.sy ...

  9. STM32MP157驱动开发——字符设备驱动

    一.简介 字符设备是 Linux 驱动中最基本的一类设备驱动,字符设备就是一个一个字节,按照字节 流进行读写操作的设备,读写数据是分先后顺序的.比如我们最常见的点灯.按键. IIC. SPI, LCD ...

  10. 驱动学习----字符设备驱动框架

    字符设备驱动框架 1.字符设备驱动简介 2.file_operations 3.驱动模块的加载和卸载 4.字符设备的注册与注销 5.实现设备具体操作函数 6.添加LICENSE和作者信息 7.linu ...

最新文章

  1. python菜鸟基础教程-Python3 面向对象
  2. linux课程教学设计,《LINUX操作系统》课程整体教学设计.doc
  3. Angular+Flask搭建一个记录工具
  4. springer journal recommendation tool
  5. PHP7 serialize_precision 配置不当导致 json_encode() 浮点小数溢出错误
  6. 51Nod 1322 - 关于树的函数(树DP)
  7. android glide本地图片,Glide下载图片并保存到本地
  8. C++类对象成员、动态对象、new、delete运算符申请动态空间(C++初学面向对象)
  9. ABP理论学习之Abp Session
  10. bzoj2588: Spoj 10628. Count on a tree 主席树
  11. 《云周刊》69期:开门红利!阿里云2月活动来袭
  12. 【数字逻辑设计】电路原理图
  13. 【radon】图像的radon变换matlab仿真
  14. Bandicam一款值得被吹爆的录屏软件
  15. requests爬取英雄联盟皮肤图片
  16. ZYNQ PS部分简介
  17. 新手必看的模具设计十大分模法,干货满满!!!
  18. Python办公自动化 5.1 Python操作ppt:win32com 使用教程 操作复制ppt PowerPoint
  19. Nginx全站开启HTTPS
  20. lol国服服务器最新人口排名,2020lol大区人数排名,lol服务器人数

热门文章

  1. 解决时间控件input不能选择的问题
  2. 如何用adb链接手机,并异常情况下的处理(转)
  3. 支持语言locale
  4. 区分.net、c#、asp.net三者间的关系
  5. python初识(2)
  6. factory工厂模式之工厂方法FactoryMethod
  7. jQuery左侧图片右侧文字滑动切换代码
  8. 文本框 只输入数字键和删除键
  9. [转] 面向对象软件开发和过程(四)重用
  10. android后台倒计时,android倒计时封装(活动进入后台,倒计时依然能正常计时)...