Linux中很多设备都是字符设备,使用ls -l查看/dev下的设备,前面带c的都是字符设备。

字符设备的创建比较容易,而且有一套固定的模式,掌握了模式完全可以“套模板”。更多的精力应该花在业务逻辑的部分。

Linux的每个设备都有一个主设备号和次设备号,创建字符设备第一步就是给它分配设备号。如果是自己用,可以任意给定一个没有用过的设备号,也可以让系统自动分配。但是如果要发布给不同的人不同的机器使用,就不能随便。推荐使用系统自动分配的方式。

下面代码中根据有没有给定设备号决定是指定还是自动分配设备号,dev变量里包含了主设备号和次设备号。MKDEV就是将两个数字合成的。register_chrdev_region()函数注册字符设备,alloc_chrdev_region()函数自动分配设备号。主设备号是关键,次设备号可以看成是该类设备的计数。通过MAJOR()可以得到主设备号。

字符设备一般会创建一个数据结构,里边包含了cdev结构、设备数据和其他数据,可以根据自己实际需求添加。然后创建该结构的指针。

分配完设备号,接下来给字符设备数据结构分配存储空间。

创建设备类

初始化字符设备、添加字符设备到内核和创建设备。

这里涉及到一个结构file_operations,这个结构里包含了文件操作函数列表,所有操作这个字符设备的动作函数地址都保存在这个结构里。

结构的定义在头文件fs.h中,这个结构有很多内容,不过常用的就那么几个。

如果没遇到问题,到这里字符设备就创建成功了。如果失败,就会goto到错误处理的地方,这里用goto是因为失败后要把前面可能申请的资源释放掉,而且有顺序,这里一定要注意。

在exit函数中要有对应的注销或释放资源的操作,顺序跟创建时相反,后创建的先释放,先创建的后释放。

下面要完成的工作就是实现file_operations结构中的函数。对于简单的字符设备,最常见的操作是open、read、write、ioctl、release等。

open函数这里只是简单的获取了一下字符数据结构体的指针。container_of函数很有意思,可以根据结构成员的地址找到结构体数据的地址。

read函数要实现将内核空间的数据传到用户空间的功能,copy_to_user()函数就是干这个的,第一个和第三个参数就是read函数的形参,中间是内核的数据。这里的count是字节个数。

write函数实现的功能与read相反,使用copy_from_user()和memdup_user()函数可以实现。ioctl函数实现一些设备独有操作的函数,i2c设备和spi设备就大量使用了ioctl。

release函数就是在设备文件关闭时需要做的操作。这里的关闭是指打开该文件的文件描述符个数为0了,如果不为0只会将计数减1而不会真正调用release函数。

具体的实例可以参看Linux源码中i2c-dev.c中i2c设备驱动的实现。

必要的头文件:

编译模块并插入到内核后,在/dev目录下会创建对应的设备文件。

在/sys/class下会创建对应的设备类目录。

ok,以上就是简单的创建字符设备的过程,通过字符设备可以实现内核与用户空间的数据交换。学习字符设备的创建也是学习linux驱动开发的第一步。

(编译的方法在另一篇专栏《Linux的gpio中断》中有提到)

限于个人水平,肯定有遗漏和错误,欢迎大家批评指正。

