根据费曼学习法,把知识点讲出来,能够加深一对知识点的理解。今天给自己讲一遍 linu 内合中 p l 的系统的驱动框架,一共画了一二三四五个图。 首先假如说我们想用某一个银角去控制 gpf 的量变的话, 一般来说我们需要做下面五个工作,一个的话是使能外设适中,然后我们要把这个银角配置为 tfo 功能,然后要配置这个银角的电器属性,比如说上拉下拉驱动能力的, 然后的话是配置 gpro 为输出,配置 gpro 为高低电瓶。其中第四步和第五步,也就是 配置 gpl 的方向和高低电瓶是由 gpl 的系统来做的。 gpl 的系统的话,它的一个大体的层次结构是这样的。 首先上面假如说我们在其他的一些驱动程序里面想去操作某一个 gpl 引脚的话,我们是去调用这个 gpl 内部库里面的一些标准的接口, 然后这个 dpo 库里面这些接口或者这些函数,他进一步是去调用的 dpo 控制器驱动里面的一些函数, 也就是这个这排控制排污库是起到一个承上启下的作用,有点类似于恰当的说,有点类似于 iphone c 里面的一个号。然后具体举例来看的话,你比如说我们 在 led 驱动程序里面,我们调用了一个 pl set value 这个函数去设置外设,去设置某一个引脚的电瓶,然后它这个函数就是 gpl 库里面这些函数全部都是 gpl 库里面的,我们这个函数也是在 gpl 库里面, 然后他这个函数具体如果我们去看临久离合源码的话,他进一步是调用的这个函数,然后这个函数里面他最终调用的是这个 table 里面的所有的函数, 而这个 table 是什么 table? 它就是这样的一个结构体,然后它里面是有这种 set 成员的,它这里的 ctable 里面的 set 函数是我们在一下控制器里面 不测的那个结构体里面的这一个成员,这就是 gpro 控制器的一个 起的层次结构。接下来的话,我们看一下 p l 控制器区域的一个源码,也就是这里,比如说这个 p l chief 里面这个成员是怎么来的, 然后我们在设备处里面,比如这个有个 p l e 控制器接点,然后它的 compatible 属性是这一个,然后我们在领导力和源码里面去搜这一个 compatible 这个关键字,能够搜到这里。 那么当我们呃控制器添加添加驱动或者设备的时候,会根据这样看 padbox 属性去进行匹配,匹配成功之后就会去调用这个驱动程序里面的 pro 函数,也就是这里这个函数。然后他在这个 pro 函数里面其实主要就 做了三个工作,第一个是分配着这样一个结构体,然后去设置这个结构体,然后最终去把这个结构体进行注册。接下来具体看一下这个 pro 成员里面的一些实际的操作。首先在这个 pro 函数里面, pro 本函数它首先调用的是这样一个 get 函数 y 这个函数,这个函数它其实就是获取了一个集成器组,在这里面它获取了这样这样一个结构器,这个结构器里面其实它就是 e p l 控制器的一个 神奇的便宜地址,我们从呃芯片手册里也能看到这个便宜地址,零四八 c 就是一个便宜地址。然后他又调用了 pro 版上市里面又调用这个 guest 效的函数,他获取的是设备书中的内存资源信息,内存资源信息也就是这里的 reg 属性。那通过这两步,前面第一步是获取了便宜地址,这个是获取了基地址,那其实通过这两步就可以获取到这个控制器的一个所有的计算器地址。 然后接下来他就开始分配这样的一个结构体,这样的结构体也就是这里的一个 pod 结构体,这个 pod 结构体里面有一个重要的成员是 p f 结构体, 然后这个 table 结构体里面就有这些具体的操作函数,设置方向、输入、输出,还有 set 这些操作函数。然后他现在分配了这样一个 ttle 结构体了,接下来他要去设置这个 tttle 结构题,也就是给 这些成员复制设置结构体,他是在这个函数里面进行,然后他这个函数里面首先这一个成一个成员就是这里的这里的 c 成员, c 就是这里的 gpl table, 然后它其他的后面几个参数就是前面获取到的这些计算器的地址, 然后他这个函数里面分主要就用这三个函数去设置这个结构题。这三个函数代码可以大家看一下里面,比如说这个第一个函数,就是这些计算器给他复制,然后这些赛的成员给他把这个函数复给他,这里面也是一样的, 这些 red red right 这些成员也都用具体的函数给它复制过去,这里也是一样的,这是设置方向的, 他其实就把这些具体的操作函数一些成员给他付给他。然后这第二步相当于完成了结构体的设置。第三步就是注册分配设置注册,注册的话,这里是申请了一个 这里 d p i o d y s 的成员, d y s 结构题, d p i o d y 结构题就是这个,然后他这里面就有一个 t p i o table, 这个 table 就是 这个 table, 就是前面这里说的这个 table, 然后它 然后他这里面把它注册到内核中。那其实通过这几步的话,我们内核中就已经通过这个结构体,我们既有然后控制器的这些计算器,还有这些具体的操作函数, 那我们就可以用这些函数根据这些计算器的地址去设置某一个引脚的,比如说输入方向,输输方向为输入还是输出,还有设置它的高低电瓶,这就是 dpl 控制器驱动程序的一个整体的流程。 然后接下来的话看一下 etf 控制器重要的数据结构,前面我们说过我们重要的结构器是一个 tf trip, 然后它这里面就包含这些具体的一些函数。 而这个 tip 我们最终注册的时候,我们是把它放到了这个 g p l d 八去里面,这里的这个 tip 成员 这个 gpr 里面 s, 一个 gpr 里面 s 就可以理解成一个 gpr octrl 了。然后它这里面除了有一个这 成员,这边还有一个 discrime 成员,这是一个结构体数组,然后这个数组里面每一项就代表着一个 discribe, 代表一个引脚,比如说这个控制器他有四个引脚,那他这个这个里面他就有四项,他这每一项他都是一个小 discribe 结构器。 然后这个结构题里面他还有一个这个 ddv 成员,他这个 ddv 成员的作用就是表示这个引脚他是属于哪一个控制器的。假如说我们 获取到了一个 dpl describe 这一个结构体的话,那么可以根据这个成员知道它属于哪一个,反推过去属于哪一个控制器,这是它里面的一个答题的数据结构。 然后接下来看一下函数要用具体的实现的原理。 这里举例来说,假如说我们有两个 gpi 控制器,这里是 gpi 控制器零,然后它上面有四个音角,这里是 gpi 控制器一,它上面有三十二个音角,那对于 gps 控制器零来说,那这里面这个意思 也就是号码机值,就他引脚的号码机值,他就是零,然后 n、 g、 p、 l 有有几个引脚,就有四个引脚,他这里标号的话就是零一、二、三, 然后这里的话这个这篇控制其一他的这个贝斯是从四开始,然后他有三十二个音角,他的雷宝这个标号就是四、五、六一直到三十五, 然后他这里面这个速度就是有四项,这个速度的话是有三十二项。现在的话,假如在设备书里面有这样一个 点,然后他用的是 dple 里面的十个引角,那么我们在 led, 比如说 led 驱动程序里面,我们用这个 dpl get 去获取的时候,他就会得到的是 dpl 一控制器里面的第十项, 第十项,那么这边返回的这个 led dpro, 它就指向了这个 cramp, 它里面是第十项,然后它根据这个底层发热膜结构器就可以找到它是属于哪一个控制器,因为它这里面有一个这个 dv 成员,它就能找到属于控制器一。 然后呢,接下来我们再去用 gpl set value 的时候,咱这边最终是这个 chief 里面的 site 成员嘛,他就可以知道是属于哪一个结构,就哪一个控制器里面的这个 tip 的 site 成员就可以完成 我们这个某一个引脚的设置,这就是电动离合 gps 系统的一个驱动框架。
粉丝578获赞2758

