模块编写1 | 学习笔记

简介: 快速学习模块编写1

开发者学堂课程【物联网开发-Linux 驱动开发实操演练:模块编写1】学习笔记,与课程紧密联系,让用户快速学习知识。

课程地址https://developer.aliyun.com/learning/course/657/detail/10869


模块编写1


内容介绍

一、设备分类

二、字符设备驱动

三、模块编写


一、设备分类

1.引入

在上节课我们学习了驱动的基本概念,清楚了驱动的基本概念之后,进行对驱动设备分类的了解。

驱动就是驱动设备,所以在学习以前首先应该了解设备分为哪几类。以下是 linux将驱动设备分成的三个大类,其中每个设备应该所具有的设备驱动,形成三大类设备驱动对应三大类设备:

1)字符设备    ---->>字符设备驱动

2)网络设备    ----->>网络设备驱动

3)块设备      ----->>块设备驱动

在上节课的分析中,可以知道设备驱动是由内核设备统一管理来控制的,因此在写相应的驱动时,要遵循内核提供的框架来写。

2. linux驱动相关概念

驱动的种类:

(1)字符设备

① I/0传输过程中以字符为单位进行传输。

② 用户对字符设备发出读/写请求时,实际的硬件读/写操作一般紧  

接着发生。

(表示字符设备的读写时同步的)

(2)块设备指的是存储设备,如:硬盘,u盘等存储设备,特点如下:

块设备与字符相反,它的数据传输以块(内存缓冲)为单位传输,块指的是存储单位,一般为4k。

用户对块设备读/写时,硬件上的读/写操作不会紧接着发生,即用户请求和硬件操作是异步的。

磁盘类、闪存类等设备都封装成块设备。

(3)网络设备

网络设备时一类特殊的设备,它不像字符设备或块设备那样通过对应的设备文件访问,也不能直接通过 read 或 write 进行数据请求,而是通过 socket 接口函数进行访问。

简言之网络设备就是一个网卡的设备,所以我们需要对应给其写出网卡的设备。

(4)设备文件:

在 linux 中有一句话叫做“一切皆文件”,即我们在对具体的硬件文件进行操作的时候也可以通过文件进行操作,也就是说设备文件对应的就是一个设备,而对设备进行操作其实操作的就是对每个设备文件进行操作。

而设备文件具体怎么创建以及和驱动的关系是什么,以及怎么通过应用层去操作文件而间接的操作到我们设备,放在之后的章节中讲述。而在此传达的意思就是,所有的设备驱动都对应了一个设备驱动文件,如字符设备驱动对应一个字符设备驱动文件。 

注意:网络涉笔驱动没有设备文件。

① 字符设备    ---->>字符设备驱动  ---->>字符设备文件

② 网络设备    ----->>网络设备驱动

③ 块设备      ----->>块设备驱动   ---->>块设备文件


二、字符设备驱动

之后开始学习各个设备驱动的使用方法。因为 linux 操作系统内核是由 c 语言编写的,而驱动时基于内核来编写的,所以驱动也是使用的 c 语言,而 c 语言时一门编译性语言,所以需要对编写的.c 文件进行编译。

所以还要学习如何编译 c 语言代码,虽然与之前的编译应用层代码使用的是同一个编译器,但方法还是有所不同。直至拿到编译后的驱动,就应该学习怎么使用驱动。

1. 驱动编写

2. 驱动编译

3. 驱动使用


三、模块编写

既然要编译c语言代码,首先回顾应用层代码编写的思路,首先是编写 main 函数入口:void main(),编译之后就会按照入口函数进入的顺序一条条执行,而内核中编写驱动并不是如此执行,在此需要使用到一个内核模块的知识点。

1. 内核模块编程简介

linux 内核整体结构非常庞大,包含的组件非常多。我们怎样选择性的把需要的部分包含在内核中呢?

Linux 内核抛弃把所有功能模块都编译到内核的做法,采用了模块化的方法将各组件灵活添加和删减,并且驱动模块还可以动态加载、删除。

意为 Linux 并不会将所有都加载到内核中去,而是当需要哪一部分再加载哪一部分。

使用模块的好处:

1)内核体积小:不需要的组件可以不编入内核

2)开发灵活:模块可以同普通软件一样,从内核中添加或删除

3 )平台无关、节省内存... 

2.三要素

总而言之,模块的编写首先需要一个入口(加载)和一个出口(卸载),当驱动模块加载时候,就会从入口开始执行,而卸载则会从出口开始执行。

最后需要遵循 GPL 协议,所以还要一个 GPL 协议申明。

(1)入口(加载)

module_init(入口函数名);

(2)出口(卸载)

module_exit(卸载函数名);

(3)GPL 协议申明

MODULE_LTCENSE(“GPL”);

而三要素都是内核提出的,所以需要遵循内核提供的宏函数来编写。其中入口(加载)通过 module_init(入口函数名);函数来编写,出口(卸载)通过module_exit(卸载函数名);

函数来编写,GPL 协议申明MODULE_LTCENSE(“GPL”);函数来编写。

同时出口,入口参数要传入对应的函数名,以此使得在出口和入口各调用对应的函数。

到此三要素介绍完毕,之后我们将考虑的是入口,卸载函数具体是什么类型,需要怎样的参数等等。

相关文章
|
存储 分布式计算 数据可视化
大数据常用技术与工具
【10月更文挑战第16天】
761 4
|
Perl
perl之print,printf,sprintf使用案例详解
perl之print,printf,sprintf使用案例详解
316 21
|
自然语言处理 定位技术 API
Android经典实战之如何获取图片的经纬度以及如何根据经纬度获取对应的地点名称
本文介绍如何在Android中从图片提取地理位置信息并转换为地址。首先利用`ExifInterface`获取图片内的经纬度,然后通过`Geocoder`将经纬度转为地址。注意操作需在子线程进行且考虑多语言支持。
1297 4
|
安全 算法 网络安全
网络安全的守护者与挑战者:漏洞、加密技术与安全意识的博弈
在数字时代的浪潮中,网络安全成为维护信息资产的重要防线。本文深入探讨了网络安全的核心要素——网络漏洞、加密技术和用户安全意识,以及它们之间的相互作用。通过分析最新的研究数据和案例,本文揭示了网络攻击的常见模式、加密技术的最新进展以及提升安全意识的有效策略。文章旨在为读者提供一套全面的网络安全知识框架,帮助他们在日益复杂的网络环境中保持警惕,采取适当的防护措施。
130 27
|
C语言
C语言中的无参函数
C语言中的无参函数
959 1
|
存储 消息中间件 Java
Java多线程实战-异步操作日志记录解决方案(AOP+注解+多线程)
Java多线程实战-异步操作日志记录解决方案(AOP+注解+多线程)
|
机器学习/深度学习 人工智能 算法
一、单层感知器(MCP人工神经元模型)
一、单层感知器(MCP人工神经元模型)
|
JavaScript 前端开发
JavaScript弹窗事件
JavaScript弹窗事件
139 0
|
SQL 关系型数据库 数据处理
实时计算 Flink版产品使用合集之作业原本只配置了采集一张表,现在想增加一张表,这张新增的表将会增量采集还是重新全量采集
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
228 0
|
机器学习/深度学习 PyTorch 算法框架/工具
Pytorch学习笔记-07 模型finetune
Pytorch学习笔记-07 模型finetune
240 0
Pytorch学习笔记-07 模型finetune