linux major头文件_Linux的字符设备相关推荐

  1. linux major头文件_《Linux设备驱动程序》(四)——字符设备驱动(上)

    之前我们说过,Linux设备主要分为三类:字符设备.块设备和网络接口. 字符设备相对于另外两个设备更加容易理解,同时,这类设备也适合大多数简单的硬件设备,因此,接下来我们学习一下字符设备驱动. 字符驱 ...

  2. linux一切皆文件之tty字符设备(深入理解sshd创建pty的过程) (五)

    一.知识准备 1.在linux中,一切皆为文件,所有不同种类的类型都被抽象成文件(比如:块设备,socket套接字,pipe队列) 2.操作这些不同的类型就像操作文件一样,比如增删改查等 3.块设备支 ...

  3. linux open 头文件_linux下通过共享内存和mmap实现进程间通讯

    前言 最近在学习GNU/Linux内核,看到mmap的时候书上说: mmap/munmap接口函数是用户最常用的两个系统调用接口,无论是在用户程序中分配内存.读写大文件.链接动态库文件,还是多进程间共 ...

  4. linux下mkdir头文件_Linux部分常用命令学习记录

    Linux部分常用命令 ls 显示目标列表 ls -a 显示所有档案及目录(ls内定将档案名或目录名称为"."的视为影藏,不会列出): ls -l 以长格式显示目录下的内容列表.输 ...

  5. linux内核led驱动开发,从Linux内核LED驱动来理解字符设备驱动开发流程

    目录 博客说明 开发环境 1. Linux字符设备驱动的组成 1.1 字符设备驱动模块加载与卸载函数 1.2 字符设备驱动的file_operations 结构体中的成员函数 2. 字符设备驱动--设 ...

  6. linux c之c语言符合标准的头文件和linux常用头文件

    1.C语言符合标准的头文件 #include <assert.h> //设定插入点 #include <ctype.h> //字符处理 #include <errno.h ...

  7. linux语言的说明顺序有哪些,(linux常用头文件详解.doc

    (linux常用头文件详解 linux常用头文件详解 POSIX标准定义的头文件??????? 目录项 ???????? 文件控制 ??? 文件名匹配类型 ??? 路径名模式匹配类型 ??????? ...

  8. linux 常用头文件,(常用头文件详解.doc

    (常用头文件详解 linux常用头文件详解 POSIX标准定义的头文件??????? 目录项 ???????? 文件控制 ??? 文件名匹配类型 ??? 路径名模式匹配类型 ??????? 组文件 ? ...

  9. Linux C try 头文件,linux c 头文件

    //1.Linux中一些头文件的作用: #include //ANSI C.提供断言,assert(表达式) #include //GCC.GTK,GNOME的基础库,提供很多有用的函数,如有数据结构 ...

最新文章

  1. TorchScript神经网络集成技术
  2. 《zw版·Halcon-delphi系列原创教程》 Halcon分类函数011,ocr,字符识别
  3. 易语言webservice接口_易语言语音通知webservice接口
  4. oracle 查阻塞日志,通过Oracle补充日志,找到锁阻塞源头的SQL
  5. 工作297:shift+$形成元
  6. delphi 更改DBGrid 颜色技巧
  7. 生活在信息世界,人人都该懂得大数据概念
  8. 桌面云的四大协议解析
  9. 外部PLC触发VisionMaster多流程运行PLC部分特殊说明
  10. sha1 file ‘<stdout>‘ write error: Broken pipe
  11. c语言求函数的极限例题,第二讲--函数的极限典型例题.doc
  12. 数组去重几种常见的方法
  13. docker内存及cpu限制
  14. 创建数据库的相关命令与字符类型
  15. (附源码)计算机毕业设计SSM基于框架的点餐系统
  16. SwitchHosts——便捷切换hosts
  17. 信安软考 第十八章 网络安全测评技术与标准
  18. Error querying database. Cause: java.sql.SQLException:
  19. 西门子S7-1200PLC控制3轴伺服程序
  20. 二叉树的深度(递归+非递归)

热门文章

  1. 理解 Redux 的最好方式,是自己写一个
  2. springmvc项目,浏览器报404错误的问题
  3. React-Native入门(2)-简单阐述跳转
  4. CREELINKS平台_处理器CeAd资源使用说明(CeAd的配置与使用)
  5. RFID技术正助力物流行业进入新时代
  6. Cordova webapp实战开发:(2)认识一下Cordova
  7. MySQL错误:The user specified as a definer (XXX@XXX) does not exist
  8. 别踩白块儿游戏源代码分析和下载(二)
  9. 我的Android进阶之旅------Android检测wifi连接状态
  10. ubuntu 安装 oracle-xe-universal