大家好,欢迎大家观看迅媒电子 linux 的视频。这节课我们继续学习 gpio 子系统相关的基础知识。 上节课给同学们讲解了使用 c s f s 控制 g p i o 的方法。有的同学可能就会犯嘀咕, 老师,你给我讲解的这种方法,我可以使用命令去控制这 pl, 但是我在后面项目开发的时候,我是要通过程序去控制这 pl 呀。那我使用 csfs 这种方法还可以吗? 这节课老师就带着同学们打破这层窗户纸。我们用这种方法通过程序去控制。我们要怎么编写程序呢? 大家在跟着我写实验代码之前,上节课老师讲解使用命令通过 csfs 控制 gpio 的实验,同学们必须跟着一起做完,而且一定要做成功,不然你跟着我写实验代码是没有意义的。 我们打开虚拟机无斑图。这节课的实验是我们第八十二个实验, 我们创建一个目录,名字呢?我们就叫 j p i o ctrl 零一。 我们这节课写的是应用程序,我们不会写驱动程序,所以用不到 make fire。 为什么写的是应用程序呢? 我们使用这种方法控制 gpl, 是不是提前底层驱动就支持了呀?所以我们不用再去写驱动了,我们直接写应用代码即可。 我们创建一个 c 文件, 然后我们使用 vs code 打开这个 c 文件。 这个程序我们要怎么写呢?或者 说我们编写这个程序的思路是什么?我们现在既然能使用命令去控制 jpl, 那我们编写程序的思路是不是就是通过程序去执行这些命令呀? 现在思路已经清晰了,那代码我们就可以开始编写了。 我们写一个慢函数, 在慢函数里面我们要做什么事情呢?我们看一下使用命令的方式是如何控制这片 l 的。第一步是不是先使用这个接口, 也就是它将 gpl 从内核空间导出到用户空间呀?所以在慢函数中,我们首先是不是也需要使用程序将 gpl 从内核空间导出到用户空间呀? 那这部分的代码我们要怎么写呢?我们可以再写一个函数,比如这个函数名字叫 g p l e x p o r t 就是将 g p i o 导出。 那首先呢,我们需要打开这个接口, 打开接口我们直接使用 open 函数就可以了。我们先定义一个聚丙 fd open 函数。这些我在系统编程的视频中都有给同学们讲解过,如果不清楚,同学们请看之前的视频 接口是不是它呀,所以我们要打开它, 我们用这个止血的方式去打开就可以了。然后我们把它的投文件加一下,我们看一下投文件都有哪些。 所以同学们在使用这些函数的时候,头文件你不用去背,你直接去查看这个慢手册就可以了。 然后我们也可以判断一下,如果说这个句柄小于零的话,是不是打开失败了呀?那我们就可以打印一句话,在应用里面,我们使用的打印是 printf, 不要搞错。 接口打开成功以后,接下来我们是不是就要用这条命令将对应的 gpl 通过 gpl 编号导出到用户空间呀?这条命令我们在应用程序里面要如何去实现呢? 首先这个函数我们需要加一个参数, 这个参数呢,我们要从这里传递进来啊,传递进来的这个参数呢,就是 j p i o 编号,也就是对应这条命令的十五。 然后我们计算一下这个参数的长度,我们再定义一个 l e n, 它呢就等于 s p r l e n 就等于这个函数的计算结果。 我们把他的头文件加进去, 然后我们直接调用写函数将它写进去,也就是通过写函数去代替它。 我们再定义一个 r e t, 我们是不是得将它写到这个地方呀。所以第一个参数呢是 f d。 那我们写什么呢?写的是不是就是十五呀? 就是它。那这个长度呢,是不是就是 l e n 呢? 我们看一下它的这个头文件啊,是哪些啊?这里面啊没有给我们写头文件。这个呢,应该是和 open 啊是一样的。 接下来我们也可以判断一下有没有写成功。那如果这个 r e t 它要是小于零的话,那就是写失败了。 然后我们 colors 掉这个 fd, 我们在这啊也可以加一个。那这样 g p l 导出的这个函数我们就写好了。 通过这个函数去调用这个接口,使用 j p i o 对应的 j p i o 编号。 j p i o 编号是在这里传递进来的,就可以将对应的 j p i o 从内核空间导出到用户空间。 这个函数,它就相当于这条命令。 除了将 g p i o 从内核空间导出到用户空间的函数,是不是还有取消 g p i o 从内核空间到用户空间的导出这样的一个接口呀。所以我们在使用函数去调 有这个接口,那思路是不是和这个函数是一模一样的呀?所以我们就直接复制就可以了。函数名呢叫 g p i o u n e x p o r t。 然后我们要打开这个接口, 这样这个函数是不是就可以去调用这个接口了呀?代码就写好了。 接下来在主函数中,也就是慢函数中,我们就可以去调用这两个函数去导出和取消导出 gpl。 我们这里来调用一下, 将 gpl 导出到用户空间之前,我们是不是需要先判断一下这个 gpl 是不是已经被导出到用户空间了,如果他已经被导出到用户空间了,你是不是就不用再导出了呀?你需要将它取消导出。 我们要如何判断呢? 将 g p i o 导出到用户空间以后,是不是会在这个路径下得到一个 g p i o i o 十五的文件呢? 那我们就判断在这个路径下有没有这个文件,就可以判断有没有被盗 出到用户空间。 我们这里使用 s printf, 我们进行一下拼接, 它呢是用来存放我们的路径的, 也就是这个路径。 我们 需要看一下在这个路径下有没有 j p i o 十五, 这个十五呢是通过这里传递进来的。 那所以我们在调用这个函数和这个函数的时候,这个十五我们是不是也得写进去,因为刚才我们在写这个函数和这个函数的时候,已经说了十五是从这传递进来的。 那最终呢,实物是我们在执行程序的时候啊,通过它传递进来的。 然后我们直接使用 a c c e s s 来判断这个文件是不是存在? 判断文件是不是存在,我们使用的参数是不是 f ok 啊, 我们将它的图文件写一下。 大家如果没有用过这个函数,也可以看一下说明。 如果这个文件 不存在,我们是不是就要将它导出一下呀?那我们就要调用这个函数,然后这个文件如果存在,说明他已经被导出了,那我们是不是就要取消导出一下呀? 在慢函数中使用这两个函数,将 g p i o 导出到用户空间以后,接下来我们就可以去设置方向和值这两个属性。也就是将它设置成输入或者是输出,或者写零,写一 或者读输入的值是零还是一,这两个属性文件所在的路径是不是这个路径下的这个里面呀? 在这里 value 和方向。那所以接下来我们在写程序的时候,是不是就要进到这个路径下去操作这两个属性文件呀?所以这里我们再定义一个函数, 这个函数的名字我们叫 j p i o control。 在这个函数里面,我们是不是要传递进去两个参数呀?为啥是两个参数呢?我们是不是需要去设置方向?还有我们设置完方向之后,我们是不是要往里面写值啊,也就是写零啊。写一。 再给大家解释一下这两个参数。第一个参数就是属性,也就是这个命令中的他。 第二个参数就是值,也就是这个命令中的 alt。 那同理对应这里的就是 y 六这个属性和零和一这个值,也就是他和他。 首先我们是不是也得 去打开这个方向啊,或者是直呢?那这里我们要怎么写呢? 这个变量就是存放路径的,然后我们使用 s printf, 我们获取一下这个路径。 呃,路径的格式我们可以写成百分号 s 加一个斜线。 后面这两个参数,一个是不是就是 g p i o 路径呀, 还有一个呢,就是我们这里传递进来的这个 a r g 啊,应该是它。给大家解释一下啊,这个代码这个参数呢, 他会被放到这里,那他的值是什么呢?他的值是不是他呢? 假设我们这里传递进来的 g p l 编号是十五,那这个 s 呢,就会等于十五,然后会给到啊这个地方。接下来呢是一个斜线, 斜线后面呢又跟上了一个它,那这个 a r g 是不是从这里传递进来的呀?如果说我们在这里 传递进来的参数是方向,也就是他,那最终这个值是不是就是他所在的路径呀? 如果大家不明白,大家可以把它的值打印出来,然后呢自己跑一下实验代码来看一下。然后我们使用 open 函数去打开这个路径下的属性文件, 这个路径下的属性文件它是不是就是 是不是就是他所在的路径和他所在的路径呀。 然后我们判断一下有没有打开成功。 打开成功之后,那我们是不是也是需要往里面写呀?我们要写什么呢?我们写的是不是这个值啊?所以我们还是先看一下这个值的长度,然后将这个值写进去, 这样这个函数我们就写好了。接下来我们就可以在慢函数中去调用 gpl ctrl 这个函数去设置 gpl 的方向和值, 我们是不是就可以直接在这个衣服判断后面去调用呀?这个函数有两个参数,第一个参数 是不是就是对应这条命令中的他和这条命令中的 y 六呀? 第二个参数它对应的是不是就是这条命令中的 alt 和这条命令中的一或者零呀? 因为我们去控制一个 led 灯,肯定是要将它设置成输出,所以我们就可以这样写。 设置完输出之后,我们是不是就可以去设置他的高低电瓶呀? 那这里呢,你可以直接啊写零或者写一。那这里呢,我想通过从这传递进来的参数去控制,所以我就可以这样写。 这样呢,我们在使用这个程序的时候,我们传递进来的参数,第一个参数是不是就是 jpl 对应的 jpl 编号呀,也就是 arj 为一。第二个参数就是我们是要把这个 jpl 设置成高电瓶还是设置成低电瓶。 用完了这个 gpl 之后,我们是不是得把它取消导出呀?所以我们这里再调用一下这个函数。这样呢,我们的应用代码就写完了,我们按 ctrl s 保存一下。我们编译一下这个应用程序, 看看有没有问题。这个应用程序我们是需要放到开发板上去运行的,所以我们不能用 jcc 变异器去变异,我们需要使用开发板对应的交叉变异器。 交叉变音器所在的路径是不是在原码里面呀?比如说在安卓原码里面和 linux 原码里面。 这里老师使用的是 linux 原码下这个路径下的这个交叉变音器。 那同学们找这个交叉变音器的时候,你去你 linux 原码所在虚拟及无班图的实际路径,比如说这个目录下放的就是老师 linux 的原码,那老师 这个 linux 原码是在虚拟机无版图的这个路径下,在 linux 原码下的这个目录下就有交叉变音器。然后我们进到这个路径下,我们要使用 j、 c、 c 去变音, 也就是这个交叉边缘器 编译成功没有问题。 l、 s 看一下,得到了可执行文件。 这里是 a m 六十四的,不是叉八六的。如果你要直接使用这个 j、 c、 c 去编译,它编译出来的是叉八六的,是没有办法在板子上去运行。我们将它拷贝到 cal, 晚上运行看一下实际效果。老师已经将变异号的程序拷贝到了开发版中。在这里, 同学们在跟着老师做这节课实验之前,上节课直接使用命令去控制 led 灯的实验,同学们一定要跟着做完并做成功,然后再跟着老师做这节课使用程序,通过 csfs 这种方法去控制 gpl 的实验。 不然你直接做的话,有可能某些细节你没有注意到,你是做不成功的。 我们执行一下这个可执行程序。这个可执行程序后面是要跟参数的,我们要跟哪些参数呢? 第一个参数 是不是他呀?那这个参数他对应的就是 gpl 编号。上节课我们讲控制 led 灯的时候,是不是给大家分析过了, led 灯对应的 gpl, 对应的 gpl 编号是十五呀, 这个食物最终会传递到这里,然后呢将它导出。第二个参数是不是它呀?它控制的是高低电瓶, 所以我们后面跟上十五和一一的话就是高电瓶,对应的就是点亮 led 灯。我给同学们看一下开拉板, 开发板上老师运行的是 linux 系统,我把它缩小,方便同学们去看。我们控制的是这颗 led 灯,同学们注意看它的亮面,现在是一,那就是点亮它,现在这个 led 灯是不是它就亮了呀?然后我们再写零是不是就熄灭了呀? 这样我们就使用程序通过 s、 y、 s、 f s 这种方法去控制了 led 灯。这个程序写的思路也就是使用程序去执行这些命令。这个思路也是很简单的, 同学们可以自己尝试着写一下。先不要照着老师去写,因为思路已经有了。这节课老师就先讲到这里,谢谢同学们的观看。

