Linux驱动开发
文章平均质量分 65
胡涂涂~
这个作者很懒,什么都没留下…
展开
-
Linux下的网络设备驱动
与字符设备和块设备不同(通过应用层和驱动层指向同一个文件,通过file_operation作为两者之间的桥梁),网络设备并不对应于/dev目录下的文件,应用程序最终使用套接字完成与 网络设备的接口。因而在网络设备身上并不能体现出“一切都是文件”的思想。Linux系统对网络设备驱动定义了4个层次,这4个层次为网络协议接口层、网络设备接口层、提供实际功能的设备驱动功能层和网络设备与媒介层。...原创 2022-08-03 22:06:26 · 3359 阅读 · 0 评论 -
slab为什么要进行染色处理
先说一下结论哈!slab中着色区的作用,是用来避免cache行的地址争用(跟缓存命中率的意思差不多),因为cache是一个固定映射,一次只能映射64k的空间,也就是说,如果两个访存操作(A,B),并不在同一片区(64k)。那么就必须要先让A完成访存操作,再切换cache的映射区间,再完成B的访问操作。然而染色区就是一个地址偏移,让A,B访问的地址位于同一片区间,防止频繁切换带来的效率低下 cache总共就32K,每个缓存行为64个字节,一共512行。为什么说cache行是一个固定映射呢,以内原创 2022-07-10 19:53:55 · 473 阅读 · 0 评论 -
如何查看自己的摄像头是否支持UVC
查看我的摄像头信息确定 USB 摄像头支持 UVC (在 PC 上) 那什么 USB 摄像头适合我们这一章的教程呢,这里有几个关键字:1.支持UVC(免驱), 2.YUV 或者 MJPEG 格式输出。把摄像头插入 PC 机的 USB 接口,查看 ID注:如果你是在 Ubuntu 等 linux操作系统下请看 1~2,在 windows 下请直接看看 3 。1. 在 linux 类操作系统下插入 USB 摄像头,用 dmesg 打印信息#dmesg[134691.269053] usb 1-1:原创 2022-03-24 10:16:10 · 6116 阅读 · 0 评论 -
Linux字符设备驱动应用层与驱动层之间的联系(详解file与inode之间的关系)
文章目录前言正文前言在开始这篇文章的阅读之前我们首先思考几个问题:1、驱动运行在内核层,应用程序运行在应用层,它们之间是如何进行这么一个信息的交互的?2、Linux中一切皆文件,每一个字符设备都是由一个文件来表示的,文件里记录着相关的硬件信息的,应用层是如何根据找到这个文件?并最终实现对该设备的控制?3、每一个设备都有唯一的文件进行表示,如果是同一类型的设备,那么我们需要为每一个设备都写一个驱动么?正文 对于字符设备驱动的讲解,我觉得的从open()函数开始,那逻辑就相当是清原创 2022-03-16 22:41:08 · 1686 阅读 · 1 评论 -
mjpg_streamer的源码学习(详解)
源码阅读顺序mjpg_streamer/mjpg_streamer.c ->int main(int argc, char argv[])mjpg_streamer/plugins/input_uvc.c ->input_init() ->intput_run() *->cam_thread()mjpg-streamer\plugins\out原创 2022-03-14 21:22:19 · 3187 阅读 · 0 评论 -
linux信号量配合共享内存应用分析(详解)
共享内存与信号量共享内存,指的是两个不相关的进程访问同一个逻辑内存,进程可以将同一段物理内存连接到他们自己的地址空间中,所有的进程都可以访问共享内存中的地址。如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访问同一段共享内存的任何其他进程。如果我们不允许两个进程同时对共享内存进行读写操作,光靠共享内存的机制是做不到的。共享内存并未提供同步机制,也就是说,在第一个进程结束对共享内存的写操作之前,并无自动机制可以阻止第二个进程开始对它进行读取,所以我们通常需要用其他的机制来同步对共享内存的访问,例如原创 2022-03-12 15:48:34 · 2136 阅读 · 2 评论 -
linux线程中互斥锁和条件变量的使用(详解)
互斥锁pthread_mutex_t在linux中,互斥锁的出现是为了限制多个线程同时对临界资源区进行访问。通过互斥锁对临界资源区进行保护,只有拥有锁的线程才可以访问临界区,没有的锁的线程如果要访问临界区则需要等到锁的释放后,竞争到锁的拥有权后,才能进入临界区。 但这里会出现一个问题:单纯加锁也会导致一直是一个线程访问临界资源的问题,个别线程竞争力很强,可能会一直占据锁的使用权,导致其他线程的无法进入临界区。 这就需要引入另一个机制 条件变量条件变量pthread_cond_t条件变量被用于线程原创 2022-03-10 20:03:51 · 1748 阅读 · 0 评论 -
linux嵌入式项目之安防监控一(详解)
实现的功能系统运行环境软件配置开发平台: Ubuntu14.04 vs2012 vs2017开发环境: linux3.14.0、uboot2013.01、gcc4.6.4 通信协议: 串口、ZigBee、http协议等 数据库 : sqlite3硬件配置处理器:Cortex-A9(Exynos4412)开发板 (开发板上自带DHT11温湿度传感器,USB摄像头等数据采集装置,所以暂时可以不考虑远端的数据采集,将开发板采集的数据上传的应用层)原创 2022-05-15 22:17:51 · 2543 阅读 · 1 评论 -
linux进程间通信之消息队列底层源码分析(详解)
前言本篇博客所涉及到的linux源码来自linux2.6,通过从应用->底层实现来分析分析整个消息队列是如何搭建的应用层首先我来看看消息队列是如何应用,因为应用层反应的是整个消息队列大概逻辑,有利于我们对于底层代码的理解1、首先什么是消息队列?消息队列,是消息的链接表,存放在内核中。一个消息队列由一个标识符(即ID)来标识。(那我们思绪扩展一下,如果进程创建了很多的消息队列,每一个消息队列都对应着一个标识符。如果我们想通过标识符找到相应队列,那进程中是不是应该要有一个类似于数组的结构将标识符原创 2022-03-06 21:01:34 · 2200 阅读 · 0 评论 -
linux进程间通信之管道通信底层实现源码分析
文章目录前言什么是管道管道是如何实现的底层源码分析前言本文所引用的内核代码,来源于linux0.11什么是管道 进程用户空间是相互独立的,一般而言是不能相互访问的。但很多情况下进程间需要互相通信,来完成系统的某项功能。进程通过与内核及其它进程之间的互相通信来协调它们的行为。管道就是作为进程间的一种通信方式,为啥这种通信方式就做管道呢? 我想这是它的通信特性决定,通俗点来讲,我们来内核中申请一块缓存区,这个缓存区留有两个接口,分别接在两个不同的进程上,这个缓冲区不需要很大,它被设计成为环形的原创 2022-03-03 19:56:37 · 1632 阅读 · 1 评论 -
linux之虚拟文件系统源码分析(详解)
文章目录前言基础知识VFS的数据结构正篇前言 虚拟文件系统是一个很庞大的架构,如果要分析的面面俱到,会显得特别复杂而笨拙,让人看着看着,就不知所云了(当然主要还是笔者太菜),所以这篇博客,以open() 函数为切入点,来试着分析分析VFS文件系统的运转机理,本文的代码来源于 linux3.4.2基础知识首先我们来看一张图 从这张图中,我们可以看出,系统调用函数并不是直接操作真正的文件系统,而是通过一层中间层,也就是我们说的虚拟文件系统,为什么要有虚拟文件原创 2022-02-28 20:50:23 · 2444 阅读 · 0 评论 -
linux之根文件系统
前言1、板卡上电后首先由UBOOT启动初始化板卡,将Linux内核移到内存中运行2、由linux内核自行做了初始化等操作,挂在了第一个应用程序上(根文件系统/linuxrc)3、根文件系统会提供磁盘管理服务,glibc设备节点,配置文件,应用程序shell(Android就是一个Linux多了个文件系统)文件系统的重要组成宏观: 1、标准库,glibc, OpenGL,media,Framework 2、配置文件 /etc/init.d/rcS 想要开机运行什么软件,载入什么画面原创 2022-02-27 08:12:51 · 2233 阅读 · 0 评论 -
Linux的信号底层实现机制(源码详解,奶妈教程)
目录前言信号的机制的底层逻辑前言这里不对基本概念进行讲述,只通过源码分析,linux中信号到底是如何实现的,该文中的函数参考源于linux0.11信号的机制的底层逻辑首先,信号的产生是随机,所以进程是不会专门用一个类似 wait( ) 函数去等待信号的发生,因为在进程运行的整个周期(开始->结束),信号可能根本不会发生。那我们进程是如何接受到信号的呢?注意看在进程描述的结构体里面,有个代表信号的成员 (long signal)变量以及(struct sigaction)结构体,先记住这个变量原创 2022-02-26 18:45:24 · 2406 阅读 · 1 评论 -
几句话讲清,TCP为啥要进行三次握手和四次分手
三次握手为了方便理解,我们给客户端 和 服务器端,赋予两个属性,接受和发送(第一次握手)客户端 : 你吃饭了么(第二次握手)服务器端 : 吃了 (==服务器端听到了客户端的问题,说明客户端发送正常,服务端的接受正常 ==,此时我们并不知道客户端的接受和服务端的发送功能是否正常)(第三次握手)客服端:okk(客服端,知道到了服务端的答案。说明客户端接受正常,服务端的发送正常)所以必须要三次握手,才能确认出服务端和客户端的接受和发送功能是正常的四次分手为了方便理解,我们模拟一段分手情景模拟:原创 2021-12-27 16:58:03 · 1175 阅读 · 0 评论 -
Linux 与 RTOS的主要区别到底是啥?
看了不少博客,浏览量最多的也是详细的介绍了这两种系统,可我对这种操作系统的界限还是很模糊(当然我知道Linux,功能更强大),我想要的答案是,为啥在Linux功能这么强大的情况下,RTOS还能有一席之地,我想这也是他们的主要区别。在经过查阅资料后,我想我得到了答案原创 2021-12-13 09:28:03 · 26306 阅读 · 7 评论 -
Source insight4.0配置成兼容UTF-8 和 GB2312的字符编码
点击进入Eeload As Encoding选择UTF-8 with BOM大功告成!原创 2021-12-11 16:00:54 · 5451 阅读 · 0 评论 -
中断和DMA的区别
1、DMA:是一种无须CPU的参与就可以让外设与系统内存之间进行双向数据传输的硬件机制,使用DMA可以使系统CPU从实际的I/O数据传输过程中摆脱出来,从而大大提高系统的吞吐率中断:是指CPU在执行程序的过程中,出现了某些突发事件时CPU必须暂停执行当前的程序,转去处理突发事件,处理完毕后CPU又返回源程序被中断的位置并继续执行所以中断和DMA的区别就是DMA不需要CPU参与而中断是需要CPU参与的中断注册函数和中断注销函数注册中断:int request_irq(unsigned init ir原创 2021-11-26 15:24:05 · 4072 阅读 · 0 评论 -
Cortex-M3 和 M4 的区别
1 、 更快的图像处理速度,浮点运算能力,M4大约是M3的1.4倍2、M4具有32位乘法累加器MAC3、M4支持SIMD指令集4、M4具有一个专用浮点运算单元FPU5、更高级的电源管理模式,从而带来更好的功率效能...原创 2021-11-23 15:54:27 · 2631 阅读 · 0 评论 -
使用do{ } while(0)的好处
**1 、为了宏展开的时候不会出错。如果直接放在花括号里会出错的**举例来说,假设你需要定义这样一个宏:#define DOSOMETHING() action1(); action2();这个宏的本意是,当执行DOSOMETHING()时,action1(),action2()都会被调用。如果有判断,再执行这个宏的话,如下:if(NULL == pPointer) DOSOMETHING();else ...//这样宏在预处理的时候会直接被展开,放在花括号里,那么实际上写的代码如下原创 2021-11-23 00:43:52 · 114 阅读 · 0 评论 -
Malloc和calloc的区别
一:它们都是动态分配内存,先看看它们的原型:void *malloc( size_t size ); //分配的大小void *calloc( size_t numElements, size_t sizeOfElement ); // 分配元素的个数和每个元素的大小共同点就是:它们返回的是 void * 类型,也就是说如果我们要为int或者其他类型的数据分配空间必须显式强制转换;**不同点是:**用malloc分配存储空间时,必须由我们计算需要的字节数。如果想要分配5个int型的空间,那就是说需要原创 2021-11-23 00:27:21 · 729 阅读 · 0 评论 -
二叉树的中序遍历,前序遍历,后序遍历
前序遍历:按照访问根节点——》左子树——》右子树的方式遍历这棵树,而在访问左子树或者右子树的时候,我们按照同样的方式遍历,直到遍历完整棵树。中序遍历:按照访问左子树——》根节点——》右子树的方式遍历这棵树,而在访问左子树或者右子树的时候按照同样的方式遍历,直到遍历完整棵树后序遍历:按照访问左子树——》右子树——》根节点的方式遍历这棵树,而在访问左子树或者右子树的时候,按照同样的方式遍历前序遍历程序示例class Solution {public: vector<int> res原创 2021-11-19 15:00:41 · 792 阅读 · 0 评论 -
Linux下LCD驱动的详解
看了不少人写的LCD驱动解释,看之前很懵逼,看之后还是很懵逼。都是放一大堆内核代码,我当时就想吐槽,能写就写,写不明白放一大堆代码是啥意思。后来,实在没办法,只能去看内核代码,结果,真香,原来别人放一堆代码是有用的。就很邪门,翻翻内核源码,不用细究,看看大概的框架,突然就悟了,所以如果大家看完我这篇博客后还是不太明白,去翻翻源码吧!前言首先,LCD驱动,linux中本身就包含了,并不需要我们自己去编写,我们要做的只是根据自己的LCD改改参数即可。驱动具体是如何现实的呢?我认为主要分为两个部分,一个部分在原创 2021-11-16 20:12:01 · 5117 阅读 · 2 评论 -
一文给你讲清楚 UART ,IIC ,SPI
基础知识介绍什么是并行通信和串行通信串行通信:串行通信是指利用一条传输线将数据一位位地顺序传送。传输方式:传输一个字节(8个位)的数据时,串口是将8个位排好队,逐个地在1条连接线上传输。特点:通信线路简单,利用电话或电报线就可以实现通信,降低成本,适用于远距离通信,但传输速度慢。并行通信:并行通信是指利用多条传输线将一个数据的各位同时传送。传输方式:传输一个字节(8个位)的数据时,并口是将8个位一字排开,分别在8条连接线上同时传输。特点:传输速度块,适用于短距离通信。所以到这里,我们就应该原创 2021-11-12 22:30:21 · 6372 阅读 · 1 评论 -
c语言的内存分配方式
内存分配方式从静态存储区分配:内存在程序编译的时候就已经分配好,这块内存在程序的整个运行过程中都存在。例如:全局变量,静态局部变量在栈上创建:在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释 放内存。动态内存的生存期由程序员决定,使用非常灵活,但如果在堆原创 2021-11-08 00:34:31 · 731 阅读 · 0 评论 -
makfile中想要同时操作两个目标(使用, ‘与’逻辑)
示例:当我们要同时生成两个 .o 文件时 ,可以用如下的形式# 形式1obj-m := test1.oobj-m := test2.o#形式2obj-m := test1.o & test2.o#形式3obj-m := test1.o test2.o原创 2021-11-07 17:34:26 · 129 阅读 · 0 评论 -
字节对齐的底层原理
CPU访问非对齐的内存时为何需要多次读取再拼接?首先简单说一下何为内存对齐。例如,当cpu需要取4个连续的字节时,若内存起始位置的地址可以被4整除,那么我们称其对齐访问。反之,则为未对齐访问。比如从地址0xf1取4字节就是非对齐(地址)访问。简单的看来,对于一个数据总线宽度为32位的cpu,它一次拥有取出四字节数据的能力,理论上cpu应该是可以从任意的内存地址取四个连续字节的,而且是否对齐硬件的设计是相同的(如果内存和CPU都是字节组织的话,那么内存应当可以返回任意地址开始连续的四字节,CPU处理起转载 2021-11-05 20:21:27 · 409 阅读 · 1 评论 -
二叉树什么时候会退化?
如果一颗二叉树的每个结点只有左子树,或者只有右子树,是不是成一个链表啦。比如在二叉搜索树里面,如果一直从小到大插入元素,就退化成一个链表了。为了防止退化,才需要各种平衡的二叉树。二叉查找树的特点就是左子树的节点值比父亲节点小,而右子树的节点值比父亲节点大,如上图:基于二叉查找树的这种特点,我们在查找某个节点的时候,可以采取类似于二分查找的思想,快速找到某个节点。n 个节点的二叉查找树,正常的情况下,查找的时间复杂度为 O(logn)。之所以说是正常情况下,是因为二叉查找树有可能出现一种极端的情况,原创 2021-11-03 00:39:53 · 1909 阅读 · 0 评论 -
中断下半部的三种机制详解
Linux的上半部分就是中断处理函数,下半部分采用三种机制来实现**上半部:**上半部就是中断处理函数,那些处理过程比较快,不会占用很长时间的处理就可以放在上半部完成。**下半部:**如果中断处理过程比较耗时,那么就将这些比较耗时的代码提出来,交给下半部去执行,这样中断处理函数就会快进快出。因此, Linux 内核将中断分为上半部和下半部的主要目的就是实现中断处理函数的快进快出,那些对时间敏感、执行速度快的操作可以放到中断处理函数中,也就是上半部。剩下的所有工作都可以放到下半部去执行,比如在上半部将数原创 2021-11-03 00:20:18 · 1777 阅读 · 0 评论 -
什么是内核空间,什么是用户空间,两者如何进行通信?
内核空间和用户空间Kernel space 是 Linux 内核的运行空间,也是驱动程序的运行空间所以称为内核空间,User space 是用户程序的运行空间称为用户空间。如何交互?Kernel space 可以执行任意命令,调用系统的一切资源;User space 只能执行简单的运算,不能直接调用系统资源,必须通过系统接口(又称 system call),才能向内核发出指令。示例string str = "user space" ;int x = 5 ;int y = 4 ;y = y +原创 2021-11-01 00:27:26 · 1323 阅读 · 0 评论 -
嵌入式面试问题之uboot启动流程分析
首先整个uboot启动,可以分为两个部分,一部分是由汇编语言编写的arch级初始化,另一部分为c语言编写的板级初始化arch初始化从_start函数入口开始,分别进行:1、关闭中断,设置SVC模式(svc又称为管理模式,在启动过程中,中断环境并没有完全准备好,也就是中断向量表和中断处理函数并没有完成设置,一旦有中断产生,可能会导致预想不到的问题,或者是程序跑飞。因此,在准备好中断环境之前,需要关闭所有中断。)2、禁用MMU、TLB3、初始化一些关键的寄存器,时钟寄存器,看门狗等板级初始化从_m原创 2021-10-31 00:36:20 · 1553 阅读 · 0 评论 -
秋招笔试中,数据输入输出的c++框架(通用版)
从键盘录入多行数据,每行的多个整数作为一个数组形式存储,每行的数据个数不一样(数据一样也用这个,整一个通用的就行)/*输入1 3 7 91 7 5 9或者4 8 7 4 5 1都可以用下面这个*/#include<stdio.h>#include<iostream>#include<vector>#include<string>using namespace std ; //输入多行数组int InputMutiint(原创 2021-10-30 20:39:18 · 169 阅读 · 0 评论 -
Linux驱动开发学习记录二
目录main函数之前的初始化工作main函数之前的初始化工作1、设置栈指针2、初始化static静态和global全局变量,即data段的内容3、将未初始化部分的全局变量赋初值:数值型short, int ,long 等为0 , bool为FALSE , 指针为空(NULL)。..bss段的内容4、全局对象初始化 ,在main之前调用构造函数5、将main函数的参数,argc、argv 等传递给main函数 ,然后才能真正的运行main函数...原创 2021-10-21 19:47:51 · 148 阅读 · 0 评论 -
Linux驱动开发学习记录一
目录如何理解Bootloader如何理解Bootloader1、如果它可以将操作系统内核复制到内存中运行,无论从本地(如Flash)还是通过网络,我们就可以称这段程序为Bootloader2、Bootloader就是这么一段小程序,它在系统上电时开始执行初始化硬件设备,准备好软件环境,最后调用操作系统内核值得一说的是,CPU上电后,会从某个地址开始执行,在嵌入式开发板中我们将ROM 或 Flash等映射到这个地址,Bootlaoder就存放在地址开始处,这样一上电就可以开始执行...原创 2021-09-17 19:04:11 · 171 阅读 · 0 评论