自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

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

原创 Linux V4L2驱动框架分析之(四):sensor驱动

为了实现代码的重用,sensor驱动只需实现各种设备控制方法供上层调用并注册v4l2_subdev,而无需关心video_device和v4l2_dev。struct v4l2_subdev结构体定义如下:struct v4l2_subdev { ...... struct list_head list; //用于挂入v4l2_dev的subdevs链表 struct module *owner; bool owner_v4l2_dev; u32 flags; struct v4l2_

2021-04-05 19:25:49 5258 3

原创 Linux V4L2驱动框架分析之(三):v4l2设备的缓存管理

v4l2设备读取数据的方式有两种,一种是read方式,一种是streaming方式。read方式很容易理解,就是通过read函数读取,而streaming方式是在内核空间中维护一个缓存队列,然后将内存映射到用户空间,应用读取图像数据就是一个不断地出队列和入队列的过程,如下图所示:使用streaming方式,需要管理多块缓冲,内核通过vb2_queue来管理,vb2_queue即缓冲队列。应用程序查询设备功能,判断设备是否支持streaming方式:if (ioctl(fd, VIDIOC_QUERY

2021-04-05 19:24:45 4863 4

原创 Linux V4L2驱动框架分析之(二):平台v4l2设备驱动

平台V4L2设备驱动的工作:根据平台自身的特性实现与平台相关的V4L2驱动部分,最主要的是包括设置并注册video_device和v4l2_device。来看看v4l2_device结构体,定义如下:struct v4l2_device { struct device *dev; ...... //subdevs链表,属于该v4l2_device的子设备会挂入到该链表 struct list_head subdevs; spinlock_t lock; //v4l2_device

2021-04-05 19:23:08 2906

原创 Linux V4L2驱动框架分析之(一):架构介绍

V4L2是video for Linux 2的缩写,是一套Linux内核视频设备的驱动框架,为上层的访问底层的视频设备提供了统一的接口。V4L2支持多种类型设备:视频输入输出设备、VBI设备和radio设备等,分别会在/dev目录下产生videoX、radioX和vbiX设备节点等。我们常见的视频输入设备主要是摄像头,也是本文主要分析对象。V4L2的框架V4L2的框架如下图所示:主要包括以下四个部分:(1) 字符设备驱动程序核心:V4L2本身就是一个字符设备,具有字符设备所有的特性,暴露接口给用

2021-04-05 19:22:25 4514 1

原创 Linux ALSA驱动框架分析之(三):Control逻辑设备的创建

Control接口Control接口主要让用户空间的应用程序可以访问和控制音频codec芯片中的多路开关,滑动控件等,进行音量控制、静音等。在ALSA中,control用snd_kcontrol结构体描述。创建一个新的control至少需要实现 snd_kcontrol_new中的info、get和put这3个成员函数,snd_kcontrol_new结构体的定义如下:struct snd_kcontrol_new { /* 控制类型,如: SNDRV_CTL_ELEM_IFACE_

2021-04-03 00:42:07 1820 2

原创 Linux ALSA驱动框架分析之(二):pcm逻辑设备的创建

pcm设备的主要功能就是:playback,把用户空间的应用程序发过来的PCM数据进行D/A转换,转化为人耳可以辨别的模拟音频。capture,把麦克风或者其他输入源的模拟信号进行A/D转换,把模拟的声音信号转变CPU能够处理的数字信号。声卡可以包含多个pcm设备。一个pcm实例由一个playback stream和一个capture stream组成,这两个stream又分别有一个或多个substreams组成。snd_pcm结构体描述一个pcm设备,定义如下:struct snd_pcm

2021-04-03 00:40:08 1537 1

原创 Linux ALSA驱动框架分析之(一):架构介绍

音频相关概念声音的采样我们知道在现实生活中,人耳听到的声音是模拟信号,PCM就是要把声音从模拟转换成数字信号的一种技术,他的原理简单地说就是利用一个固定的频率对模拟信号进行采样,采样后的信号在波形上看就像一串连续的幅值不一的脉冲,把这些脉冲的幅值按一定的精度进行量化,量化之后就行进行编码。PCM(Pulse Code Modulation)即脉冲编码调制。在PCM过程中,将输入的模拟信号进行采样、量化和编码,PCM信号的两个重要指标是采样频率和量化精度。衡量量化的指标就是采样位数(深度):即指描述数

2021-04-03 00:37:44 2452

原创 Linux设备模型分析之(五):uevent

uevent是kobject的一部分,用于在kobject状态发生改变时,例如增加、移除等,通知用户空间程序。用户空间程序收到这样的事件后,会做相应的处理。该机制通常是用来支持热拔插设备的,例如鼠标插入后,鼠标相关的驱动软件会动态创建用于表示该鼠标的device结构(相应的也包括其中的kobject),并告知用户空间程序,为该鼠标动态的创建设备节点。uevent的机制是比较简单的,设备模型中任何设备有事件需要上报时,调用uevent提供的接口。uevent模块准备好上报事件的格式后,可以通过两个途径把

2021-03-22 21:21:32 859

原创 Linux设备模型分析之(四):class

class,它主要是集合具有相似功能或属性的设备,这样就可以抽象出一套可以在多个设备之间共用的数据结构和接口函数。设备驱动一般会调用class_create函数创建一个class,然后再class下创建设备,这样的话,就可以自动的创建设备文件了。class结构体的定义如下:struct class { //class的名称,会在“/sys/class/”目录下体现 const char *name; struct module *owner; //该class的默认attrib

2021-03-22 21:18:39 473

原创 Linux设备模型分析之(三):sysfs

sysfs是一个基于RAM的文件系统,它和kobject一起,可以将kernel的数据结构导出到用户空间,以文件目录结构的形式,提供对这些数据结构(以及数据结构的属性)的访问支持。sysfs目录前面提到过,一个kobject,对应sysfs中的一个目录。因此在注册kobject添加到kernel时,会调用sysfs文件系统的创建目录接口,创建与kobject对应的目录:创建sysfs目录,实际上就是创建kobject对应的sysfs目录项,并与父kobject的sysfs目录项建立关系。在系统中

2021-03-22 21:16:44 1085

原创 Linux设备模型分析之(二):设备模型的基石

Linux设备模型通过sysfs文件系统将设备、驱动、总线组织成拓扑结构以目录结构进行展示与管理以及与用户空间通信,如下图:这些功能的实现离不开设备模型的基石:kobject。kobject是组成设备模型的基本结构,device、bus、device_driver等数据结构体里面都直接或间接包含有kobject成员。//设备struct device { ...... struct kobject kobj; ......};//驱动struct device_driver { ..

2021-03-22 21:13:43 466

原创 Linux设备模型分析之(一):设备模型核心

设备模型其实是Linux内核为了管理硬件上的设备和对应的驱动制定的一套软件体系。Linux设备模型的核心是使用bus、class、device、driver四个核心数据结构,将大量的、不同功能的硬件设备以及驱动,以树状结构的形式,进行归纳、抽象,从而方便内核的统一管理。用device和driver两个数据结构,分别从“有什么用”和“怎么用”两个角度描述硬件设备。bus,即总线,如下图:SoC系统中有spi,i2c,usb等实体总线用于外设的连接,而针对集成在SoC中的外设控制器,Linux内核提供

2021-03-22 21:11:43 771

原创 Linux中断子系统分析之(四):驱动程序申请中断

中断子系统中有一个重要的设计机制,那就是Top-half和Bottom-half,将紧急的工作放置在Top-half中来处理,而将耗时的工作放置在Bottom-half中来处理。如果中断不分上下半部处理,那么意味着只有等上一个中断完成处理后才会打开中断,下一个中断才能得到响应。当某个中断处理处理时间较长时,很有可能就会造成其他中断丢失而无法响应,影响系统性能。中断分成上下半部处理可以提高中断的响应能力,在上半部处理完成后便将中断打开,这样就可以响应其他中断了,等到中断退出的时候再进行下半部的处理。为了进

2021-03-18 18:19:26 805

原创 Linux中断子系统分析之(三):irq domain

irq domain的作用前面也要提到过,来张图:irq domain结构体的定义如下所示:/* include/linux/irqdomain.h */struct irq_domain { /* 系统中的irq_domain都会挂入全局链表irq_domain_list,link就是挂入该链表的节点 */ struct list_head link; //IRQ domain的name const char *name; //irq_domain操作集

2021-03-18 18:19:00 2201

原创 Linux中断子系统分析之(二):通用的中断处理

当有外部中断发生时,硬件会根据异常向量表,找到中断的入口地址,开始调用由操作系统提供的通用中断处理函数。而系统初始化阶段的异常向量表的设置、执行中断服务例程前后的上下文保护与恢复等等,这部分是CPU架构相关代码。通用中断处理函数,核心是围绕着struct irq_desc来展开。在linux kernel中,对于每一个外设的中断都用struct irq_desc来描述,我们称之中断描述符,保存了中断的相关信息,如硬/软件中断号、中断服务例程等。struct irq_desc结构体定义如下:struc

2021-03-18 18:18:31 1079

原创 Linux中断子系统分析之(一):整体架构

中断的硬件框架处理器一般只有两根左右的中断引脚,而管理的外设却很多。为了解决这个问题,现代设备的中断信号线并不是与处理器直接相连,而是与一个称为中断控制器的设备相连接,后者才跟处理器的中断引脚直接连接。一个中断硬件组成架构的示例,如下图:中断控制器有的是支持多个CPU,如ARM的GIC、x86的APIC,有的不支持。在庞大复杂的硬件系统中,外设很多,硬件系统中可能就不止一个中断控制器了,中断控制器可以级联。一个中断级联的硬件框架示例,如下图:Linux的中断子系统的软件框架图如下所示:最上面

2021-03-18 18:18:00 997

原创 Linux 块设备驱动分析(三)

块设备驱动Linux 块设备驱动分析(一)Linux 块设备驱动分析(二)在块设备的注册和初始化阶段,与字符设备驱动类似,需要申请设备号, 完成这个任务的函数是register_blkdev,其原型为:/* major参数是块设备要使用的主设备号,name为设备名, 如果major为0,内核会自动分配一个新的主设备号,函数返回主设备号 */int register_blkdev(unsigned int major, const char *name);除此之外,在块设备驱动初始化过程

2021-03-14 23:24:03 308

原创 Linux 块设备驱动分析(二)

Linux 块设备驱动分析(一)块IO请求的处理过程页高速缓存(page cache)是Linux内核实现磁盘缓存,它主要用来减少对磁盘的I/O操作。具体地讲,是通过把磁盘中的数据缓存到物理内存中,把对磁盘的访问变为对物理内存的访问。如读取一个文件,首先会先检查你读的那一部分文件数据是否在高速缓存中,如果在,则放弃访问磁盘,而直接从内存中读取,如果不在,则去磁盘中读取。对于写操作,应用如果是以非SYNC方式写的话,写的数据也只是进内存,然后由内核帮忙在适当的时机回写进硬盘。内存的页最终是要转化为硬

2021-03-14 23:23:04 354

原创 Linux 块设备驱动分析(一)

Linux块设备IO子系统框架块设备与字符设备的不同块设备是与字符设备并列的概念,这两类设备在Linux中驱动的结构有较大差异,总体而言,块设备驱动比字符设备驱动要复杂得多,在I/O操作上表现出极大的不同,缓冲、I/O调度、请求队列等都是与块设备驱动相关的概念。系统中能够随机(不需要按顺序)访问固定大小数据片的硬件设备称作块设备,这些固定大小的数据片就称作块。最常见的块设备是硬盘,除此以外,还有软盘驱动器、蓝光光驱和闪存等许多其他块设备。块设备的一般访问方式是通过文件系统。另一种基本的设备类型是字符

2021-03-14 23:22:13 294

原创 pinctrl子系统分析(三)

pinctrl子系统分析(一)pinctrl子系统分析(二)这章讲解配置节点的解析以及pinctrl_state的pinctrl_setting增添,先来个图:create_pinctrl:static struct pinctrl *create_pinctrl(struct device *dev){ struct pinctrl *p; const char *devname; struct pinctrl_maps *maps_node; int i; struct pinct

2021-03-11 15:30:10 622 2

原创 pinctrl子系统分析(二)

pinctrl子系统分析(一)pin控制器驱动pin控制器驱动的主要工作是,枚举pin控制器的信息,如控制器有多少个引脚,支持多少个function,每个function对应几个group,支持多少个group等,建立table保存这些信息,最后调用pin control核心提供的pinctrl_register函数将pin控制器注册进系统。pinctrl_register函数定义如下:struct pinctrl_dev *pinctrl_register(struct pinctrl_desc

2021-03-11 15:29:43 1778

原创 pinctrl子系统分析(一)

pinctrl子系统的软件架构许多SoC的内部都包含了pin控制器,通过pin控制器,我们可以匹配引脚的状态和功能特性。在了解pinctrl子系统之前,我们先来了解一些基本的概念。SoC的很多引脚都可以配置成不同的功能,如A1和A2两个引脚,既可以当作普通的gpio使用,又可以配置为i2c的SCL和SDA,也可以配置为其他功能等等,这称作引脚的复用(简称pinmux)。除此之外,还可以配置引脚的电气属性,如上拉/下拉、输入/输出等,这称作引脚的配置(简称pinconf)。有时需要将多个引脚组合在一起

2021-03-11 15:29:03 1184

原创 通过sysfs操作gpio

在gpio-sysfs.c驱动文件的入口函数:static struct class_attribute gpio_class_attrs[] = { __ATTR(export, 0200, NULL, export_store), __ATTR(unexport, 0200, NULL, unexport_store), __ATTR_NULL,};static struct class gpio_class = { .name = "gpio", .owner = THIS_MOD

2021-03-08 19:44:09 700

原创 GPIO子系统架构分析(二)

gpio libgpio lib(drivers\gpio\gpiolib.c)中提供了一组不依赖于硬件平台的接口函数,理解其中的主要函数非常关键。gpio lib提供的主要函数如下。(1) gpio的设置与gpio值的获取void gpiod_set_value(struct gpio_desc *desc, int value);int gpiod_get_value(const struct gpio_desc *desc);(2) 设置gpio方向的接口int gpiod_direct

2021-03-08 19:43:27 1132

原创 GPIO子系统架构分析(一)

GPIO子系统架构在设备驱动中对GPIO的操作是非常普遍的,linux内核提供了GPIO子系统,方便用户使用,它为用户提供了GPIO的统一操作接口,用户不需要关心底层实现,因为这是芯片厂商需要关心的,芯片厂商会去做这一部分工作。如下图即为GPIO子系统的软件架构。最底层的是gpio控制器。gpio控制器驱动是硬件相关的模组,主要工作是调用gpio lib提供的接口注册驱动。gpio lib模块是一个硬件无关模块,提供了gpio控制器驱动的注册、注销方法,从用户角度给出了操作gpio的接口,这样,各个

2021-03-08 19:42:58 1773

原创 分析一个内核提供的input_handler

对应一些常用的输入设备,如键盘、鼠标等,内核提供的对应的input_handler,用来统一处理这类设备的事件。比如键盘,不管哪种型号的键盘,能上传的事件信息都是一样的,如上传键值’A’、'B’等。本次分析drivers\input\evdev.c,其注册的input_handler支持所有的input_dev。入口函数:/* evdev_handler只设置了driver_info,evbit、keybit等未设置,都为0,从上一章分析 input_attach_handler函数得知,该in

2021-03-07 21:27:05 372

原创 Linux 输入子系统分析(二)

input_dev驱动input_dev驱动程序的工作主要是:申请一些硬件资源,如注册中断等,申请input_dev并设置,然后调用核心层提供的input_register_device函数进行注册。设备有数据时,调用input_event函数向核心层报告事件,如键盘按下,读取按键值,然后上报事件。前面提到input_dev会与input_handler进行匹配,具体怎么匹配呢?调用input_register_device函数注册input_dev时会进行匹配的,该函数定义如下:int input

2021-03-07 21:25:45 134

原创 Linux 输入子系统分析(一)

Linux内核输入子系统输入设备(如按键、键盘、触摸屏、鼠标等)是典型的字符设备,其一般的工作机理是底层在按键、触摸等动作发送时产生一个中断,然后CPU通过USB、I2C等读取键值、坐标等数据,并将它们放入一个缓冲区,字符设备驱动管理该缓冲区,而驱动的read接口让用户可以读取键值、坐标等数据。显然,在这些工作中,只是中断、读键值/坐标值是与设备相关的,而输入事件的缓冲区管理以及字符设备驱动的file_operations接口则对输入设备是通用的。基于此,内核设计了输入子系统,由核心层处理公共的工作。L

2021-03-07 21:23:53 171

原创 Linux spi驱动框架分析(四)

系列文章:Linux spi驱动框架分析(一)Linux spi驱动框架分析(二)Linux spi驱动框架分析(三)spi_master的消息队列机制SPI数据传输可以有两种方式:同步方式和异步方式。所谓同步方式是指数据传输的发起者必须等待本次传输的结束,期间不能做其它事情,用代码来解释就是,调用传输的函数后,直到数据传输完成,函数才会返回。而异步方式则正好相反,数据传输的发起者无需等待传输的结束,数据传输期间还可以做其它事情,用代码来解释就是,调用传输的函数后,函数会立刻返回而不用等待数据传输

2021-03-04 17:01:41 1031 1

原创 Linux spi驱动框架分析(三)

spi_master驱动Linux spi驱动框架分析(一)Linux spi驱动框架分析(二)spi_master驱动负责最底层的数据收发工作,为了完成数据的收发工作,控制器驱动需要完成以下这些功能:申请必要的硬件资源,例如中断,DMA通道,DMA内存缓冲区等等;配置spi控制器的工作模式和参数,使之可以和相应的设备进行正确的数据交换工作;向spi核心层提供接口,使得上层的设备驱动可以通过核心层访问控制器驱动;配合核心层,完成数据消息队列的排队和处理,直到消息队列变空为止;控制器的相关

2021-03-04 17:00:46 1001 1

原创 Linux spi驱动框架分析(二)

spi coreLinux spi驱动框架分析(一)spi核心(dervers/spi/spi.c)中提供了一组不依赖于硬件平台的接口函数,理解其中的主要函数非常关键,因为spi_master驱动和spi设备驱动之间赖于i2c核心作为纽带。spi核心中提供的主要函数如下。(1) 为spi_master驱动提供的接口//分配spi_master结构体struct spi_master *spi_alloc_master(struct device *dev, unsigned size);//注

2021-03-04 16:59:29 1120 1

原创 Linux spi驱动框架分析(一)

Linux下spi的驱动架构如下图:从图中可以观察到spi系统的整个框架,发现跟i2c的框架很十分相似;spi驱动框架主要分为三个部分,spi控制器驱动,spi设备驱动,和spi核心。内核把spi控制器抽象为struct spi_master结构体,设备驱动抽象为spi_driver,spi设备抽象spi_device结构体。spi与i2c内核空间的类比:(1)spi_master就相当于i2c中的i2c_adapter(2)spi_driver即i2c_driver(3)spi_device

2021-03-04 16:58:11 2095 2

原创 通用i2c设备驱动分析

内核提供了一个通用的i2c驱动,这个驱动程序为每个适配器提供了设备文件的功能,下面就简要分析一下这个驱动程序,对应的驱动文件为drivers\i2c\i2c-dev.c。入口函数如下:static int __init i2c_dev_init(void){ int res; printk(KERN_INFO "i2c /dev entries driver\n"); //申请字符设备设备号,主设备号89 res = register_chrdev_region(MKDEV(I2C_MAJ

2021-03-01 19:45:00 509 1

原创 Linux i2c驱动框架分析 (三)

i2c适配器驱动i2c适配器驱动加载与卸载i2c总线驱动模块的加载函数要完成两个工作。初始化i2c适配器所使用的硬件资源,如申请I/O地址、中断号等。初始化好i2c_adapter数据结构的成员,然后通过i2c_add_adapter()添加i2c_adapter的数据结构。i2c总线驱动模块的卸载函数要完成的工作与加载函数相反。释放i2c适配器所使用的硬件资源,如释放 I/O地址、中断号等。通过i2c_del_adapter()删除i2c_adapter的数据结构。

2021-03-01 19:44:32 573

原创 Linux i2c驱动框架分析 (二)

i2c corei2c核心(drivers/i2c/i2c-core.c)中提供了一组不依赖于硬件平台的接口函数,理解其中的主要函数非常关键,因为 I2C 总线驱动和设备驱动之间赖于i2c核心作为纽带。i2c核心中提供的主要函数如下。(1)增加/删除i2c_adapterint i2c_add_adapter(struct i2c_adapter *adapter);void i2c_del_adapter(struct i2c_adapter *adap);(2)增加/删除i2c_driv

2021-03-01 19:44:02 2795 1

原创 Linux i2c驱动框架分析 (一)

Linux的i2c体系结构Linux的i2c体系结构分为3个组成部分。(1) i2c核心i2c核心提供了i2c总线驱动和设备驱动的注册、注销方法,i2c通信方法上层的、与具体适配器无关的代码以及探测设备、检测设备地址的上层代码等。(2) i2c总线驱动i2c总线驱动是对i2c硬件体系结构中适配器端的实现。i2c总线驱动主要包含了i2c适配器数据结构i2c_adapter、i2c适配器的i2c_algorithm数据结构和控制i2c适配器产生通信信号的函数。经由i2c总线驱动的代码,我们可以控制

2021-03-01 19:43:23 679

原创 驱动程序中的并发与控制(三)

信号量(semaphore)相对于自旋锁,信号量的最大特点是允许调用它的线程进入睡眠状态。信号量的定义与初始化/* include\linux\semaphore.h */struct semaphore { raw_spinlock_t lock; unsigned int count; struct list_head wait_list;};其中,lock是个自旋锁变量,用于实现对信号量的另一个成员count的原子操作。无符号整型变量count用于表示通过该信号量允许进入临界区

2021-02-27 16:17:12 158

原创 驱动程序中的并发与控制(二)

自旋锁spin_lock说明:Kernel版本:4.9.88设计自旋锁的最初目的是在多处理器系统中提供对共享数据的保护,其名称来源于它的工作方式。为了获得一个自旋锁,在某CPU上运行的代码需先执行一个原子操作,该操作测试并设置某个内存变量。由于它是原子操作,所以在该操作完成之前其他执行单元不可能访问这个内存变量。如果测试结果表明锁已经空闲,则程序获得这个自旋锁并继续执行;如果测试结果表明锁仍被占用,程序将在一个小的循环内重复这个“测试并设置”操作,即进行所谓的“自旋”。不同的处理器上有不同的指令用

2021-02-27 16:16:15 139

原创 驱动程序中的并发与控制(一)

并发与竟态并发指的是多个执行单元同时、并行被执行,而并发的执行单元对共享资源(硬件资源和软件上的全局变量、静态变量等)的访问则很容易导致竞态。在Linux内核中,主要的竞态发生于如下几种情况。对称多处理器(SMP)的多个CPUSMP是一种紧耦合、共享存储的系统模型,其体系结构如下图所示,它的特点是多个CPU使用共同的系统总线,因此可访问共同的外设和储存器。在SMP的情况下,两个核的竞态可能发生于CPU0的进程与CPU1的进程之间、CPU0的进程与CPU1的中断之间以及CPU0的中断与CPU1

2021-02-27 16:15:14 326

原创 Linux字符设备的设计框架

这里写自定义目录标题欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入 static void __spi_pump_messages(struct spi_master *master, bo

2021-02-24 23:27:51 163

空空如也

空空如也

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

TA关注的人

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