Linux驱动(三):字符设备驱动之杂项

news/2024/9/19 0:39:55/ 标签: linux, microsoft, 运维, Linux驱动, RK3588s, 瑞芯微, 驱动开发

目录

  • 一、Linux设备分类
  • 二、设备号与字符设备的编码方式
    • 1.设备号
    • 2.字符设备的编码方式
  • 三、杂项字符设备驱动的初级编写


一、Linux设备分类

  Linux下一切皆文件,所有的硬件设备在Linux应用层中都会被抽象成文件,所有对硬件设备的操作到应用层中,也都会被抽象成文件的操作,设备文件通常会被放在/dev目录下。

类型作用
字符设备(Character Devices)字符(char)设备是个能够像字节流(类似文件)一样被访问的设备,由字符设备驱动程序来实现这种特性。字符设备驱动程序通常至少要实现open、close、read和write的系统调用。
块设备(Block Devices)和字符设备类似,块设备也是通过/dev目录下的文件系统节点来访问。块设备(例如磁盘)上能够容纳filesystem。在大多数的Unix系统中,进行I/O操作时块设备每次只能传输一个或多个完整的块,而每块包含512字节(或2的更高次幂字节的数据)。
网络设备(Network Devices)任何网络事物都需要经过一个网络接口形成,网络接口就是一个能够和其他主机交换数据的设备(网络设备)。接口通常是一个硬件设备,但也可能是个纯软件设备,比如回环(loopback)接口。

详解
1.字符设备
  字符设备是Linux设备类型中占比最多的设备,除了块设备和网络设备,其他设备基本都是字符设备,我们常常写的驱动代码,也往往是字符设备。之所以叫字符设备,是因为操作该设备时是通过字节一位一位(字符流)的去操作的。适用于实时数据流处理和设备交互。文件符号为c
  每一个字符设备在应用层的抽象文件也被叫做设备节点,在/dev下执行ls -l ,就可以看到很多创建好的设备节点。
在这里插入图片描述

– 代表普通文件
l 代表链接文件 ---- 快捷方式
c 代表字符设备
d 代表目录文件
b 代表块设备
p 代表管道
s 代表套接字

2.块设备
  与字符设备不同,块设备以固定大小的数据块进行数据传输。块设备通常用于存储设备,如硬盘、固态硬盘(SSD)、U盘等。适用于需要高效和灵活数据存取的应用场景。文件符号为b
3.网络设备
  网络设备用于连接和管理网络中的计算机和其他设备,网络设备的协同工作,确保网络的连接性、性能和安全性。Unix访问网络接口的方法仍然是给它们分配一个唯一的名字(比如eth0),但这个名字在filesystem中不存在对应的节点。内核和网络设备驱动程序间的通信,完全不同于内核和字符以及块驱动程序之间的通信,内核调用一套和数据包相关的函数socket,也叫套接字。
使用ifconfig命令,即可查看网络设备:
在这里插入图片描述

二、设备号与字符设备的编码方式

1.设备号

  在 Linux 系统中,设备号用于唯一标识设备文件,以便内核正确地访问硬件设备。设备号包括主设备号和次设备号,它们分别用于区分设备类型和具体设备实例。
示例
在这里插入图片描述
  简单来讲,设备号就是用来区分具体的硬件设备的。主设备号是先对硬件设备大致分个类,先确定该硬件设备具体属于哪一类,而次设备号就是用来再细分到具体哪一个设备。
主设备号固定是10,次设备号是0-255

2.字符设备的编码方式

在这里插入图片描述
  我们可以将操作系统大致分为三层,应用层、内核层以及硬件层。我们的所有界面操作都是应用层,所有的驱动代码都在内核层,所有具体的硬件在硬件层。应用层的所有操作,会先通过API接口反馈给驱动层,驱动代码运行后,最后才会反馈给具体的硬件进行需求实现。
  作为一个嵌入式软件工程师,我们所编写代码的顺序就是先写驱动后应用层。

编写字符设备驱动代码的方法大致有三种:
1.杂项字符设备驱动。用于处理与内核不直接相关的设备或功能的驱动程序,适用于各种简单或虚拟设备的实现,并为开发者提供了一种简便的方式来处理字符设备
2.Linux2.6 字符设备驱动 。 在 Linux 2.6 内核中编写字符设备驱动提供了一个强大且灵活的方式来与设备进行交互。虽然这种方法有许多优点,如清晰的接口和与文件系统的集成,但也存在一些缺点,如复杂性、性能开销和安全问题。
3.早期经典字符设备驱动。太老了,几乎被淘汰。

三、杂项字符设备驱动的初级编写

目标:通过编写代码实现初级open、close、read、write的驱动编写以及应用层的简单调用。

应用:
app.misc.c

