linux驱动分层分离思想

转:https://blog.csdn.net/zqixiao_09/article/details/51088887

前面我们学习I2C、USB、SD驱动时,有没有发现一个共性,就是在驱动开发时,每个驱动都分层三部分,由上到下分别是:

1、XXX 设备驱动

2、XXX 核心层

3、XXX 主机控制器驱动

而需要我们编写的主要是设备驱动部分,主机控制器驱动部分也有少量编写,二者进行交互主要时由核心层提供的接口来实现;这样结构清晰,大大地有利于我们的驱动开发,这其中就是利用了Linux设备驱动开发中两个重要思想,下面来一一解析

一、设备驱动的分层思想

在面向对象的程序设计中,可以为某一类相似的事物定义一个基类,而具体的事物可以继承这个基类中的函数。如果对于继承的这个事物而言,其某函数的实现与基类一致,那它就可以直接继承基类的函数;相反,它可以重载之。这种面向对象的设计思想极大地提高了代码的可重用能力,是对现实世界事物间关系的一种良好呈现。

Linux内核完全由C语言和汇编语言写成,但是却频繁用到了面向对象的设计思想。在设备驱动方面,往往为同类的设备设计了一个框架,而框架中的核心层则实现了该设备通用的一些功能。同样的,如果具体的设备不想使用核心层的函数,它可以重载之。举个例子:

return_type core_funca(xxx_device * bottom_dev, param1_type param1, param1_type param2)
{
if (bottom_dev->funca)
return bottom_dev->funca(param1, param2);
/* 核心层通用的funca代码 */
...
}
     上述core_funca的实现中,会检查底层设备是否重载了funca(),如果重载了,就调用底层的代码,否则,直接使用通用层的。这样做的好处是,核心层的代码可以处理绝大多数该类设备的funca()对应的功能,只有少数特殊设备需要重新实现funca()。

再看一个例子:

return_type core_funca(xxx_device * bottom_dev, param1_type param1, param1_type param2)
{
/*通用的步骤代码A */
...
bottom_dev->funca_ops1();
/*通用的步骤代码B */
...
bottom_dev->funca_ops2();
/*通用的步骤代码C */
...
bottom_dev->funca_ops3();
}
    上述代码假定为了实现funca(),对于同类设备而言,操作流程一致,都要经过“通用代码A、底层ops1、通用代码B、底层ops2、通用代码C、底层ops3”这几步,分层设计明显带来的好处是,对于通用代码A、B、C,具体的底层驱动不需要再实现,而仅仅只关心其底层的操作ops1、ops2、ops3。图1明确反映了设备驱动的核心层与具体设备驱动的关系,实际上,这种分层可能只有2层(图1的a),也可能是多层的(图1的b)。

这样的分层化设计在Linux的input、RTC、MTD、I2 C、SPI、TTY、USB等诸多设备驱动类型中屡见不鲜。

二、主机驱动和外设驱动分离思想

主机、外设驱动分离的意义

在Linux设备驱动框架的设计中,除了有分层设计实现以外,还有分隔的思想。举一个简单的例子,假设我们要通过SPI总线访问某外设,在这个访问过程中,要通过操作CPU XXX上的SPI控制器的寄存器来达到访问SPI外设YYY的目的,最简单的方法是:

return_type xxx_write_spi_yyy(...)
{
xxx_write_spi_host_ctrl_reg(ctrl);
xxx_ write_spi_host_data_reg(buf);
while(!(xxx_spi_host_status_reg()&SPI_DATA_TRANSFER_DONE));
...
}
     如果按照这种方式来设计驱动,结果是对于任何一个SPI外设来讲,它的驱动代码都是CPU相关的。也就是说,当然用在CPU XXX上的时候,它访问XXX的SPI主机控制寄存器,当用在XXX1的时候,它访问XXX1的SPI主机控制寄存器:

return_type xxx1_write_spi_yyy(...)
{
xxx1_write_spi_host_ctrl_reg(ctrl);
xxx1_ write_spi_host_data_reg(buf);
while(!(xxx1_spi_host_status_reg()&SPI_DATA_TRANSFER_DONE));
...
}
      这显然是不能接受的,因为这意味着外设YYY用在不同的CPU XXX和XXX1上的时候需要不同的驱动。那么,我们可以用如图的思想对主机控制器驱动和外设驱动进行分离。这样的结构是,外设a、b、c的驱动与主机控制器A、B、C的驱动不相关,主机控制器驱动不关心外设,而外设驱动也不关心主机,外设只是访问核心层的通用的API进行数据传输,主机和外设之间可以进行任意的组合。

如果我们不进行上图的主机和外设分离,外设a、b、c和主机A、B、C进行组合的时候,需要9个不同的驱动。设想一共有m个主机控制器,n个外设,分离的结果是需要m+n个驱动,不分离则需要m*n个驱动。

Linux SPI、I2C、USB、ASoC(ALSA SoC)等子系统都典型地利用了这种分离的设计思想。

---------------------
作者:zqixiao_09
来源:CSDN
原文:https://blog.csdn.net/zqixiao_09/article/details/51088887
版权声明:本文为博主原创文章,转载请附上博文链接!

原文地址:https://www.cnblogs.com/newjiang/p/9844960.html

时间: 2024-10-19 23:54:25

linux驱动分层分离思想的相关文章