题找到了啊,你代码的时候这个地方忘了,直接从上往下拷贝了啊,把它还原一下。是这样的。 这种是不确定,加了个清空,这是还原之后的。那这个地方都忘了去,所以导致计算器的配置全错了。这个不用去, 就这个或等于啊,这边都没去有这么一个代码。然后我们重新编译。 编完了之后,这边我也重启一下吧,搞一个全新的。这边是摄像头。现在 红灯是亮的,光线还非常强。边上绿灯和蓝灯都是亮的。三个灯。 写的时候不够细心啊。 接完成然后贴 哦。 cd 杠 lab 嗯,第一批 把我的微加载它就关了啊,红灯已经关了。点杠 a p p 一亮了啊。点杠 a p p 零关了。这就是一个驱动控制 啊,律动控制那个两次一是没效的啊。我这边因为没有加那种翻转。 嗯,有一个注意事项就是这个。我们在这边要改设备术啊。这个设备术的话我是已经改过了,就这一块。 嗯,现在我可以把它再重新编译一下。文档中设备数这一块我已经整过了啊。设备数的一个编译。设备数编译啊,就这个 mac etbs 嗯,我把原声的重新编一下啊。 mac d t b s 这个没保存,保存一下, 那刚刚的效果大家也看到的是 ok 的对吧。然后我再把它考过去,考过去设备数考了。然后就要重启原声的。应该是这样的。 他这个红灯,他在不停的闪烁。嗯,等他启动啊。启动完了之后,红灯是在闪烁的,并且是不可控的。 a 要把这个灯把它关了。 嗯,大家现在应该能看得到啊,这个红灯在闪烁对吧。 啊 o o t 红灯红灯不停的在闪。 c d 杠我走。刚才一样的一个过程。 嗯,第一批 mode mode lower 的。嗯,那红灯在 带伞,他根本就没有关。点杠 a p p 一嗯,点杠 a p p 一没有用啊。没有用。零 嗯,也没有用。所以说大家在写这个的时候,一定要记得去把这个设备数把它改了啊。我们回过头来,我们再把它改回去啊。比如说这一段,这两个,我们把它注视掉,或者是你只改这个状态, 直接改成两个状态,把它变成禁用也 ok。 保存编译设备数, 然后把设备数考过去。嗯,考过去之后重启这里啊。重启一下, 这是设备书。那两个柱掉,柱掉了之后,这两个灯就是那个了。嗯,我也不知道是亮的还是熄的吧。哎呀,好像一个亮一个熄吧。绿灯是熄的,红灯是默认是亮的。 但他不闪了啊。 嗯,现在就应该能看得到差别了。之前在加载的过程中,他已经在闪了。 现在在加载的这个过程中,他已经没有动了啊。 ot a d 杠你看,已经 不散了。第一批 一敲火车熄了。杠 a p p 一亮了,零一了, 可以看得到结果了啊。 这个就是啊,点灯啊,用驱动点灯。要注意的一个问题,用它的这个板子啊。 a t k 的,用原子的。这个板子要改四位数, 我们现在整理一下啊。嗯, 这是资料, 加一个吧, 流程,不然的话到时候东西不好找。这是几级啊?这是二级。这是改成三级三级。 第一个是找资料找计算器,第二个是写代码。写代码的话,我们首先是嗯 e 计算器 and now 定义 后是计算器的常量定义好了之后。然后是 q 里内存指灯 uni, 嗯,不是虚拟地址,虚拟地址指针印印。然后再是虚拟地址映射,虚拟地址映射之后 uni 地址。一个是映射,一个是反过来的。词叫什么?要释放,这叫释放吧。 然后是 led 计存器 不说话, 不是 led 开关 框架路口出口修改, a p p 修改, 设备数修改。就这么几个过程。然后一个个的截图, 肯定要定义。 买这个吧。别墅的都来都来到这里了。 led 两个路调 倍速修改, 一个个的来。首先是地址映射,地址映射, 嗯,计算器量定义。量 意思 计算器地址常量定义,虚拟地址指针定义, unit 指印设 你地址一个。那不就是 led 初始化吗?有关方法 一滴益生菌 下面呢。这个就不需要了,他就在 led 处置画里面。 led 开关 已经消失了。 嗯,虚拟地址释放 led 触手画。我要搞定 a d 啊。虚拟地址释放 led 开关。然后是框架入口出口, pp 修改出入口。 it 方法太长了,那直接省略了啊,不写了。嗯, a p p 修改修改, 放弃了。 怎么一回推两个, 领略了。大概就这么一个流程啊。这是计算器操作的啊,涉及到的函数就这么几个函数。 那是,这是从头到尾啊,我们签一遍有有这么多啊。基本框架啊,有的就说明了,有的就没有说明,有的还做了小实验啊。内存拷贝,然后是动态的去注册以及创建, 那个动态创建节点就是计算器操作到这里,每一个小的驱动实验就完成了啊。这讲就到这里了啊。

