![](https://img-blog.csdnimg.cn/20210922113856325.jpg?x-oss-process=image/resize,m_fixed,h_224,w_224)
驱动
文章平均质量分 76
驱动
Engineers_wzf
android driving engineer_wang
展开
-
内核Kconfig编写
编写内核.config 配置用户自定义宏或者string1、menu “hangsome wzf Configuration”endmenu使用make menuconfig 找到你写的那个目录就会出现这个标签2、configs 后面要定义的宏以及类型可以是string bool 还有默认的值3、sourcesource 类似于include 在这个menu下会出现你source 的目录的configs...原创 2022-05-07 23:20:32 · 406 阅读 · 0 评论 -
驱动——platform驱动ADC
我们再谈一下平台总线。前面讲平台总线是可以让drv和dev实现分离。主要作用是用于平台升级。现在结合设备树来看一下 平台总线的好处。(平台总线是虚拟总线,用于一些ADC,PWM这样的没有实体总线连接(iIC spi…)的一些设备,为了管理这些设备统一虚拟出平台总线来管理)1)首先我们要了解到当我们在设备树文件上写了应该设备后(属于我们的直接定义的设备,可以有2^20个子设备(前面说可以放无限个是错误的)它就会把设备树的信息放在/sys/bus/plaoform/device下(那我要是iic设备应原创 2021-10-06 16:29:14 · 355 阅读 · 1 评论 -
驱动———互斥和同步
这个主要是为了解决竞态的问题。什么是竞态?就是对于同一个数据,由于有很多路径同时访问(这里的同时访问,可能发生在多核处理器的状态,在单核上是指假的同时访问,接下来会讲同时访问的请况)。由于这样多个文件访问读取修改,这样就会造成数据紊乱。从而大概率会使很多路径读写等操作的数据都是不正确的。这在内核这种级别的代码来讲是致命的。为了解决这种问题于是引入了互斥的同步的概念。eg:我在内核中有一个全局变量:i= 5;我正常的的程序是要执行一个i++的操作。那么我实际上执行的指令是三条ldr r1,[ro]原创 2021-10-03 23:20:34 · 172 阅读 · 2 评论 -
设备树编写基础
为什么会有设备树:在linux2.6之前,Linux采用硬编码的方式,把支持的厂商的测试板的信息全部写在内核中。来实现Linux的兼容,这使得内核硬件信息的代码占比越来越大。而对用户来说我只要我的板子的硬件信息。这就导致有很多的代码的冗余我们引入设备树之后,用户可以根据自己的板子,去填写和修改设备硬件信息,做到硬件信息和驱动的分离。我驱动过程中,我们的设备树文件,会被挂载到u_boot的一个内存区域,比如我们之前系统移植的过程中。我们把U-Image 放到41000000把exynos4412-fs原创 2021-09-30 16:54:21 · 501 阅读 · 0 评论 -
驱动中断申请
一、申请中断步骤。在编程过程中,需要定义自己的节点–描述当前设备用的中断号arch/arm/boot/dts/exynos4412-fs4412.dts +51 key_int_node{compatible = “test_key”;interrupt-parent = <&gpx1>;interrupts = <2 4>;};编译设备树文件:make dtbs更新dtbs文件:cp -raf arch/arm/boot/dts/exynos4412原创 2021-09-30 09:14:21 · 205 阅读 · 1 评论 -
驱动———IIC子系统(二)
总结一下编程步骤。我们只需要编写drv的代码即调用层的代码。再调用层做的事情就是,把drv注册到iIC bus里面,然后实现按照iic的总线通信协议,进行数据交互。具体步骤。1)编写设备树文件,根据芯片手册,找到我们的硬件连接在第几组iic总线,以及地址,中断等信息。2)实例化i2c_driver结构体并把它注册到drv总线里面去。注册成功后,匹配完成就会调用i2c_driver结构体的probe方法我们需要在probe方法中:3)申请设备号,以及实现file_operation4)创建设原创 2021-09-29 14:08:28 · 220 阅读 · 0 评论 -
驱动——IIC子系统(一)
IIC子系统和input子系统一样,适用于所有挂载在IIC下与SOC进行通行的。即适用于所有的IIC设备。常见的有Cream mpu6050 等等的一些设备。我们说input子系统里面要完成的事情都是把设备的信息传递给用户。就是input。那对于我们IIC来说它肯定也是有一类的作用,所以才会划分出一类出来。所以IIC子系统它的功能是什么?它要做什么?相对于IIC来说,我们之前就接触过IIC总线协议,IIC总线协议里面做的事情就是让主机和从机进行通信。这是一些IIC传输过程的内容。那我们IIC原创 2021-09-27 16:35:58 · 278 阅读 · 0 评论 -
Linux内核——container_of
在驱动过程中,一直有一个做法,就是通过,我知道的一个结构体的一个成员,那么我就可以拿到整个结构体的数据我们也称为以小博大。就比如字符设备驱动过程中的input_dev input_handler 和evdev_handl 这三个结构体就天天在那博来博去的。乍一想:就是通过,我知道的一个结构体的一个成员,那么我就可以拿到整个结构体的数据。这肯定没问题啊,我都知道一个成员了,那拿到整个结构体的数据这不是易如反掌吗?但是真的让你去操作你会怎么操作???内核是定义一个宏去完成以小博大co原创 2021-09-27 13:55:40 · 104 阅读 · 0 评论 -
高级驱动———驱动详解
虽然我们知道了当我们写一个设备的模块时候,只要指定是字符输入设备,当你模块装载的时候,内核就会自动匹配input.ko event.ko模块,让这个设备模块完成驱动。内核帮我们完成了这些事情2,申请设备号 register_chrdev_region (与内核相关)3,注册字符设备驱动 cdev_alloc cdev_init cdev_add (与内核相关)4,利用udev/mdev机制创建设备文件(节点) class_create, device_create (与内核相关)5,构建原创 2021-09-26 14:37:30 · 345 阅读 · 0 评论 -
高级驱动——(驱动所有按键)
我们用一种更为高级的方法去驱动所有的按键————理论上按键最多可以驱动768个,但是我的板子只有三个按键所以现在只能驱动三个,但是驱动三个和驱动768个都是一样的。首先我们要利用起设备树文件了,如果不用设备树的话,你就得一个一个的去驱动,虽然你可以在一个模块上完成所有的按键驱动,但是要是真的驱动768个按键,那么你估计能写上万行代码。你要跟以前的方法一样,每一个按键都要去实例化设备,然后获取中断,地址,…这些信息,然后再处理这些信息。但是如果你用了设备树,我直接在设备树上写好这些信息,到时候你拿的去用原创 2021-09-24 20:40:48 · 2215 阅读 · 2 评论 -
输入子系统(二)
我们前面讲的好像有点问题:1)我们编写的设备模块,不是再编译的时候和核心层的input.c、调用层的evdev.c结合然后一起编译。正解是,我设备本来就是一个模块,而核心层也是一个模块,调用层也是一个模块。只不过内核在运行的时候就已经把核心层和调用层的资源加载进去在内核里了。当我们的设备模块装载到内核中之后,内核就会调用核心和调用层的模块,组成一个完整的驱动。2)那个set_bit函数也并不是把那个ev_key写到evdev里面去:这个函数是把ev_dev的里面的ev_key的位置一:3)关于eve原创 2021-09-24 15:08:43 · 334 阅读 · 0 评论 -
输入子系统(一)
前面我们引入了分层的概念:我们要驱动一个设备我们只要编写差异化代码:5、硬件信息等等。。。然后其它代码:内核会去帮你做:那我们的内核是怎么帮你做的呢?它怎么知道怎么申请设备号?怎么知道怎么读写信息?等等那1234678这些的操作?其实它在内核会有几个文件帮你做现在事情:在kernel内核中会有drives这个文件,这个文件下就是帮我们内核去编写一个可复用性的代码(其实不是它帮我们编写,是它本来就有这些代码,只不过可以匹配)。在drives下面你可以看到的是很多子系统,像i2c、input、等这些子原创 2021-09-23 20:44:51 · 233 阅读 · 3 评论 -
高级驱动——导学
之前我就说过,驱动代码的过程肯定是那一套,但是稍微有点懂点代码的人或者有点面向对象的思维的人看到这种代码肯定会不爽。第一:我每写一个小小的驱动,只有一个按键的驱动代码量都这么大,要是所有的驱动都这样写那光驱动这一块就可以几十M了,而我们的内核源码才2~3M,(我们的驱动代码以模块的形式,可以直接放在内核中当内核启动之后模块也会加载,也可以在内核加载完成之后,再加载驱动模块到内核中—华为微架构就是利用这种方法)所以肯定会有一种方法去减少我们的代码量。第二:我们的代码有很多事可以复用的,我一开始想的就是把申原创 2021-09-23 11:16:45 · 209 阅读 · 0 评论 -
驱动(一)
一、驱动具体是做什么?我不知道。二、驱动步骤。1)在内核源码的目录下,编写驱动代码,生成.ko文件,并装载或卸载我们写的模块。三、具体实现1)驱动代码驱动代码和我们平常写的代码不一样,他有固定的格式。驱动代码所需的四个部分。1)头文件2)驱动模块装载和卸载入口的声明。3)实现模块装载和卸载函数入口4)GPL申明...原创 2021-09-11 13:38:57 · 2126 阅读 · 0 评论 -
驱动中断编程——IO模型
上一章讲到怎么申请和触发一次中断并且和应用层进行数据的交互。但是我们看到这个中断就跟假的中断一样。申请中断,并设置为双边沿的触发方式。触发了之后我们的中断处理程序就会执行,把值放到我们的数据缓冲区。那我应用层并不知道你什么按啊,我得一直去读你的数据缓冲区的值才能读到的传过来的数据啊。这就很不好,不仅仅让应用程序什么都做不了,而且还一直占着CPU的资源。那么为了处理这种事件我们在驱动中引入了文件IO模型。文件IO模型有四种:1)阻塞2)非阻塞3)多路复用4)异步信号一、阻塞模型阻塞.原创 2021-09-18 21:38:48 · 326 阅读 · 1 评论 -
中断上下文
一、什么是中断上下文中断上下文是指在一次中断处理中,中断处理的过程可以分成两个函数就是在一个中断进程中先处理上文,然后直接返回执行正常程序。然后再通过其它方式去实现下半文。如果遇到中断处理函数中比较费时的操作就利用利用中断上下文。————————————————————————————————————————————————下半文的实现方法1,softirq: 处理比较快,但是内核级别的机制,需要修改整个内核源码,不推荐也不常用2,tasklet: 内部实现实际调用了softirq3, w原创 2021-09-19 19:43:12 · 4230 阅读 · 4 评论 -
字符设备驱动——(应用控制)
上次我们搭了一个驱动的框架,并且使用了文件接口,去控制驱动。但是我们只是搭了一个框架,申明都没有做。一、应用控制内核(与内核实现数据交互)1)交互原理我们将实现在应用层的用户空间去控制内核空间,并且通过内核空间去控制硬件。这就是一个简单的驱动我们将做一个led点灯的实验(学软硬件结合(单片机,嵌入式,物联网),点灯实验就跟helloworld一样,虽然很基础,但是你可以有无数个方法去实现)。我们在创建设备号的时候,的这个函数就为我们提供了一个用文件控制的接口。这个my_opes是一个文件控制原创 2021-09-13 20:44:00 · 193 阅读 · 0 评论 -
驱动——中断编程(申请中断)
一、我们之前学的字符设备的驱动,把设备关于输入输出的设备利用gpio设置成输出模式。但是如果是其它设备就不用这样配置。和裸机驱动一样。只是读取了设备的状态信息,并且利用文件操作结构体和应用程序交互数据。我们还支持中断模式。对设备申请中断。申请中断之后cpu就会监视设备,看是否发生了中断的触发方式。如果发生中断就会跳转到中断处理函数。中断编程流程。前提:像之前一样搭建好框架。申请设备号,申请设备节点。1、在设备树中写入我们要操作的设备在编程过程中,需要定义自己的节点–描述当前设备用的中断号E原创 2021-09-17 11:33:28 · 934 阅读 · 0 评论 -
平台总线(二)
我们前面讲的不是平台总线。只是设备驱动模型。他只是一个利用总线的驱动模型,而平台总线又再这个基础上扩展了一些接口。平台总线里面的总线不需要创建内核已经创建好了(bus/platform)platform:平台1, busplatform_bus:不需要自己创建,开机的时候自动创建struct bus_type platform_bus_type = {.name = “platform”,.dev_groups = platform_dev_groups,.match = platfor原创 2021-09-21 21:52:34 · 138 阅读 · 0 评论 -
平台总线(一)
一、前面说到驱动编程的几种模型。我们已经可以自己手动的写一个简单的驱动设备了。但是,从一开始我就觉得这种写法写的又很乱,然后每写一个设备就要写这么多东西,我们又这么多的设备那不是得占很多的空间。然后我引入了平台总线的概念。平台总线和IIC等其它总线的区别:本质上是一样的,只是根据设备操作的总线类型不一样区分了不同的总线,台总线一般用于无法区分总线类型的那类设备,IIC,SPI总线,因为对应的操作的设备是IIC或SPI的,属于标准总线,所以直接标准化了,方便使用。——————————————————原创 2021-09-20 20:58:15 · 870 阅读 · 0 评论 -
字符驱动(框架搭建)
一、驱动分类1)字符设备驱动:设备对数据的处理是按照字节流的形式进型的,在开发板或者电脑上我们的绝大多数设备都是字符设备。比如串口,lcd,led,iic,ketpid,鼠标等都是按字节处理数据的。2)块设备驱动:设备随数据的处理是按照若干个块进行的。一个块又固定大小,比如512\1024…每次读写都是按块的倍数进行,一般用于存储设备:SD卡硬盘光盘等。3)网络设备驱动:专门针对网络设备的一类驱动。//注意:在入口申请了申明资源就要对应的在exit中释放申明资源,都有对应的。二、字符设备驱动框架原创 2021-09-12 15:37:33 · 581 阅读 · 0 评论 -
字符驱动规范
看到之前的代码,第一反应是什么?这他妈的是什么狗屎。静态变量哪里放的都是,代码乱的根本就没人看。那我们来梳理和规范运行代码。1)面向对象思想我们要定义很多静态变量。但是这些变量都是用来描述我们的设备的运行信息的,比如设备号。。。这时候我们就可以用到面向对象的思想(这里是假的面向对象)用一个结构体来封装这些信息。这样就看起来结构清晰又高级。2)出错处理还有就是我们需要做很多带返回值的函数操作,去申请一些系统资源需。但是如果函数出错,它是直接RETURN的,根本就没有去管申请的资源去做释放,这肯定原创 2021-09-14 14:35:10 · 95 阅读 · 0 评论