#include <stdio.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
int main(int argc,char *argv[])
{int fd =0;char buffer[100];const char *data = "Hello, this is a test write!";if(argc<2){printf("请输入正确的参数\n");return -1;}fd = open(argv[1],O_RDWR);if(fd<0){perror("open");return -1;}write(fd, data, strlen(data));read(fd, buffer, sizeof(buffer) - 1);close(fd);return 0;
}

驱动:
misc_test.c

#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>int my_open (struct inode *inode, struct file *fp)
{printk("Open ok\n");return 0;
}int my_release (struct inode *inode, struct file *fp)
{printk("Release ok\n");return 0;
}
ssize_t my_read (struct file *fp, char __user *buf, size_t size, loff_t *off)
{printk("Read ok\n");return 0;
}
ssize_t my_write (struct file *fp, const char __user *buf, size_t size, loff_t *off)
{printk("Write ok\n");return 0;
}struct file_operations my_filop = {.owner = THIS_MODULE,.open = my_open,.release = my_release,.read = my_read,.write = my_write};struct miscdevice my_misc={.minor=255,.name="my_open",.fops = &my_filop
};static int __init my_open_init(void)
{int a=0;a = misc_register(&my_misc);if(a<0){printk("my_misc_register error\n");return -ENODEV;}printk("杂项字符设备注册成功\n");return 0;
}static void __exit my_open_exit(void)
{misc_deregister(&my_misc);printk("杂项字符设备注销成功\n");
}module_init(my_open_init);
module_exit(my_open_exit);
MODULE_LICENSE("GPL");

结果:
在这里插入图片描述



http://www.ppmy.cn/news/1519952.html

相关文章

1004.最大连续1的个数Ⅲ

1.题目描述 给定一个二进制数组 nums 和一个整数 k&#xff0c;如果可以翻转最多 k 个 0 &#xff0c;则返回 数组中连续 1 的最大个数 。 示例 1&#xff1a; 输入&#xff1a;nums [1,1,1,0,0,0,1,1,1,1,0], K 2 输出&#xff1a;6 解释&#xff1a;[1,1,1,0,0,1,1,1,1,1,1…

我不是非酋之-天空概率

最近入坑了dnf手游&#xff0c;染上了合天空&#xff0c;大黑蛋子一个&#xff0c;突发奇想&#xff0c;模拟下合天空概率&#xff0c;看看是否真的有20%。 梳理代码逻辑如下&#xff1a; 不考虑礼包和其他东西 条件&#xff1a; 合成概率20%&#xff0c;每次需要2个装扮和一个…

改进YOLO的群养猪行为识别算法研究及部署(小程序-网站平台-pyqt)

概述 群养猪的运动信息和行为信息与其健康状况息息相关&#xff0c;但人工巡视费时费力&#xff0c;本实验提出采用行为识别算法于群养猪的养殖管理中&#xff0c;识别群养猪drink&#xff08;饮水&#xff09;、stand&#xff08;站立&#xff09;和lie&#xff08;躺卧&#…

论tomcat线程池和spring封装的线程池

Tomcat 中的线程池是什么&#xff1f; 内部线程池&#xff1a;Tomcat 确实有一个内部的线程池&#xff0c;用于处理 HTTP 请求&#xff0c;通常是org.apache.tomcat.util.threads.ThreadPoolExecutor 类的实例。这个线程池专门用于处理进入的 HTTP 请求和发送响应。可以通过 T…

【C++】手动实现String类的封装(分文件编译)

实现了String类的大部分封装&#xff0c;采用分文件编译 //mystring.h #ifndef MYSTRING_H #define MYSTRING_H#include <iostream> #include <cstring> using namespace std;class myString { private:char *str; //定义一个字符串int size; //记录字符串…

线性代数 第五讲:线性方程组_齐次线性方程组_非齐次线性方程组_公共解同解方程组_详解

线性方程组 文章目录 线性方程组1.齐次线性方程组的求解1.1 核心要义1.2 基础解系与线性无关的解向量的个数1.3 计算使用举例 2. 非齐次线性方程的求解2.1 非齐次线性方程解的判定2.2 非齐次线性方程解的结构2.3 计算使用举例 3.公共解与同解3.1 两个方程组的公共解3.2 同解方程…

鸿蒙界面开发(五):相对布局

相对布局RelativeContainer 相对布局的容器&#xff0c;支持容器内部的子元素设置相对位置关系&#xff0c;适用于界面复杂场景的情况&#xff0c;对多个子组件进行对齐和排列。子元素支持指定兄弟或父元素作为锚点&#xff0c;基于锚点做相对位置布局。 锚点&#xff1a;通过…

RK3568 Android 11 蓝牙BluetoothA2dpSink 获取用于生成频谱的PCM