大家好,欢迎大家观看迅威电子 limi 核磁视频。上一节课我们写了一个最简单的驱动 hello word, 这个驱动程序我们要怎么编译呢? 我们如果在单片机上开发驱动程序,是不是有像 koiar 这种工具供我们使用呀?如果我们写 linix 应用程序,也有像阿姆 jcc 这样的变异器供我们使用, 但是我们现在写的是驱动程序,驱动程序要如何变异呢?这节课我们一起来学习一下。我们现在写 写的是 linux 驱动程序,我们的最终目标是想让我们自己写的驱动程序在 linux 系统中跑起来。 我们在介绍 linix 内盒原码的时候,是不是讲过 linix 内盒原码的顶层目录呀?在顶层目录下有一个 drivers 的文件夹,这个文件夹下放的就是 linix 系统的驱动程序。 我们是不是也可以将我们自己写的驱动程序放到这个文件夹里面呀?然后我们编译 linix 内核,我们在编译 linix 内核的时候,就会一起把驱动编译到 linix 内核里面, 所以这个就是第一种编译方法,将驱动放到 linux 内核里面,然后编辑 linux 内核,这样 驱动会直接变异。在 linux 内核里面,我们用驱动的时候直接稍写 linux 内核镜像就可以了。这个是第一种变异方法。 第二种编译方法是把驱动程序编译成内核模块,内核模块是独立于 linux 内核以外的模块。 所以第二种编译方法和第一种编译方法的最大区别就是,第一种编译方法是把驱动程序编译到 linux 内盒里面,我们用它的时候要稍写 linux 内盒镜像。 第二种方法是把驱动程序编译成 linix 内核模块,这个模块它独立于 linix 内核以外,我们用它的时候再把它加载到 linix 内核里面就可以了。那什么是 linix 内核模块呢? 内核模块是 linux 系统中的一种特殊机制,我们来想一个问题,如果我现在有非常多的驱动程序,也就是有非常多的点 c 文件,如果我使用第一种方法将这些驱动全部编译到 linux 内核里面, 我们编译得到的 linix 内核镜像,它的体积是不是就比较大呀?而且我们全编译到 linix 内核里面,它会拖慢 linix 内核的启动速度,这个也非常好理解。我们可以用 windows 电脑给大家做类比, 比如我现在在 windows 电脑上安装了非常多的软件,这些软件它是不是就占用我电脑的地方呀?而且 windows 系统在启动的时候,它的启动速度也会变慢,这个也非常好理解。还有 一个问题就是有些驱动我们使用的频率很少,或者暂时用不到,如果我们也把它编译到 linux 内核里面,它是不是也会造成我们体积上的浪费,并拖慢我们的启动速度呀?这个我们也可以用 linux 系统给大家做类比, 比如说我在 windows 电脑上安装了一个我很不常使用的软件,但是这个软件他也占用了我电脑的内存,也拖慢了我电脑的启动速度。 那为了解决这个问题, linux 系统它就有了一个特殊的机制,这个机制就是 linux 内核模块。内核模块它是独立于 linux 内核以外的,也就是说我们把驱动程序编译成 linux 内核模块, 得到的是一个单独的文件,这个文件它的后置是点 k o, 也就是 k o 文件。 那这个 ko 文件我们要怎么用呢?我们可以在系统运行的时候将这个 ko 文件插入到 linux 系统当中,我们不用的时候就可以将这个 ko 文件从 linux 系统中卸载掉, 这个过程我们是无需重启 linux 系统的。使用这种方法是不是就解决了刚才我说的那几个问题啊?而且也非常的方便,所以这个就是第二种方法,将驱动程序编译成 linux 内核模块。最后我们再来总结一下, 我们编译驱动程序有两种方法,第一种方法就是将驱动程序编译进 linux 内核。第二种方法就是 将驱动程序编译成 linux 内核模块,所以我们编译第一个驱动 hello word 就有这两种方法。在后面的课程中,我会分别给大家介绍这两种方法。这节课我就先讲到这里,谢谢大家的观看。