linux驱动的分离分层概念

bus_drv_dev模型:功能改写只需改dev硬件代码即可,drv不需改写. LED例子 下面用一个点亮LED的例子来说明这个分离的的例子: led_dev.c  定义这个平台设备的资源: static struct resource led_resource[] = {  [0] = { .start  = 0x56000010, //GPFCON的物理地址  .end    = 0x56000010 + 8 - 1,   .flags  = IORESOURCE_MEM, },  [1] 

Linux-3.5-Exynos4412驱动分层分离

linux-3.5/Documentation/driver-model/bus.txt 先写一个简单的例子,是为了给学习platform做准备. dev.h 1 #ifndef JASON_DEV_H_ 2 #define JASON_DEV_H_ 3 4 #include <linux/device.h> 5 6 struct pridevice { 7 struct device device; 8 char *name; 9 }; 10 11 12 #endif 1 #include

linux驱动之i2c子系统device注册driver注册简单分析

Linux 驱动设计主要是根据分层分离思想,i2c子系统分为i2cocre.adapter.及device_driver层,其实adapter也是个device,只不过是我们主控芯片的I2C控制接口而已,我们的主控芯片有几个I2C接口就有几个adapter; i2ccore这一层linux已经帮我们实现,主要的工做是类似platform总线的作用,负责drvier及设备的注册,相比platform多了个adapter的注册管理工作,以及i2c的数据发送接收等等算法,说算法有点夸大,其实就是按照i

Linux驱动之平台设备驱动模型简析(驱动分离分层概念的建立)

Linux设备模型的目的:为内核建立一个统一的设备模型,从而有一个对系统结构的一般性抽象描述.换句话说,Linux设备模型提取了设备操作的共同属性,进行抽象,并将这部分共同的属性在内核中实现,而为需要新添加设备或驱动提供一般性的统一接口,这使得驱动程序的开发变得更简单了,而程序员只需要去学习接口就行了. 对于整个设备总线驱动模型的样子,如下图.简单来说,bus 负责维护注册进来的devcie 与 driver,每注册进来一个device 或者 driver 都会调用 Bus->match 函数

驱动编程思想之初体验 --------------- 嵌入式linux驱动开发之点亮LED

这节我们就开始开始进行实战啦!这里顺便说一下啊,出来做开发的基础很重要啊,基础不好,迟早是要恶补的.个人深刻觉得像这种嵌入式的开发对C语言和微机接口与原理是非常依赖的,必须要有深厚的基础才能hold的住,不然真像一些人说的,学了一年嵌入式感觉还没找到门. 不能再扯了,涉及到linux的驱动开发知识面灰常广,再扯文章就会变得灰常长.首先还是回到led驱动的本身上,自从linux被移植到arm上后,做驱动开发的硬件知识要求有所降低,很多都回归到了软件上,这是系统编程的一大特点,当然 ,也不排除有很多

嵌入式linux驱动开发之点亮led未遂(驱动编程思想之初体验)

有了上两篇文章的基础,我们就可以开始开始进行实战啦!这里顺便说一下啊,出来做开发的基础很重要啊,基础不好,迟早是要恶补的.个人深刻觉得像这种嵌入式的开发对C语言和微机接口与原理是非常依赖的,必须要有深厚的基础才能hold的住,不然真像一些人说的,学了一年嵌入式感觉还没找到门. 另外实践很重要,一年多以前就知道了arm,那时整天用单片机的思维去yy着arm,直到前段时间弄来一块arm板,烧上linux系统后才知道,坑呀!根本不是那回事,所以实践是学习计算机类最重要的基本素质,如果整天看书,那基本上

linux驱动(九)platform驱动模型详解,以及基于platform驱动模型的led驱动

参考: http://blog.csdn.net/qq_28992301/article/details/52385518 http://blog.csdn.net/zoe6553/article/details/6372445 http://blog.chinaunix.net/uid-25014876-id-111745.html 1:什么是platform总线?platform总线是区别于实体总线USB. I2C.SPI .PIC总线的虚拟总线,一些usb设备选址的话需要通过USB总线来进

14.linux-platform机制实现驱动层分离(详解)

版权声明:本文为博主原创文章,未经博主允许不得转载. 本节目标:        学习platform机制,如何实现驱动层分离 1.先来看看我们之前分析输入子系统的分层概念,如下图所示: 如上图所示,分层就是将一个复杂的工作分成了4层, 分而做之,降低难度,每一层专注于自己的事情, 系统只将其中的核心层和事件处理层写好了,所以我们只需要来写驱动层即可,接下来我们来分析platform机制以及分离概念 2.分离概念 优点: 将所有设备挂接到一个虚拟的总线上,方便sysfs节点和设备电源的管理 使得驱

Linux驱动修炼之道-SPI驱动框架源码分析(上)【转】

转自:http://blog.csdn.net/lanmanck/article/details/6895318 SPI驱动架构,以前用过,不过没这个详细,跟各位一起分享: 来自:http://blog.csdn.net/woshixingaaa/article/details/6574215 SPI协议是一种同步的串行数据连接标准,由摩托罗拉公司命名,可工作于全双工模式.相关通讯设备可工作于m/s模式.主设备发起数据帧,允许多个从设备的存在.每个从设备 有独立的片选信号,SPI一般来说是四线串