自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(39)
  • 收藏
  • 关注

原创 搭建arm64的qemu环境

qemu在调试内核方面还是比较方便、效率的。以前基本上多是用arm32的平台,网上大部分资源也是关于arm32的。现在arm64的也比较普遍了,最近刚好要看一些内核的东西,花了2天的时间搭建了这个环境,希望看到的朋友少走弯路,节约点时间。本文主要包含3部分内容:1.安装qemu虚拟机,2.配置网络,3.虚拟机挂载NFS。因为每个人的环境还是有点差异的,搭建的过程中需要根据自己的实际情况做些更改。

2022-10-13 17:13:01 3593 1

原创 Linux驱动模型之Kobjects、kset和ktype

它是驱动模型的骨架,从程序的角度来说,也可以理解为基类。通过sysfs文件系统为整体系统提供一个层级视图。Kobject对于内核的作用是什么?内核事件层:提供一个基于object的内核到用户层的通知系统,本质上它是通过netlink来实现的。

2022-09-15 17:55:11 433

原创 Linux驱动模型之注册驱动

bus就是我们这个驱动将要挂载到的总线(在device结构体中也有这个成员,它是bus 、dev、drv三个形成关联的桥梁),而of_match_table和probe就是我们经常在驱动中需要填充的内容。到这里之后,就和注册设备时类似,先将drv和dev进行匹配,如果匹配成功就调用驱动中的的probe()回调函数。在这个函数有4个主要的步骤,其它步骤2中是将驱动添加到bus维护的驱动链表上,步骤4对驱动和设备进行关联,并调用probe函数。驱动的注册相对设备的注册来说,过程会简单很多。...

2022-08-19 22:18:03 688

原创 Linux驱动模型之注册设备

这个结构体有点大,删除了部分内容,可以浏览下它大概的成员。现在只需要关注struct bus_type *bus这个成员。设备的话我们关心几个点:1.设备是怎么添加到总线管理的设备链表上的?2.注册设备后,它是怎么和驱动匹配,并最终调用驱动中的probe()函数的?3.其实还有跟sysfs、event相关的一些内容,也很重要,后面再说吧。...

2022-08-19 22:12:51 953

原创 Linux驱动模型之总线

在linux中有很多总线,其中有和实体对应的总线,比如:media 总线、spi 总线、i2c总线、hid 输入子系统总线、eMMC 存储设备总线。也有虚拟出来的总线,比如:platform虚拟平台总线。以platform总线为例,它的灵魂是:device(设备)driver(驱动)platform_bus(platform总线),它的特点是设备,驱动分层动态的管理和加载,当我们将设备和驱动注册到虚拟总线上(内核)时,在他们注册时,会互相寻找一次对方。...

2022-08-19 22:04:15 1258

原创 Linux驱动模型概述

设备驱动模型是linux驱动的基石,应该也算一个复杂的东西,怎么来理解它呢?总的来说它包含sysfs、底层的kobject、ktype和kset、和驱动相关的bus、driver、device、class,另外还有uevent事件等。在很多书籍中对这部分的内容基本上都有提及到,但是都是点到为止,没有进行深入的说明。相反,有经验的工程师都知道,其实这部分的内容非常重要,非常重要,非常重要!如果对这部分没有清晰的认识,看再多的驱动代码也是雾里看花。

2022-08-19 21:58:41 434

原创 devm设备资源管理分析

这里只是以clk为例来分析,读者朋友可以自己去看下其它的函数,它们的原理基本上是一样的,比如添加资源第一步调用devres_alloc()来分配队形,第二步是资源自己的相关操作,第三步调用devres_add()函数将资源添加到设备的资源链表上。释放资源时,遍历设备资源管理链表,然后调用资源注册的释放函数。...

2022-07-26 18:14:51 803

原创 devm简介

简单介绍了devm原理、devm的原由和devm的相关函数。

2022-07-26 18:02:55 1911

原创 i2c_check_functionality()函数说明

在i2c驱动的probe()函数一般会调用这个函数,它的作用是什么呢?而它又是怎么实现的呢?

2022-07-15 18:09:45 2632

原创 STM32标准帧和扩展帧的发送

在stm32中标准帧和扩展帧是怎么发送的?它们之间是怎么判断区分的呢?

2021-12-02 17:59:02 5825 4

原创 V4L2之buffer分配和映射

数据结构

2021-11-05 17:44:08 3591

原创 V4L2框架

框架图