大家好,欢迎大家观看迅威电子 linux 视频,我们将前置知识学习完了以后,就可以学习如何将驱动贬义到 linux 内核这节课我以三五六八开挖板为例, 我们要如何将驱动变异进 linux 内核呢?这里我带着大家先分析一下这个需求。 我们之前讲 macmat newcanfig 图形化界面,我们说可以通过这个图形化界面来控制驱动的状态, 可以让驱动编译进 linix 内核,也可以让驱动不编译进 linix 内核,再或者让驱动编译成 linix 内核模块,我们可以使用图形化界面来实现。现在我们是想让我 我们自己写的驱动编译到林尼克斯内核,那我们是不是也可以通过图形化界面这种方法呢?那我们要怎么实现呢?我们是不是就可以在图形化界面中添加一个选项,让这个选项控制我们驱动的状态, 我们是不是就分析出来了呀?那具体要怎么操作呢?我们再继续往下分析。 我们之前是不是讲了 k 肯飞鸽文件呀?我们说图形化界面中的选项都是由 k 肯飞鸽文件决定的, 所以我们要想在里面添加一个自己的选项,首先是不是就要修改 k 肯飞歌呀? k 肯飞歌的语法我们上节课是不是也讲了呀?接下来我 以三五六八卡板为例,将 hello word 点塞这个驱动编译进三五六八的内核镜像当中,我们看一下要如何操作。我们打开三五六八的 linux 原码,然后进到 linux 原码的内核原码目录下, 这里大家使用的原码要和我保持一致,我们现在已经知道了,我们要修改的是 kick figure 文件,但是我们要修改哪个 kick figure 文件呢? 我们先进到 drivers 这个目录下,这个目录下存放的是不是就是 linux 系统的驱动原码呀?然后我们进到这个目录下,这个目录下放的就是 linux 系统的字符设备的驱动原码,我们就可以将 hello word 点 c 这个驱动原码放到这个目录下。所以我们第一步先在这个目录下创建一个文件夹,这个文件夹用来存放我们的驱动原码。 然后我们进到这个文件夹下,我们在这个文件夹下创建一个 kicking figure, 注意这个 kick 是大写的,然后打开这个 kicking figure, 这个 kitten 飞鸽我们要怎么写呢?我们是想让它在图形化界面中显示一个配置选项,那我们 增加一个配置选项,是不是实用这个关键字就可以了呀?比如说他的名字叫 hello what? 然后我们 这个选项有两种状态,我们使用这个类型,这个选项的名字,我们也可以随便起一个这个选项的名字,我们就叫这个名字。 然后我们还可以给这个选项设置一个默认的状态, 比如说我们让他默认就是选择上的,再把帮助信息添加进去,这个帮助信息我们随便写也可以了, 这样我们的 kickin figure 文件是不是就写好了呀?写好了 kickin figure 文件以后,这个 kickin figure 文件它是存在于 hello word 这个文件夹下的。那我们是不是得让上一集的 kickin figure 包含我们这一集的 k k 飞格呀?不然的话他是没有任何关联的,大家说是不是啊?所以我们返回上一集目录,打开上一集目录的 k k 飞格, 我们在这里将我们下一集的也就是 hello word 这个文件夹下的 k 肯贝格包含进去。怎么包含呢?我们是不是使用这个关键词就可以了?上节课我们讲语法的时候也讲到过,我们来写一下, 这样我们就写好了,然后保存,我们来验证一下我们 写的有没有问题。我们回到内盒原版目录下,然后输入 mac manukfiger, 我们看一下能不能打开成功,如果说你的这个界面成功出来了, 那基本上就没有问题,如果说他提示错误了,这个一般都是语法问题,你认真检查一下就可以了。我们来看一下,我们先进到 diys driver 这个目录, 然后我们进到字符设备这个目录下,因为我们是将 hello word 添加到了这个目录下,在这个目录下是不是就有我们添加的这个选项呀?然后这个选项默认已经被选择上了, 那这样的话我们第一步就已经完成了,然后我们就可以将自己 写的驱动程序,也就是 hello word 点 c 放到我们自己创建的这个 hello word 目录下,我们来操作一下, 我们将这个驱动程序拷贝过来, 这个驱动程序我们拷贝过来以后,那我们要如何编译这个驱动程序呢? 编译的话是不是就要用到 mac file 文件了呀?因为 mac file 文件里面他定义了编译规则,所以我们接下来就要在这个文件夹下创建一个 mac file 文件。 那这个 make file 文件里面的编译规则要怎么写呢 啊?我们是不是想让图形化界面来控制我们这个驱动编不编译到立那颗行列盒里面呀?所以我们的这个 make fire 就要和我们的图形化界面产生联系, 怎么产生联系呢?我们通过图形化界面配置的驱动的状态,也就是选项的状态,他最终会保存到点啃飞鸽文件当中, 是不是啊?我们来看一下,我们看一下 hello word, 这个在点肯 figure 文件当中他是怎么存在的?我们打开点肯 figure, 我们来搜一下 hello word, 哎,这里直接就找到了 啊,它是不是这样的一个存在形式呀?那我们在写 make file 的时候,我们就可以将它作为一个变量, 这个变量它的值如果是 y 的话,他就把这个 hello word 点 c 编译到林尼克斯内盒里面,如果说他不等于 y 等于 no, 那就不变异。所以我们在 mac file 文件里面,我们要引用这个变量, 这个变量等于 y 还是等于 no, 它都是根据这个图形化界面来 设置了。如果说你把它选上了,也就是在图形化界面当中把它选成了星号,那么它就等于 y, 如果说你没有把它选成星号,你就是一个中括号这样的一个状态,那它这里 啊就等于 no。 我们将这个变量啊复制一下, 然后我们呃再进到 hello work 这个目录下, 我们打开 mac file, 我们这里呢?还是 o b g 这里我们就要引用这个变量了, 那如果这个变量他要是等于 y 的话,那么他就啊变异, 这样是不是就可以了呀?如果说他的指是 y, 那么他就编译这个 hello word, 这样我们 mak five 就写好了,我们看一下这个驱动的名字啊,有没有写错 啊?和这里是一样的,那我们这个 make fire 它是不是存在于 hello word 这个目录下呀? 我们是不是也得和上一集的 makfiel 有一个关联呀?所以我们还要修改上一集目录的 macfiel, 包含我们 hello word 这个目录下的 makfiel。 我们打开 macfiel 这个呢?我们要怎么写呢?我们直接就在最前面写就可以了, 我们直接写 o b j 杠外啊,也就是默认就将它把编译进去。 这个 hello word 指的是我们 hello word 这个文件夹,这个文件夹的名字, 如果说你是文件夹的话,你后面要加一个这样的斜线啊,这个要特别注意啊,这个斜线不要忘掉,这样的话他就会包含 hello word 这个目录下的 macfive, 这样我们就做好了。那我们要怎么验证呢? 我们要如何验证 hello word 点 c 这个驱动程序 有没有编译到另类可思内核里面呢?我们可以从两个方面入手,首先我们可以编译一下内核镜像,看一下在编译内核的时候,他有没有编译这个驱动。 二,我们可以把边翼得到的内核镜像稍写到踏板上,看一下在内核启动阶段有没有加载 hello word 点 c 这个驱动程序的打印信息, 我们可以从这两方面入手,所以我们先来编译一下内核镜像。在编译之前有个细节,我们要注意一下我们在编译内核镜像的时候,使用的是不是 build 点 sh 这个编译脚本呀? 在这个编译脚本里面有这样的一个函数,这个函数叫 build gun kerno, 在这个函数里面有这样的一句代码,这个代码我们可以分成 两部分来看,第一部分啊,是这个部分,剩下的就是 mac, 什么什么,我们通过这个代码可以看出来,他应该是 mac 啊,一个 configer 文件。 大家还记得我们在讲点肯飞格文件和肯飞格文件作用的时候的那节课吗?我们说肯飞格文件是 linux 原码中默认的一些配置文件,如果我们想用这些默认的配置文件的话,要使用魅克 后面跟上默认的肯飞鸽文件的名字,然后执行完这个命令以后,就会生成一个点肯飞鸽, 我们来看他这里的操作是不是就是使用的默认的肯飞格文件来生成点肯飞格文件呀?啊?大家想一个问题,我们当前的 我们当前的这个点啃飞鸽里面,他是不是已经配上了 hello word 呀?那如果说他在代码这里再执行一下这个命令,他是不是又会生成一个新的点啃飞鸽呀? 这个新的点啃飞鸽会将原来的点啃飞鸽给覆盖掉,那覆盖掉以后的点啃飞鸽里面是不是就没有哈喽味了呀?那他是不是就不能贬义我们的驱动了呀?所以这个细节我们要注意一下,我们要简单的修改一下,这个我们要怎么改呢? 既然他使用的是默认的 config 文件来生成的点 config 文件,那我们就将我们现在的这个点 config 文件和原来默认的 config 文件进行一个复制的操作就可以了呀。我们 来看一下具体的操作,现在在我当前目录下有一个点肯飞格,这个点肯飞格里面我们配置上了 hello word, 然后我用这个点肯飞格文件来生成一个默认的肯飞格文件,我们使用这个命令, 这个默认的肯飞鸽文件是不是在这个路径下呀?这个如果大家之前认真听我讲的课,大家一定知道啊,这个默认的肯飞鸽文件是在哪啊?这个默认的肯飞鸽的名字啊,叫这个名字, 我们直接用当前的这个 configure 啊来覆盖掉原来的这个就可以了, 我们这里执行一下,这样的话,在我们使用脚本变异的时候,他使用的这 默认的肯飞鸽啊,得到一个新的点肯飞鸽,然后这新的点肯飞鸽里面就有我们配置上的哈喽味了吧,啊,就是这样的一个道理,然后我们就直接变异内盒镜像, 这个边翼内核镜像的操作,我相信大家肯定都会了, 这里呢,我们就耐心的等待他编译成功,我们可以关注一下他的编译信息,大家看这里是不是新生成了点肯飞鸽呀?如果说你不按照刚才我的那个操作来操作一下的话,那么这里呢,他就会将 默认的那个 configure 啊进行一个覆盖,然后呢,你的点 configure 里面就没有 hello word 了,这样的话你就贬义不了 的驱动了。演绎完了以后,我们来看一下, 我们进到 hello word 这个目录下 l s 看一下,我们可以发现 hello word 这个目录下这个点 c 它已经进行了变异啊,生成了中间文件,是不是啊? 从这个编译的结果来看,他应该是将这个 hello word 点 c 编译进立尼克斯内核了,但是为了保险起见,我们还是要把这个内核原码, 也就是布特点 i m g 稍写到卡板上来看一下,我这里已经将内核镜像稍写到了卡板上,稍写过程我就给大家剪掉了。我们要怎么快速的查看内核启动阶段有没有加载 我们 hello word 这个驱动呢?大家记得我们在写 hello word 点 c 这个驱动的时候,是不是在驱动加载的时候会打印 hello word 呀?所以我们就可以直接使用这个命令来检索一下有没有 hello word 这个关键字,我们来检索一下, 我们通过这个检索信息啊,可以发现在第零点五八秒的时候打印了哈罗沃的,那说明我们编译的这个内核里面有了我们哈罗沃的点塞这个驱动,说明我们的操作已经成功了,我们这节课做的实验也已经成功了, 这节课大家可以自己动手实验一下,如果说你是跟着我的学习顺序学的话,那么这节课其实非常的简单, 我们这节课学完,那么我们已经将第二种变异方法学完了,就是如何将驱动变异到内核。这节课我就先讲到这里,谢谢大家的观看。

这种看法就是能力的驱动和单品机不一样啊,这是最直观的感受。单品机下面驱动怎么写?直接就是操作寄存器,对,寄存器对吧?你觉得寄存器难的话怎么办?掉库吗?掉库函数,直接掉函数就完了,但是内内个它不一样,它竟然还有个什么 驱动的分离和分层的概念。哇,这个这个框架一上来,这理解这个东西啊啊,我用了好久我就弄蒙了,是吧?就是驱动的分离和什么什么什么分离和分层啊,这个东西。这什么鬼东西啊?这,这是什么?当时我,我出去的时候就这东西,我出去的时候就是这个想法。 这都是一些啥玩意,搞这么复杂,那有必要吗?你直接操作进行不就完了吗?搞这么复杂。这是我当时开始学的时候一个困惑,但是呢,这个困惑怎么办呢?我也 没有说是去,哎,找各种资料去把他深入去抛弃,而且深入深不了,知道吧,你再深一点,我觉得我就要放弃这个行业了。我也觉得我可能不适合了啊,我没有办法, 我都怀疑自己了,怎么办?硬着头皮往下坐。对, 通过大量的练习啊,那有些东西他很神奇,学习,学习是个很神奇的东西,我有时候觉得就是你这个知识点你不懂啊,很简单,你就狂砸,就是 这个这个知识点不懂我就啊,比如说这个什么分离分层不懂了,那我就写大量的驱动程序,我写大量的驱动程序,写的多了,你自然有一天就发现,哎,他竟然就是这么个东西。哦,那你自然就开窍了,知道吧。突然之间你竟然就开窍了,我不知道大家有没有这种感 说就一定要多做就是。嗯,我我个人的学习经历就是你看很多呢,想了解这个概念啊。你看很多解释啊,你看那么多解释没用的, 只有真的自己上手去做,多做你才会真正有一个深的认识。这就是我个人的一些学习的一些方法,就是这样的。然后常见的驱动框架也很简单,我常见的那个下面啊,驱动框架简直太庞大了啊。