Android 中的 A2DP Sink A2DP Sink 在 Android 系统中主要用于 接收 其他蓝牙设备&#xff08;如手机、平板、电脑等&#xff09;发送过来的 高质量的立体声音频。简单来说&#xff0c;它让你的 Android 设备可以充当一个 蓝牙音箱 或 耳机 的角色。 核心功能&#xff1a; 接…

vue3 监听

watch &#xff08;1&#xff09;监听ref 状态的变化 const num ref(1) watch(num,(newValue,oldValue)>{console.log(newValue,oldValue);//2,1 }) setTimeout(()>{num.value },500)&#xff08;2&#xff09;computed const num ref(1); const double computed((…

惠中科技光伏清洗剂:绿色清洁,引领光伏行业新潮流

在当今全球能源转型的大潮中&#xff0c;光伏产业作为绿色能源的重要组成部分&#xff0c;正以前所未有的速度蓬勃发展。然而&#xff0c;随着光伏板在户外环境的长时间暴露&#xff0c;其表面不可避免地会积累灰尘、鸟粪、油污等污染物&#xff0c;严重影响光伏板的透光率和发…

Gorm--Scan

在 Gorm 中&#xff0c;Scan 是一个用于将查询结果映射到自定义结构体或变量的函数。与 Find 或 First 不同&#xff0c;Scan 允许你将查询结果存储到与数据库模型不完全匹配的结构体中。它特别适合用于自定义查询结果或联合查询的场景。 type Result struct {Name stringEma…

#单片机基础 笔记二

SPI中断 1.SPI总线协议 1.1协议介绍 SPI接口是Motorola &#xff08;motorola | Smartphones, Accessories & Smart Home Devices&#xff09;首先提出的全双工三线/四线同步串行外围接口采用主从模式&#xff08;Master Slave&#xff09;架构。 时钟由Master控制&#xf…

ELK学习笔记——如何给Kibana新增用户和角色

Kibana新增用户和角色 首先用超管账号登录上Kibana&#xff0c;按照下面步骤操作 1、创建角色 按图操作 2、创建用户 按图操作 3、给用户分配角色 至此&#xff0c;角色和用户绑定成功&#xff1b; 最后&#xff0c;可以退出管理员账号&#xff0c;登录这个新…

github私有仓库通过action部署hexo到公开仓库

github私有仓库通过action部署hexo到公开仓库 有一段时间一直将博客md文件直接放到公开仓库然后通过工作流action创建一个gh-page分支&#xff0c;来实现部署 但是这样做有一个问题&#xff0c;如果你的源文件&#xff0c;或者配置文件中有涉及变量&#xff0c;或者密钥key&a…

Linux-vim

文章目录 vi和vimvim的基本概念vim的基本操作vim正常模式命令集插入模式从插入模式切换为命令模式移动光标删除文字复制替换撤销上一次操作更改跳至指定的行 vim末行模式命令集列出行号跳到文件中的某一行查找字符保存文件推出vim vi和vim vi/vim的区别简单点来说&#xff0c;…

Linux C 内核编程 /proc 编程例子

直接上代码 proc_demo.c内核版本&#xff1a; 5.4.0-150-generic #include <linux/module.h> #include <linux/sched.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> #include <linux/uaccess.h> #include <linux/slab.h>s…

threading.local的使用

python中的threading.local对象 在Python中&#xff0c;使用threading.local对象的意义在于为每个线程提供了一种安全地存储和访问线程局部变量的方式。这种机制对于多线程编程特别有用&#xff0c;因为它可以帮助开发者避免一些常见的多线程编程问题&#xff0c;如数据竞争、…

技术周刊 | Rspack 1.0、v0 支持 Vue、2024 年度编程语言排行榜、Ideogram 2.0、从 0 实现一个 React

大家好&#xff0c;我是童欧巴&#xff0c;欢迎来到第 126 期技术周刊。 资讯 Rspack 1.0 Rspack 1.0 正式发布&#xff0c;作为一款基于 Rust 的高性能 JavaScript 打包工具&#xff0c;它兼容 webpack API 和生态&#xff0c;提供了显著提升的构建性能。1.0 版本在性能、兼…

第三章:实时流数据处理与分析

目录 3.1 流处理框架深入解析与实战 Flink与Kafka Streams的性能对比&#xff1a;事件驱动架构的代码实现 1. Apache Flink&#xff1a;流处理的“性能怪兽” 2. Kafka Streams&#xff1a;轻量级、低延迟的流式处理框架 实时异常检测与报警系统&#xff1a;结合Flink CEP…

【Transformer】基本概述

文章目录 提出背景核心思想—注意力机制流程解析参考资料 提出背景 在Transformer模型出现之前&#xff0c;循环神经网络&#xff08;RNN&#xff09;及其变体&#xff0c;如长短期记忆网络&#xff08;LSTM&#xff09;和门控循环单元&#xff08;GRU&#xff09;&#xff0c;…