2021-11-05 17:42:20 9089 3

原创 V4L2之events

V4L2的event

2021-11-04 17:36:01 3329 1

原创 设备树之节点和属性

设备树概图节点别名节点aliases 的意思是“别名”,因此 aliases 节点的主要功能就是定义别名,定义别名的目的就是为了方便访问节点。有时候引用的节点可读性很差,这个时候就可以定义一个简单的易于理解的名字。在系统的中的定义如下:aliases {serial0 = "/simple-bus@fe000000/serial@llc500";ethernet0 = "/simple-bus@fe000000/ethernet@31c000";};获取节点属性函数:int of_a

2021-09-29 17:35:27 2328

原创 V4L2之mmap()函数

前言我们经常使用mmap函数,它到底是怎么实现的呢?今天就来说说。。。读者朋友是不是有这样的疑问:1.在调用mmap()后,它的返回值到底是什么?又是怎么来的呢?2.我们在驱动中实现static int xxx_drv_mmap(struct file *filp, struct vm_area_struct *vma)的参数为什么是这样的?它跟我们的mmap()函数参数完全不沾边啊。3.在linux底层驱动的实例中是怎么实现的?做了哪些事情呢?函数使用映射#include <sys/

2021-09-18 17:32:04 1696

原创 V4L2之设备注册

前言本文主要讲的是NXP的imx8mm,源码是由NXP提供的,不同的下游厂家的开发板也应该是一样的。引入异步注册的原因在SOC中的视频处理可能由多个IP组成,比如csi_bridge、csi_mipi接口、具体的sensor(ov5640等),甚至更多的IP,这样就导致了V4L2的复杂性。在v4l2中的视频数据流是有方向和顺序的,在linux中引入了异步注册的机制。v4l2的bridge驱动需要在所有的子设备都已经加载后,在初始化所有的子设备。异步注册的核心在于设备树中引入port接口,在子设备中有一

2021-09-17 17:48:27 4111 7

原创 linux基础之链表

前言list在linux内核中使用非常频繁。链表操作定义双向链表结构体struct list_head { struct list_head *prev; struct list_head *next;};初始化一个链表static void INIT_LIST_HEAD(struct list_head *list){ list->next = list; list->prev = list;}在前一个和后一个之间插入一个新的链表项static void __

2021-08-16 17:51:08 486 1

原创 imx8mm启动图标更改

说明imx8mm的启动图标分为3个部分:ubootkernel文件系统uboot图标uboot 不需要更改,uboot启动的时候还没有lcd的驱动。驱动位置:MYIR-i.MX8MM-Uboot/drivers/video/imx/imx8_hdmi.c //系统启动默认的是这个。kernel更改启动图标pngtopnm logo.png > linuxlogo.pnmpnmquant 224 linuxlogo.pnm > linuxlogo224.pnmpnmt

2021-08-12 18:00:31 826

原创 sysfs文件系统分析