f e c 一零零 s 在 linus 环境下使用 g 派,有模拟 spi 驱动七七三五 t f t 屏幕,这个刷新速度感人,因为用的 c 语言操控 s y s class 里面的 g pyo, 所以速度有点慢。 用逻辑分析仪查看时钟频率只有五二 jack 左右,基本上可以肉眼看到的看到刷新的像素点位置,可能通过操作文件来间接控制,效率太低了。驱动上层的驱动程序用的 stm 三二的程序,底层按钮使用的文件写入 还没有写自动化脚本,所以只能暂时手敲 reset 底下 看它缓慢运行。

这一张开始讲 lcd 的驱动程序,那些人们已经自带了 lcd 驱动程序,但是我想自己来从头到尾自己来写一遍。好,先来回顾一下之前我们怎么写制服设备、驱动程序、 应用程序。写应用程序的人,他只会调用 open, rely 这些接口,大家不会去看原理图,也不会看西面手册,那就需要我们来提供驱动程序这些 oppo 凌乱最终肯定得操作到硬件, 就引入了中间的驱动程序。最简单方法,你调用 open, 我给你提供驱动程序的 首款,你在用绿,我给你提供驱动程序的绿,你在用 ry, 我给你提供驱动程序的耐弹术。 就基于这个很简单的想法,制服设备怎么写呢?第一第二,构造这些东西,这东西放在这个结构体里面, fine operation 结构体构造这个结构体里面有我们的 open 函数等于什么,什么 open 读写函数等于什么,什么东西等等等等。第三,辛苦构造者要用起来 register 谁来吊用?了解窗体外入口函数有入口自然有出口,了解窗体外需要什么参数,主设备号 名字,还有这个 fire operation 结构体。第一个确定主设备号,这个主设备号你可以自己确定,也可以让内阁帮你分配。 以前我们从头到尾就是按照这一二三四五这五个步骤来写驱动程序的,那现在我们要看的是 内盒里面别人怎么写?看懂了别人的驱动程序之后,把我们的代码融合进去, 那么别人怎么写这个驱动程序呢?一样的,我们是这么写,别人也是这么写, 边也得这么做,来看一看, 那么是哪一个文件呢?首先直接写出来, fb mama 点系,我们来看一看 fb mama 点 c 这个内盒里面自带的 lcd 的驱动程序,我们先来看一看,当然他肯定不止一个,因为基于我们之前说的分层思想,他肯定会把一些共性的东西给抽出来。 看到入口函数,这是个入口函数,好看。这里 russia's 的插头外主设备号有的, five operation 结构底也有了, reach the tradeway 也有了,一二三都有了。 好创建类,以前没有创建类,这是额外的东西了。额外的东西, class clue eight 创建类在类下面创建设备,看看我们之间写的代码, cloud evacuate 这两个无所谓的,这只不过是让这个 mdy 或者 uty 这应用程序根据这些信息帮我们创建设备节点而已。看,这里,主设备好有了。第二, find operation 结构体 也看到了。第三 register xdy 也看到了,一二三都有了啊,这个创建类也有了,但是他没有这个创建,没有在这个类下面创建设备,这是有原因的。我们先来看一看,先不管这东西,那就是 xdy, 哦,不好意思,看错了, fbm 联系里面 ready 是川铁外,难道你看这里有什么东西? oppo 女赖什么,什么函数都有了, 那以后他是不是通过这行就可以来操作我们的 lcd 呢?那肯定不行了,这是一个通用的文件,我们来继续深入来看一看。先写一下文档, lcd 驱动程序 来看一看,我们来假设, 我们来假设。我们打开一个文件,他的主设备号是二十九,次数标是零 加色。应用程序 open do i have been in 主设备号二十九侧设备号零,那么会最终会干嘛呢?就会找到我们这个 fb open lesson 里面的 open 函数。 fb open 内盒里面最终会找到 fb open, 看看他做什么事情。 好,看一下。哎,这有个结构题, fb infafbfb is flame buff 正常中去的意思。 fb infa 结构题,次色 会好, 得到这个设备节点的次次设备号,然后来看看做什么事情。嗯,这个结构题等于 等于次数标,下次是零, 从这个数组里面得到一项以次设备号为下标,在这个数组里面得到一项,然后干嘛呢? 如,然后如果他有 open 函数的话,第二用他的 open 函数,没有就算了。来,然后返回这 open。 注意了,要用到这个数组。好,我们来看看我们想读呢绿的 假设,我想读一下这个内存,看看这 lcd 上有什么东西,来看看怎么读。读函数略, fb 略,应用程序来读,最终 就到内盒里面这个独函数,看看他做什么事情。 以次设备号得到次设备号,以次设备号为下标,在这个数据里面得到一项,这就是零了,次数标就是零,在这个数据里面得到一项, 这个速度,这个速度, 然后看看这餐出的判断。咱们先不用管,如果这个数组向里面提供了 fbops, 提供了独函数,就调用他的独函数,如果没有提供的话,做什么都行。咱们继续往下看,如果没有提供的话,看这里 硬化结构里面有什么 surprine, size, security, 屏幕大小等等等等。 bikis, 什么 sucream, s, mama, land 不知道什么意思,往下看,分配一个缓冲区。好,这里有个 sucream base 这个结构体,这个结构体哪来的?这个数组里面来的?这个结构体里面有一个什么?屏幕背式,那就显然应该是在想象一下,猜测一下,你去装电脑的时候是不是竟然有什么显存呢?这里就是显存,显存的基地,字读原 sus 等于 显存的基地,加上某个偏移值,大家看到吗?读,读圆,从这个圆,圆在哪里?圆是显存基地,在那里,从里面读到一个数据,放到墓地里面来,然后 copy to use。 目的是什么? dess 的什么? 该死的就拿 buff 嘛,俺不分配个 buff 嘛?要 copy to use, 那就这么简单,如果他有读函数,那就用他的读函数, 如果他没有读完数,他们干嘛呢?从这里读 screenbase 来读 screenbase 来读圆等于什么?什么东西?然后读, 读这个圆,要 copy to use it, 就这么简单, 目的等于八分。大家看 open 和读 都依赖于一个结构体, f b info 结构体。 f b info 结构体。这个结构体哪来的?从这个数组里面得到的?以次数标为下标,在这个数据里面得到一项。他现在问了, 这个结构,这个数组 在哪里被设置, 这个速度在哪里 被设置好?来看一看。再从这里可以看到, fbm 点 c, fbma 点 c 提供的都是些抽象出来的东西,他最终都得依赖于这个数据里面的这个结构体。 那么这个结构体在谁来设置?来搜索一下?好,这个结构体来搜索一下,在这个文件里面定义。那么谁来设置他呢?来搜索。搜索 等于什么时候?等于某个东西?哪个函数? let's fly and buff 注册 flying buff 好,层次就出来了。 register flame buffer, 其他文件就是硬件相关的东西了,这就是 硬件相关的驱动程序,这里呢?我给你抽象出来,对吧?你 open 驴乱都从我这里进来,等等等等,这里就定死了。 这样分成了之后,应用程序他就知道读写是什么,里面那个差距什么含义了。 io ctrl, 他要传什么, 我们插上去就定死了。这是驱动乘以分成,这就是我们的驱动乘以分成。 我们先看看 legit flying buff 他会干嘛呢?把这个结构体 先看找出哪个空向,找到空向之后呢? devocular eight, 我们说的 class devocular ace 也是 ctel。 嗯,稍等一会。 classic devaculators 最终也是 老铁,不用管 在泪下面创建设备,跟之前一样的。之前不是说过在这里吗?只创只看见他创建的泪, 没有看见在泪下面创建设备。因为你只有真正的有设备时候,你才有必要去创建设备节点,对不对?这个 mdy 才有,只有你真正有一个硬件的时候, 我才有必要在这个类下面创建设备,这样 mdyudy 才能会去创建设备节点。所以你可以想象一下这个 fbm 点 c 直播。一个抽象出来一个框架性的驱动程序,他 并不能够支持具体的驱动,他需要依赖于底层的,底层的某个驱动程序给他提供,给他注册一个 fbe info 结构体才行。从这里可以看得出来。来取 frank 白粉啊,先看到这里, 那么有哪些情绪来调用这个 lutchform 来搜索一下啊?一大堆 各种各样的 lcd 驱动程序,各种各样,内部有一大堆,也有我们的二四幺零 s 三系,这两种都有,不知道是哪一个。一三系,二十到零 f b 各种各样的东西,先把它写下来, 比如说 s 三 c, 二四幺零 f b 点 c, 也比如说 其他的, 随便找一个各种其他的,其他的就不写了,分成,以前我们写驱动程序时候一个文件搞定, 现在呢?别人帮你写好了上面这个文件,你想用这一套东西的话,你得按照这一套来,你得干嘛呢?看看这里二十到零 fb 点系,进去看一看,看看别人做什么事情, 看这驱动程序,看这驱动程序,从那入口就开始看。 注册一个平台 drive, 我们说按照总线驱动设备模型呢,我们关心他的 pro 函数,如果内核里面有同名 零的平台设备的话,这普罗法就就会被吊用。看这普罗法就里面做什么事情,根据平台设备获得某些信件相关的信息,你要干嘛? following buffalo, 分配一个 fb info 结构题 好,这里可以进各种设置,硬件相关的操作,硬件相关的操作,设置完之后,硬件相关的操作要先不用管。注册 好,从这里我们会抽象出来,怎么写驱动程序呢?来看一看 the, 分配一个 f b in 的结构体,第二,设置 第三,注册第四,那第三是硬件相关的操作, 就这么做, 这是我们分析的这个框架,之后就知道怎么回事了。来看一看,我们先把它写下来。 largest flame buff 怎么写? lcd 驱动程序?第一,分配一个 f b in 否结构体 用什么行业来分配呢?参考是别人的代码 laying buff a lock 第二,设置第三,注册,怎么注 注册呢?刚才这函数第四,那肯定得硬件相关的操作了,这就是框架,我们来看一看。核心是 fv invo 结构体, 我们来看看,比如我想得到他的分辨率,那怎么做呢?可以从上面往下看, 得到一个想获得这个 lcd 的分辨率等等这些信息要干嘛? ioconto 吊,用 ioconto 看看 lco 里面会什么东西? ioconto 里面这里有各种 commond get 可变的 v v 是什么意思? v 字 v r 可变的屏幕信息,大家以次设备好 为下标,在这个数组里面得到一个 fp info 结构体,把这个结构体里面的 var, 把这个结,把里面一个成员拷贝和用户空间,这个成员里面有什么东西,它就有 s y 方向的分辨率,就是这么简单。 从这里你可以看到 fe m 点西只不过是一个抽象出来的东西, 他最终得依赖于底层提供的 fb info 结构体,这就是我们分析的这框架。

