(Linux驱动入门)字符设备

news2025/2/21 23:05:00

一、设备相关概念

1.1 设备号

内核中通过类型dev_t来描述设备号,其实质是unsigned int 32位整数,其中高12位为主设备号低20位为次设备号设备号也是一种资源,当我们需要时可以调用函数去申请。

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

这是Linux内核中注册字符设备驱动的函数之一,它的作用是在内核中申请一段设备号,并将其与设备驱动程序进行绑定。具体来说,它的参数含义如下:

  • from:设备号的起始值,通常为0。
  • count:需要注册的设备号数量。
  • name:设备名称,用于在 /proc/devices 文件中显示设备的名字。

函数执行成功时,会返回0,否则返回一个负数错误码。

1.2 设备信息的描述

#include <linux/cdev.h>

struct cdev {
    struct kobject kobj;           // 对象,用于实现 sysfs 文件系统接口
    struct module *owner;         // 指向模块对象的指针,用于记录模块的引用计数
    const struct file_operations *ops;  // 指向字符设备驱动程序提供的操作函数集合的指针
    struct list_head list;        // 用于链接同一设备号下的所有设备结构体的链表
    dev_t dev;                    // 设备的主、次设备号
    unsigned int count;           // 要注册的设备号的数量
};

1.3 设备行为的描述

#include <linux/fs.h>

struct file_operations {
    struct module *owner;   // 指向模块对象的指针,用于记录模块的引用计数
    loff_t (*llseek) (struct file *, loff_t, int);  // 实现文件偏移量设置函数
    ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);  // 实现读操作函数
    ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);  // 实现写操作函数
    int (*open) (struct inode *, struct file *);  // 实现设备打开函数
    int (*release) (struct inode *, struct file *);  // 实现设备关闭函数
    long (*unlocked_ioctl) (struct file *, unsigned int, unsigned long);  // 实现设备控制函数
    int (*mmap) (struct file *, struct vm_area_struct *);  // 实现设备内存映射函数
    int (*flush) (struct file *, fl_owner_t id);  // 实现设备缓冲刷新函数
    int (*fsync) (struct file *, loff_t, loff_t, int datasync);  // 实现设备同步函数
};

struct file_operations 中的函数指针成员包括:

  • llseek:实现文件偏移量设置函数。
  • read:实现读操作函数。
  • write:实现写操作函数。
  • open:实现设备打开函数。
  • release:实现设备关闭函数。
  • unlocked_ioctl:实现设备控制函数。
  • mmap:实现设备内存映射函数。
  • flush:实现设备缓冲刷新函数。
  • fsync:实现设备同步函数。

这些函数指针中的大部分都是可选的,根据实际需求进行选择实现。

二、驱动的使用

insmod和rmmod是Linux系统中用于安装和卸载内核模块的命令,而mknod是用于创建设备节点的命令。

2.1 insmod

  1. 使用gcc编译内核模块源代码,生成.ko文件。

  2. 在终端中输入insmod  **.ko 命令,加载.ko文件。

  3. 内核检查模块符号表,如果符号表正确,则会调用模块中的init函数进行初始化。

  4. init函数会进行设备的初始化,包括申请设备号、创建字符设备结构体、初始化设备、注册设备等。

  5. 通过调用cdev_add函数将字符设备添加到系统中。

  6. 创建设备节点,以便应用程序可以使用设备。

2.2 rmmod

  1. 在终端中输入rmmod  **.ko 命令,卸载模块。

  2. 内核会调用模块中的exit函数,对设备进行资源的释放,如注销字符设备、释放设备号等。

  3. 调用cdev_del函数将字符设备从系统中删除。

  4. 删除设备节点,以便应用程序无法使用设备。

2.3 mknod

//mknod [选项] <文件名> <文件类型> <主设备号> <次设备号>
  mknod /dev/testchar       c        232        0
  1. 在终端中输入mknod命令,创建设备节点。

  2. 使用mknod函数创建设备节点,需要指定设备的名称、设备类型、主设备号、次设备号等参数。

  3. 创建成功后,应用程序可以通过打开设备节点访问设备。

2.4 流程图

来源:05-字符设备驱动(三):驱动的测试以及驱动的Makefile_哔哩哔哩_bilibili

2.5 Makfile文件