sysfs实现的功能为用户空间提供一个层级视图结构。提供统一的引用计数。分别用show和store来提供属性数据的导出导入。可向用户空间发送信号。ps:实现的诀窍就是将kobject和文件目录(directory entries)联系起来。相关的结构体struct kobject { const char *name; //kobject 的名称 struct list_head entry; //连接下一个kobject结构 struct kobject *parent;

2021-07-05 22:20:25 400

原创 linux字符设备驱动之open()函数

疑问:用户的open()函数到驱动的open()函数的过程是怎么样的?为什么传递了struct inode *inode, struct file *filp两个参数?函数调用过程分析在我们的驱动程序中会这样写open()函数static int imxirq_open(struct inode *inode, struct file *filp){ filp->private_data = &imxirq; /* 设置私有数据 */ retu

2021-07-05 22:19:11 3321

原创 linux中的同步机制

内核抢占定义:进程正在执行内核函数时,即它在内核态运行时,允许发生内核切换(即当前进程被新的进程替换)。关键点:不管是抢占内核还是非抢占内核,运行在内核态的进程都可以自动放弃cpu。这种称之为计划性进程切换。比如无法获取到资源而转入睡眠状态。在抢占型内核中,由异步事件引起的进程切换,称之为强制性进程切换。比如中断处理函数唤醒了高优先等级的进程。禁止抢占的条件:如果current_thread_info->tHRead_info->preempt_count的值大于0就禁止抢占。在以下

2021-07-05 22:18:03 391

原创 git生成patch

生成patch的两种方式1.git diff#只想 patch Test.java 文件git diff Test.java > test.patch# 把所有的修改文件打成 patchgit diff > test.patch2.git format-patch$ git format-patch HEAD^ #生成最近的1次commit的patch$ git format-patch HEAD^^ #生成最近的2次commit的patch$ git

2021-07-04 21:53:47 11473

原创 sys文件系统调节lcd背光

sys的位置/sys/class/backlight/lcd_backlight@0cat max_brightness //获取最大的亮度:100cat actual_brightness //获取实际的亮度:80echo 100 > brightness //设置亮度为100echo 80 > brightness //设置亮度为80驱动位置:/drivers/pwm/pwm-imx.c //imx的和cpu相关的pwm操作。/drivers/pwm/core.c/dr

2021-06-24 17:48:02 980

原创 Linux中断之softirq和tasklet

前言为什么要将中断分为上半部和下半部?软中断软中断和中断是非常类似的,它最大的不同的就是使用软件来实现的。数据结构<interrupt.h>struct softirq_action{void (*action)(struct softirq_action *);void *data;};代码分析使用方法tasklet数据结构代码分析使用方法工作队列数据结构代码分析使用方法线程化中断总结它们之间的区别和使用场景...

2021-06-24 17:37:34 187

原创 设备树之创建platform设备

前言在引入设备树机制后,设备的相关信息都用设备树的方式来表示。内核或者驱动通过of系列函数来获取到这些信息。然后在内核中用链表的形式组织起来。相关的结构体属性:struct property { char *name; int length; void *value; struct property *next;

2021-05-28 17:35:21 946 1

原创 linux字符设备注册函数分析

疑问:1.字符设备驱动注册过程中到底发生了什么事情?register_chrdev_region 和 alloc_chrdev_region的区别int register_chrdev_region(dev_t from, unsigned count, const char *name) {... for (n = from; n < to; n = next) { next = MKDEV(MAJOR(n)+1, 0);

2021-05-26 17:57:53 324

原创 STM32生成的执行文件

编译过程中的提示linking...Program Size: Code=40892 RO-data=2456 RW-data=556 ZI-data=15092 FromELF: creating hex file...编译名字含义Code为程序代码部分RO-data 表示 程序定义的常量 const temp;RW-data 表示 已初始化的全局变量ZI-data 表示 未初始化的全局变量Total RO Size (Code + RO Data)Total RW Size

2021-05-24 16:43:05 791

原创 linux之I2C驱动分析

实际上有两部分驱动并且是分层的。I2C主机驱动。2C设备驱动。对于I2C主机驱动,一旦编写完成就不需要再做修改,其他的I2C设备直接调用主机驱动提供的API函数完成读写操作即可。这个正好符合Linux的驱动分离与分层的思想,因此Linux内核也将I2C驱动分为两部分:I2C总线驱动,I2C总线驱动就是SOC的I2C控制器驱动,也叫做I2C适配器驱动。I2C设备驱动,I2C设备驱动就是针对具体的I2C设备而编写的驱动。整体驱动构架理解:方式概述:实际上有两个步骤:client(bor

2021-04-28 17:57:54 1280

原创 Linux系统中的延时

内核延时如果是短延时,比如不超过几毫秒,可以用下面的方式,比如最小1ms;因为软件定时器一般用于长延时。1.下面这三个是忙等待,比较精确include <linux/delay.h> void ndelay(unsigned long nsecs); //纳秒void udelay(unsigned long usecs); //微秒void mdelay(unsigned long msecs); //毫秒2.下面的函数会引起休眠

2021-04-27 17:39:19 2541

原创 linux中的信号

信号信号的作用让一个进程知道某个事件已经发生 让一个进程执行信号处理函数信号基本情况Linux中很多信号,有些信号与体系无关,但是像SIGCHLD或者SIGSTOP这样的信号是与体系结构相关的;另外想SIGSTKFLT这样的一些信号只为特定的体系结构而定义。它们都有默认的操作。0-31为常规信号,32-64为实时信号.它们的区别:常规信号:不进行排队,发送多次也只有一个信号被进程接收到。实时信号:排队,多次发送的每个信号都会被进程接收到。注意:linux系统并不使用实时信号,

2021-04-26 17:51:45 718

原创 linux字符设备驱动

MAJOR(dev_t dev) //从设备号中获取主设备号MINOR(dev_t dev) //从设备号中获取次设备号MKDEV(int major, int minor) //用主设备号和次设备号生成设备号旧版字符设备注册:实际上对申请设备号、申请设备内存、初始化cdev、系统注册步骤的集合。#include <linux/fs.h>register_chrdev(unsigned int major, const char *name,const struct.

2021-04-26 17:46:53 1288

原创 stm32循环buffer数据处理实例

接着上次的《stm32实用循环buffer》,给大家提供一个参考实例,根据实际情况改改就能用。/******************************************************************************* @File : usart2.c* @Author : [email protected]* @Version : V0.0.1* @Date : 20-February-2020* @Brief : This file pr

2020-08-30 11:47:50 1713 3

原创 C++中的构造函数和析构函数

构造函数定义:每个类都分别定义了它的对象呗初始化的方式,类通过一个或者几个特殊的成员函数来控制其对象的初始化过程,这些函数叫做构造函数。在对象建立的时候,就会执行构造函数。特点:构造函数的名字和类名相同。 构造函数没有返回值。 构造函数也有一个参数列表(可能为空)和一个函数体(可能为空)。 类可以有多个构造函数,和其它重载函数类似,不同的构造函数之间必须在参数数量或者类型上有区别。 如果类没有显示的定义构造函数,编译器会自动隐式的定义一个默认构造函数。构造函数方式:默认构造函数。

2020-05-13 17:06:46 593

原创 设备树之pinctrl(itop4412平台)

重要结构步骤:在设备树中添加信息在驱动中调用系统提供的相关的函数可参考官方文档注意:pinctrl子系统不仅仅只是包括gpio,引入pinctrl最大的好处是标准化pin初始化。1 pinctrl子系统提供给驱动的API接口 参考文档:doc "Documentation/driver-api/pinctl.rst"2 使用pinctrl完成初始化的步骤 A:p...

2020-05-08 18:00:06 1316 2

原创 linux内核之Per-CPU变量

最好的同步技术就是把不需要同步的内核放在首位。因为每种显示的同步原语都有不容忽视的开销。本质:Per-cpu变量主要是数据结构的数组,每个cpu对应数组中的一个元素。位置:Per-cpu数组在主存中被排列,以使每个数据结构放在硬件高速缓存中的不同行(参考第二章硬件高速缓存)。这样,对没cpu数组的并发访问不会造成高速缓存行的窃用和实效(这种操作会带来昂贵的系统性能开销)。应用条件:一个cpu不应该访问其它cpu对应的数组元素,另外,它可以随意读或者修改它自己的元素而不担心出现竞争条件。这样也

2020-05-08 17:43:36 2413

原创 设备树简介

设备树起源?device tree 来源于openfirmware,内核中关于设备树的函数都是以of开头。为什么要用设备树?减少储存空间,减少驱动的冗余编码。 实现一套内核对应多套板级设备。环境:设备树增加usb3503A、网卡、nfs的支持编译:设备树被编译后的二进制文件传到内核后,内核有专门的函数解析,处理。语法:遇到括号就是节点,括号里面就是节点的属性1 节点...

2019-12-15 16:18:42 703 1

原创 stm32 rgb多彩led驱动

给大家分享下stm32的rgb多彩led驱动头文件:#ifndef _LED_H#define _LED_H#ifdef __cplusplus extern "C" {#endif#include "includes.h"#define RED 1#define GREEN 2#define BLUE 3#define YELLOW 4#de

2017-08-18 16:56:21 5798 2

原创 stm32实用循环buffer

本人在实际开发中多次用到串口的循环buffer,最开始在网上搜索了相关文章和资料,感觉通用性不是很高。自己也写过fifo,感觉还是过于臃肿。一直想找个完美的循环buffer。在看linux内核代码时,发现内核里面也经常使用fifo。linux内核代码是最优美、精简的,高效的代码。真是“山穷水尽疑无路,柳暗花明又一村”。特意移植除出来,希望对大家有用。代码设计的相当的巧妙~~~头文件

2017-03-05 21:21:33 5807 1

原创 设备树之emmc驱动移植

硬件设备:itop4412开发板 内核版本linux-3.8.1设备树方式减少了设备的冗余编码,同时使移植变得更加高效。eMMC作为开发板的基础,十分重要。设备树用的是内核自带的smdk4412.dtsvim arch/arm/boot/dts/exynos4412-smdk4412.dts在设备树中添加如下代码: 87 ldo22_reg:

2017-03-05 18:35:54 4929

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除