好,大家来看,我们先从课件这里头呢,先捋一下它的这个内容,是不是先捋一下它这个大纲,然后呢,我们再细讲这个知识点。 呃,首先呢,我们看这个这部设备驱动这个课件里面呢,我们的大纲,大纲里面第一个概数,第二个 linux 驱动相关概念。然后呢是 linux 内核模块是吧?模块编程呢,我们已经给大家讲过了。然后呢,再往下是这幅设备驱动的框架, 往后呢是 gpl 的一个设计,也就是说我们的这个内核运行起来以后呢,这个 gpl 如何操作是不是?呃,大缸呢?是这样的。然后呢,像这个模块我们已经提前给大家讲了。然后呢,我们先来看一些基本的概念,和 linux 驱动相关的一些概。 我们看看这些内容呢,我们有没有涉及打算这样,第一个呢,是驱动的概述的一个内容。第一个驱动的定义和驱动的功能。这个驱动的定义和功能以及驱动的地位呢,我们在第一天的时候已经给大家解释过了,是吗?还有没有印象, 有印象吗?哎,驱动的定义和驱动的功能以及驱动的地位。然后呢,驱动程序与应用程序,驱动程序和应用程序呢,大家想一个呢,是 一个是运行在应用层的是不是?然后呢,运行在应用层呢,它是属于用户用户态。然后呢,一个是运行在内合层的,它是 内核胎。然后呢,运行在不同层次的话,他们的权限也是不一样的 是吧?能听懂不?就是内合成的代码,或者说我们的这个驱动程序运行在内合台,它的权限呢,要比应用程序的权限呢要高是不是 啊?然后呢,是驱动库,内核应用。然后呢,像像这个驱动他的一个功能驱动,驱动的定义和功能这块呢,他列了内核的五大功能,我们也说过了,是不是 内核的五大功能,内核的五大功能里面其中有一项呢,就是驱动管理,或者叫设备控制啊,我们一般称之称之,称之为这个驱动管理是不是啊,驱动管理啊。然后呢,驱动的定义和功能这些呢,我们都讲过了,那我就不再去啰嗦了行吗?啊,这些就不去 啰嗦了。然后呢,像这个刚才我已经跟他说了,观众的主主要就是应用程序呢,他是在运行态的。然后呢,我们的这个驱动程序代码呢,是在内核态的,运行的位置不一样,运行的这个所处的环境不一样, 那这些运行的环境不一样的话,决定了他们运行的时候呢,权限也不一样是吧?权限也不一样, 城市结构呢,我们也说了,所以这些东西呢,我们都不看了。然后呢,这些应用,然后呢,库内核驱动这些概念呢,我们也不看了是吧? 然后呢,大家忘记的自己呢,再去翻一翻,因为这些笔记呢,大家是不是都自己下载下去了,非修里面的是不是啊?下去呢,忘记的大家一定要下去多翻一翻。 这是讲的什么东西?其实我们在讲驱动,大家有没有发现,其实跟我们应用层呢,也是在一直在回顾大家的应用层,是不是又在加深大家对应用层的这些理解, 明白了吧,加深对应用程的一些理解,因为我们内核很多的这些机制呢,跟应用程都是为了实现应用程所提出来的某些需求,明白吧 啊。再往后呢,就些这个库库的话呢,提到了用户太的一些库,就 lip c, lip c 的那个标准 c 库。 然后呢又提到内核用的库,内核用的库呢,跟我们这个用户层的库呢,其实我们看到的这个函数呢,基本上差不多,是不是函数名差不多,只不过是实现的时候呢,这个是在内核源码中 写的。然后呢,这个是 c 的应用户层的这个库,标准 c 库呢,是去实现的。 好了,那这些呢来清楚以后,接下来呢驱动的一些基本概念。这个驱动的基本概念呢,我们其实也在前面提到过 linux 呢, 他有这样的一个思想呢,就是一切接文件的,然后呢,对所有的操作呢,都是把它抽象成文件进行操作。 然后呢,对于设备的管理呢,他也是抽象成文件的方式呢,去进行管理和操作的,对吧?然后呢,还有一个就是 linux 呢,将所有的设备给他进行了划分,划分成三大类设备,对不对?划分成三大类设备哪三大类呢?就是我们后面呢看到的。 那这样呢,一些关键的概念,我们还是要给大家写一下。第一个 哎,第一个 基本嗯概念 linux 操作系统 思想,按一切接文件的思想, 这个呢大家一定要记得。 然后呢,对设备的操作, 也是将设备抽象成设备文件。然后呢是通过 文件或者说应用程,通过文件 i o 对设备文件进行 操作,其 最终结果 我是在操作设备 啊,这句话呢,大家也要先把它记住了,然后呢,后期我们在学习的时候呢,再去理解他到底怎么做到的, 听明白了吧,你得先把它记住了,然后呢,才能去在后面的学习过程中呢,才去才能去理解。或者这样说,我们把这句话记住了,你先有一个这样的印象。那我们在后期学习的过程中呢,就是为了学习这些过程呢,到底是如何实现的是吧? 否则你后面学习呢,也没目标。呃,能不能读懂读懂这句话。其实现在呢,大家发现我们操作的时候已经是用过了,只是呢,不知道他怎么实现的。比如说我们之前对那个创口的操作。 创口的操作,当时是不是打开了一个 dv 目录下的设备文件叫 c, 就看他的那个文件类型是不是 c 啊, c 呢,就是制服设备文件吗?是吧。然后呢,我们 open 打开这个文件,然后呢,通过 red 和 red 是不是就能对这个文件进行读写,最终的结果是不是真的就是读了这个创口,写了这个创口了 是吧?现象呢,其实大家已经看到过了,只不过不知道他在内核里面到底如何实现的这个功能,对吧?哎,不知道这个。那后期呢,这个问题是不是就是我们后期要解决的一些问题对吧? 啊,这是基本的一些概念。然后呢,再就说 linux 操作系统,将设备分成三 三大类,也只有这三大类。听明白了,只有这三大类,可没有其他的。 哎,分成三大类。那分成三大类的话呢,这三大类分别是 分别是什么呢?制服设备。然后呢,是块设备 和网络设备是不是?哎,制服框和网络。好了,那我们先来看这个。 呃,块设备。块设备呢?指的是什么呢?块设备。我这这里呢,可以告诉大家指的是什么呢?指的是存储设备。 大家看到的这些各种各样的这个存储设备呢,包括磁盘啊,包括我们的这个 sid 啊等等这些东西。 emc 这些呢,都是块设备,明白吧,这些都是块设备。存储设备。 然后呢,网络设备,这个就不用说了吧,网卡是不是啊?就网卡相关的一些设备。 网络设备那除了这个充足设备和网络设备以外,剩下的全部是制服设备。听明白了不?剩下的全是设备设备。那也就说制服设备 类型太多了,对不对?基本上除了快设备和网络设备,剩下的全是。那比如说鼠标什么设备? 键盘,触摸屏,显示器。 哼,是不是也是制服的?那显示器,这这不是重组的吧?谁的数据是重放在显示器里头的?不是吧?谁上网用显示器上网的,不是用网口的,你把网线怼到显示器里面吗? 所以呢,只要不是块设备和网络设备,剩下的都是制服设备,明白吧?啊,都是制服设备。所以制服设备的类型特别庞大,种类特别庞大。明白了吧?那就剩下的都是制服设备,除 除了网络设备和块设备。好像是一句废话,但实际上就这样对吧?除了网络设备和块设备,剩下的 全部是制服设备。好,那我们根据这样的一个定义呢,其实就能够很容易去区分出来这个设备呢,到底是一个什么样的类型,对吧? 听明白了吧,你通过这样的一个描述,能不能很明确的区分出这个设备的类型啊?能吧啊能,能的话我们还要清楚什么呢?还要清楚不同的设备呢,他有什么样的特 特点,这个也要大家清楚对不对啊?这个也要清楚。好,那我们先来看这个制服设备它的一个特点。往下呢?大家看这制服设备呢,是 io 传输过程中以自己 io 就输入输出嘛,对不对? 在说输出过程中呢,是以制服为单位进行传输,以制服为单位,那一一次性传输的是不是一个制服啊,对吧,一个制服就按自己去传输,听明白了吧? 啊,这是第一个。然后呢,第二个特点,用户呢,对制服设备发出读写请求时,实际的硬件读写,紧接着就发生了,也就说这个是同步的。 你只要说用户对这个这幅设备呢,我发出读写请求了,比如说你要 red 和 red 读写它,那直接呢就会在应届上体现出读和写,也就说中间没有一个缓冲机制,明白吧, 能不能听懂?这下没有缓冲机制。然后呢,直接就输出输入,紧接着发生了,是一个同步的,没有缓冲的啊。这他的特点以制服为单位传输。这是第一个。 我们把特点呢往下斜一斜,这里呢是它的特点。嗯,第一点。 然后呢,我们再看第二点, dad 总结呢,就是同步 发声,然后呢是五五缓从七至。 好理解不? 这几句话好不好?丽姐能读懂是不是啊?能读懂这个东西呢?你能理解了这句话的意思,然后呢,能读懂他,那就 ok 了。那接下来的任务呢,就是你要把它记住特点,你只只能记,是不是特点你只能记。 然后呢,我们再来看块设备的特点。块设备呢,与这部设备相反。然后呢,他的数据传输呢,以块为单位,也就说他不是以自介为单位了,他是以块。那 跨了就是 n 多个字节。那就看这个系统里面对跨的定义。比如说有的是一个跨的大小呢,是五百一十二个,五百一十二个字节。然后呢,有的定的是啊,幺零二四对吧? 不一样,有的是四零九六。那就看这个系统里面对块的这个单位是定义的是多大是吧?那他以块为单位读取,那也就是说他一次操作的时候呢,可能是五幺二,可能是幺零二四,也可能是四零九六。看他如何定义的,对吧。 这是传输上的一个特点,数据传输以跨为单位, 就是一个数据的一个单位大小,又出来一个块。这跟大家看到那 k b 呀等等的那没什么区别 是吧?啊,就就像大家看到的米和厘米,这个有啥区别吗?对不对?就是单位不同啊。然后呢,第二个特点,用户对块的读写操作时,然后呢,应届上的读写不会紧接着发生。然后呢,其用户请求和应届操作是异部的, 是不?刚好是相反的呀?不不不,相反就是跟我们的这个制服设备是完全不一样的,对不对?他不会紧接着发生,那不会紧接着发生。你说这个数据到哪了? 那不就弄了块缓冲区放了,那先放了那吗?对不对?你总不能说他不会紧接着发声,就把数据扔了。你想发数据,你比如说你,你想把某一个文件呢写到这个,写到硬盘里面, 那你想写进去,他不会紧接着发生,然后先给你扔了,然后呢,那不没了吗?那写不进去了是不是?他肯定是先把这块东西呢,给你保存起来以后呢,等过一会呢,直接全部给你放过去。一次性是不给你放过去啊, 所以它呢是一个翼步, 有缓冲的方式。 然后呢,再一个是磁盘类,散虫类等设备呢,都分装成块设备。哎,这就说了一个块设备具体是啥了是吧。块设备是啥?其实呢,大家其实也能想明白,这个块设备呢,我们要重储数据,这个重储数据呢,不可 能说你写一个字节,就他就往往词盘里头给你写一个,你读一个,他就从词盘里头读一个字节,这个太浪费了是不是啊?你只有说我写了一块,先把它先保存到缓冲区,然后呢,我一次性操作,硬件就把它写进去了,对吧? 哎,一次性写就写进去了,不会说一次一次的。这个这样一直频繁的去操作硬件,这个硬件自己他也受不了对吧?他硬件自己也受不了, 不管是从效率啊,还是从使用的生命的生命周期啊,还是什么,对吧,都是决定了他的这种块设备的一个操作特点。 然后呢,我们最后看一下就是网络设备了。网络设备呢,是一类比较特 数的设备呢,他不像制服设备和块设备那样有对应的设备文件。也就说这个块设备和制服设备呢,是不是对应的有设备文件对吧。 然后网络设备呢,是没有的,也不能够直接通过 red red 呢进行数据的一个请求访问,而是通过 socket, 就是我们应用程学的那个 socket 接口。网络呢,它是通过 socket 去实现的对吧?然后数据接收和发送的,对应的是用的那个剩的和 receive 对吧?啊,是用的这些接口 对呢。网络设备呢,它有一个非常重要的一个特点呢,就是没有设备文件 啊,这个没有设备文件,我们不是说 内核里面一切接吻,接着怎么 socket, 它就特殊了呢? 因为网络的出现呢,它是在 linux 操作系统之前就有了是吧?并不是说 linux 操作系统有了以后才有的网络。那如果是这样的一个卸货顺序的话,它 linux 可能还真的去弄个设备文件啥的,对吧? 但是在这个 linux 操作系统之前,人家网络就有了,人家就有自己的一套标准协议,对吧?哎,这这个使用方法已经是有的,已经是固定时的,他只能兼容,明白了吧。 好,这是我们 linux 里面的三大类设备。然后呢,三大类设备清楚以后呢,我们接下来再往下啊,再往下往下看呢。这一块呢,就提到了一个设备文 界和组。从设备号。其实这个有点太早了,刚好呢,我们讲设备文件,讲这个制服设备驱动的时候再说是吧。再说好了,那我们基本概念呢,了解以后,第二个我们要看的就是这个种类最庞大的制服设备驱动。 制服设备驱动啊。那我们看制服设备驱动的什么呢?制服设备驱动的框架。先来看框架,然后呢,才能去在这个制服设备驱动的框架基础上,完成制服设备驱动的一个编写对吧?完成制服设备驱动的一个编写。 这是我们接下来呢要看的一个内容。

银河麒麟系统用命令安装动资复印机驱动程序,在驱动程序所在文件夹,鼠标右键点击打开终端,输入屏幕上的命令,注意区分大小写, 这一步是解压驱动的第一低保到系统的指定目录,这里输入系统的用户密码,开始执行安装程序。下面添加打印机到系统, 输入屏幕上的命令, 添加一个名字是幺二三碰的打印机,注意命令,不要输入错误, 注意区分大小写, 这里是复印机的 ip 地址和对联, 这里的文件路径,不要输入错误, 按插件可以补全文件 密码错误三次, 需要重新输入。命令 完成后打印机就添加好了,系统里已经可以看到一百二十三喷打印机可以执行命令,卸载这个打印机, 这样打印机就被删除了。