模块编写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”);函数来编写。

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

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

相关文章
|
5月前
|
开发者 Python
函数与模块:编写高效的Python代码
【4月更文挑战第8天】本文介绍了Python中提升代码效率和可读性的关键——函数和模块。函数是可重复调用的代码段,用于封装逻辑,减少重复,提高结构清晰度。通过`def`定义函数,使用`return`返回值,支持位置、关键字、默认和不定长参数。模块是包含Python代码的文件,用于组织代码,可导入使用。通过`import`导入模块,创建自定义模块以分解大型项目。熟悉Python标准库中的模块能提升开发效率。掌握函数和模块的使用对编写高效、易维护的代码至关重要。
45 2
|
2月前
|
存储 测试技术 数据库
Python接口自动化测试框架(练习篇)-- 函数编程(一)
本文通过实际的编程练习,讲解了面向过程编程的概念和应用,包括如何定义函数、处理文件读写以及实现用户注册功能,最终将这些过程封装成函数,体现了Python作为脚本语言的面向过程编程特性。
17 2
|
2月前
|
IDE Java 测试技术
Python接口自动化测试框架(基础篇)-- 基础语法(真的很基础)
这篇文章是关于Python编程语言的基础语法介绍,包括编码、标识符、注释、行和缩进、输入输出以及导包等基础知识点,旨在帮助初学者理解并掌握Python编程的基础。
19 2
|
2月前
|
测试技术 Python
Python接口自动化测试框架(练习篇)-- 函数编程(二)
本文通过具体的编程练习,深入探讨了Python中的函数编程,包括如何定义函数、使用参数和返回值,以及函数式编程的技巧和应用,如使用lambda表达式和递归函数解决实际问题。
19 1
|
2月前
|
IDE 测试技术 开发工具
Python接口自动化测试框架(基础篇)-- 讨厌的异常处理
本文详细讨论了Python中的异常处理机制,包括异常捕获、异常抛出、自定义异常、环境清理,以及使用上下文管理器确保资源正确释放,最后还提到了Python的标准异常类。
22 1
|
5月前
|
JavaScript 前端开发 测试技术
编写JavaScript模块化代码主要涉及将代码分割成不同的文件或模块,每个模块负责处理特定的功能或任务
【5月更文挑战第10天】编写JavaScript模块化代码最佳实践:使用ES6模块或CommonJS(Node.js),组织逻辑相关模块,避免全局变量,封装细节。利用命名空间和目录结构,借助Webpack处理浏览器环境的模块。编写文档和注释,编写单元测试以确保代码质量。通过这些方法提升代码的可读性和可维护性。
39 3
|
5月前
|
IDE Linux 开发工具
Python语言的编写和运行代码
Python语言的编写和运行代码
116 1
|
前端开发 JavaScript
前端代码如何规范编写?
前端代码如何规范编写?
112 0
|
Java 测试技术 数据库连接
python接口自动化(二十一)--unittest简介(详解)
前边的随笔主要介绍的requests模块的有关知识个内容,接下来看一下python的单元测试框架unittest。熟悉 或者了解java 的小伙伴应该都清楚常见的单元测试框架 Junit 和 TestNG,这个招聘的需求上也是经常见到的。
220 1
python接口自动化(二十一)--unittest简介(详解)
|
安全 Java 测试技术
python接口自动化(三)--如何设计接口测试用例(详解)
上篇我们已经介绍了什么是接口测试和接口测试的意义。在开始接口测试之前,我们来想一下,如何进行接口测试的准备工作。或者说,接口测试的流程是什么?有些人就很好奇,接口测试要流程干嘛?不就是拿着接口文档直接利用接口 测试工具测试嘛。其实,如果只是三五个接口,你可以这么做一个临时的接口测试。但是,如果是上百个接口,或者,你们公司的这个项目,第一次做接口测试,那么,我们还是很有必要严格遵守接口测试的流程。
343 0
python接口自动化(三)--如何设计接口测试用例(详解)
下一篇
无影云桌面