ifneq ($(KERNELRELEASE),)   如果KERNELRELEASE变量已定义,即当前为内核构建过程,执行以下代码
obj-m := charDev.o   编译模块charDev为目标文件obj文件,即生成charDev.o
else 
PWD := $(shell pwd)   定义变量PWD为当前目录的绝对路径
KDIR:=  / lib/ modules/ 'uname -r' / build  定义变量KDIR为内核源码目录路径
all:   
          make -c$(KDIR)][M=$(PWD)   在内核源码目录下执行make,参数为M=$(PWD),表示生成的目标文件存放在当前目录
clean:  
          rm -rf *.o *.ko *.mod.c *.symvers .c~s~ 
 删除编译生成的目标文件
endif 

三、通过驱动ioctl 点灯

ioctl函数用于在用户态和内核态之间传递控制命令,通常用于设备驱动中实现设备的特定操作,也可以用于进程间通信和内核调试等场景。

int ioctl(int fd, unsigned long request, ...);

fd表示要进行控制命令的文件描述符;request表示控制命令的编号,需要设备驱动实现者自己定义,通常使用宏定义的方式定义在头文件中;最后一个可选参数则是控制命令需要的参数,如果没有参数则传递NULL

可通过访问 cat /proc/ioports 来获取设备当前的IO端口号

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/438237.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

光伏发电数据监控的运维平台

摘要&#xff1a;全球化经济社会的快速发展,加快了传统能源的消耗,导致能源日益短缺,与此同时还带来了严重的环境污染。因此,利用没有环境污染的太阳能进行光伏发电获得了社会的普遍关注。本文根据传统式光伏电站行业的发展背景及其监控系统的技术设备,给出了现代化光伏电站数据…

Vue3通透教程【十二】TS类型声明优势

文章目录 &#x1f31f; 写在前面&#x1f31f; 上篇文章解惑&#x1f31f; JS函数中的隐患&#x1f31f; 函数中的类型&#x1f31f; 写在最后 &#x1f31f; 写在前面 专栏介绍&#xff1a; 凉哥作为 Vue 的忠实 粉丝输出过大量的 Vue 文章&#xff0c;应粉丝要求开始更新 V…

计算机视觉 | 八斗人工智能 (中)

目录 卷积&滤波1.一个没有任何效果的卷积核2.平均均值滤波3.图像锐化4.soble边缘检测 卷积的三种填充模式1.padding --> same模式 最常用的模式2.full和valid模式三通道卷积 canny边缘检测算法&#xff08;效果最好&#xff09;Sobel算子、Prewitt算子 相机模型畸变矫正…

新能源汽车和数字化转型

工业时代的代表产品是交通运输设备&#xff0c;核心桂冠是发动机。信息时代的代表产品是智能手机&#xff0c;核心桂冠是芯片。 汽车是个很有代表性产品&#xff0c;因为它既属于复杂高精密金属机械设备&#xff0c;又属于大规模使用的大件消费品。所以这100年来&#xff0c;汽…

代码随想录算法训练营第三十二天|122.买卖股票的最佳时机II 、55. 跳跃游戏 、45.跳跃游戏II

文章目录 122.买卖股票的最佳时机II55. 跳跃游戏45.跳跃游戏II:star: 122.买卖股票的最佳时机II 遇到每天正利润就收集&#xff0c;负利润就不收集 链接:代码随想录 解题思路&#xff1a; ①因为可以多次买卖&#xff0c;所以考虑到最终把最终利润进行分解 如假如第0天买入&am…

垃圾收集算法面试总结

垃圾收集算法 标记 - 清除算法 首先标记出所有需要被回收的对象&#xff0c;标记完后统一回收所有被标记的对象。 后续的收集算法都是基于这种思路并对其不足进行改进而得到的。 这种方法主要有两个缺点&#xff1a; 一个是效率问题&#xff0c;标记和清除两个过程的效率都…

java mysql超市会员积分带抽奖系统

后台相关操作&#xff1a; &#xff08;1&#xff09;系统管理&#xff1a;管理系统的管理员用户。 &#xff08;2&#xff09;会员管理&#xff1a;对会员信息进行增删改功能。 &#xff08;3&#xff09;商品管理&#xff1a;对系统的商品进行增删改查功能等维护。 &#xff…

分治法解二维的最近对问题,算法分析与代码实现,蛮力法与分治法解决二维的最近对问题的区别

&#x1f38a;【数据结构与算法】专题正在持续更新中&#xff0c;各种数据结构的创建原理与运用✨&#xff0c;经典算法的解析✨都在这儿&#xff0c;欢迎大家前往订阅本专题&#xff0c;获取更多详细信息哦&#x1f38f;&#x1f38f;&#x1f38f; &#x1fa94;本系列专栏 -…

人工智能发展到GPT4经历了什么,从专家系统到机器学习再到深度学习,从大模型到现在的GPT4

大家好&#xff0c;我是微学AI&#xff0c;今天给大家讲一下人工智能的发展&#xff0c;从专家系统到机器学习再到深度学习&#xff0c;从大模型到现在的GPT4&#xff0c;讲这个的目的是让每个人都懂得人工智能&#xff0c;每个人都懂得人工智能的发展&#xff0c;未来人工智能…

“智慧赋能 强链塑链”—— 煤炭行业数字化转型探讨

煤炭作为传统能源行业之一&#xff0c;是国民经济中不可或缺的一部分&#xff0c;随着国家能源结构的战略转型&#xff0c;煤炭企业的长期盈利能力将面临巨大的挑战。供应链作为煤炭行业生产运营的基础保障&#xff0c;在企业开源节流的要求下&#xff0c;其传统粗放的供应链管…

Xcode 14.3 cocoapod 1.12.0 打包报错解决

前言 前几天升级Xcode到14.3版本&#xff0c;运行项目报错&#xff0c;于是记录下来。 开发环境 macOS: 13.3.1 Xcode: 14.3 CocoaPods: 1.12.0 问题描述 [Xcode菜单栏] -> [Product] -> [Archive]&#xff0c;进行打包操作。执行到 Run custom shell script [CP]…

day16 信号灯

信号灯概念和有名信号灯 目录 信号灯概念和有名信号灯 有名信号灯 无名信号灯 信号灯P操作 信号灯V操作 system V信号灯的 信号灯/信号量&#xff08;semaphore&#xff09; 信号量代表某一类资源&#xff0c;其值表示系统中该资源的数量&#xff1b; 信号量是一个受保…

【C语言】程序运行环境及预处理指令

文章目录 程序的翻译环境&#xff1a;程序的运行环境&#xff1a;C语言预定义符号#define定义标识符#define定义宏具有副作用的宏参数 #与###的使用##的使用 宏和函数对比#undef命令行定义条件编译常见的条件编译指令&#x1f31e; 文件包含指令嵌套文件包含 其他预处理指令 撒…

【C++】对数组指针的理解,例如 int (*p)[3]

目录 简介思考理解结语 简介 Hello&#xff01; 非常感谢您阅读海轰的文章&#xff0c;倘若文中有错误的地方&#xff0c;欢迎您指出&#xff5e; ଘ(੭ˊᵕˋ)੭ 昵称&#xff1a;海轰 标签&#xff1a;程序猿&#xff5c;C选手&#xff5c;学生 简介&#xff1a;因C语言结识…

Win7 无法安装 VMware Tools 解决方法

文章目录 1.下载kb4474419补丁2.虚拟机 > 设置 > 软盘&#xff0c;选中“使用物理驱动器”3.解决IE浏览器只能访问百度4.下载windows iso的正确方式 win7版本&#xff1a;cn_windows_7_ultimate_with_sp1_x64_dvd_u_677408_2&#xff08;iso大小3.18 GB&#xff09; vmwa…

C++内联函数(编译器角度,汇编角度),auto关键字,范围for语法糖,nullprt与NULL区别等

TIPS 在C当中有一个东西可以打印类型&#xff1f;typeid(变量名).name()数组一旦从参数进入到函数里面&#xff0c;它就已经是个指针了&#xff0c;再也不是一整个数组了 内联函数&#xff08;正常函数定义前加个inline修饰&#xff09; 在实际当中&#xff0c;有时候去调用…

13、拦截器

文章目录 1、HandlerInterceptor 接口2、配置拦截器3、拦截器原理 【尚硅谷】SpringBoot2零基础入门教程-讲师&#xff1a;雷丰阳 笔记 路还在继续&#xff0c;梦还在期许 1、HandlerInterceptor 接口 /*** 登录检查* 1、配置好拦截器要拦截哪些请求* 2、把这些配置放在容器中…

爬虫——肯德基

import requests #UA伪装&#xff1a;将对应的User-Agent封装到一个字典中 headers{User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/112.0.0.0 Safari/537.36 Edg/112.0.1722.48 } #指定url url http://www.kfc.com.c…

【jvm系列-09】垃圾回收底层原理和算法以及JProfiler的基本使用

JVM系列整体栏目 内容链接地址【一】初识虚拟机与java虚拟机https://blog.csdn.net/zhenghuishengq/article/details/129544460【二】jvm的类加载子系统以及jclasslib的基本使用https://blog.csdn.net/zhenghuishengq/article/details/129610963【三】运行时私有区域之虚拟机栈…

一图看懂 xlrd 模块:读写 Excel 文件的数据和格式信息, 资料整理+笔记(大全)

本文由 大侠(AhcaoZhu)原创&#xff0c;转载请声明。 链接: https://blog.csdn.net/Ahcao2008 一图看懂 xlrd 模块&#xff1a;读写 Excel 文件的数据和格式信息, 资料整理笔记&#xff08;大全&#xff09; 摘要模块图类关系图模块全展开【xlrd】统计常量intdict 模块26 os27 …