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
版权声明:本文为博主原创文章,转载请附上博文链接!
linux驱动分层分离思想的更多相关文章
- linux驱动的分离分层概念之LED
bus_drv_dev模型:功能改写只需改dev硬件代码即可,drv不需改写. LED例子 下面用一个点亮LED的例子来说明这个分离的的例子: led_dev.c 定义这个平台设备的资源: stat ...
- Linux-3.5-Exynos4412驱动分层分离
linux-3.5/Documentation/driver-model/bus.txt 先写一个简单的例子,是为了给学习platform做准备. dev.h #ifndef JASON_DEV_H_ ...
- Linux设备驱动的软件架构思想
驱动相关:硬件之上的软件层,负责底层硬件与用户程序的交互 设备相关:底层设备的硬件操作 总线:匹配设备和驱动 设备驱动分层的思想:为同一类设备设计一个框架,而框架中的核心层则实现了该设备的一些 ...
- Linux驱动之平台设备驱动模型简析(驱动分离分层概念的建立)
Linux设备模型的目的:为内核建立一个统一的设备模型,从而有一个对系统结构的一般性抽象描述.换句话说,Linux设备模型提取了设备操作的共同属性,进行抽象,并将这部分共同的属性在内核中实现,而为需要 ...
- linux设备驱动的分层设计思想--input子系统及RTC
转自:linux设备驱动的分层设计思想 宋宝华 http://blog.csdn.net/21cnbao/article/details/5615493 1.1 设备驱动核心层和例化 在面向对象的程序 ...
- 【linux】驱动-5-驱动框架分层分离&实战
目录 前言 5. 分离分层 5.1 回顾-设备驱动实现 5.2 分离分层 5.3 设备 5.4 驱动 5.5 系统,模块 5.6 Makefile 参考: 前言 5. 分离分层 本章节记录实现LED驱 ...
- 《linux设备驱动开发详解》笔记——12linux设备驱动的软件架构思想
本章重点讲解思想.思想.思想. 12.1 linux驱动的软件架构 下述三种思想,在linux的spi.iic.usb等复杂驱动里广泛使用.后面几节分别对这些思想进行详细说明. 思想1:驱动与设备分离 ...
- 嵌入式linux驱动开发之点亮led(驱动编程思想之初体验)
这节我们就开始开始进行实战啦!这里顺便说一下啊,出来做开发的基础很重要啊,基础不好,迟早是要恶补的.个人深刻觉得像这种嵌入式的开发对C语言和微机接口与原理是非常依赖的,必须要有深厚的基础才能hold的 ...
- 驱动编程思想之初体验 --------------- 嵌入式linux驱动开发之点亮LED
这节我们就开始开始进行实战啦!这里顺便说一下啊,出来做开发的基础很重要啊,基础不好,迟早是要恶补的.个人深刻觉得像这种嵌入式的开发对C语言和微机接口与原理是非常依赖的,必须要有深厚的基础才能hold的 ...
随机推荐
- redis 分布式,主从同步
redis和memcache比较像的,memcache可以实现服务器的集群,redis肯定也是可以的.下面在一台机,实现redis主从复制. 1,copy一下redis.conf,生成一个从机的配置 ...
- NSTimer的循环引用
在日常开发中想到会引起循环引用的一般比较容易想起的是 1.delegate 2.block 今天要说的就是另外一个,NSTimer 这个比较容易会被忽略掉 简单的说就是创建timer为成员变量的时候t ...
- web前端入坑第五篇:秒懂Vuejs、Angular、React原理和前端发展历史
秒懂Vuejs.Angular.React原理和前端发展历史 2017-04-07 小北哥哥 前端你别闹 今天来说说 "前端发展历史和框架" 「前端程序发展的历史」 「 不学自知, ...
- Android无线测试之—UiAutomator UiObject API介绍五
获取对象属性与属性的判断 1.获取对象属性相关API 返回值 API 说明 Rect getBounds() 获取对象矩形坐标,矩形左上角坐标与右下角坐标 int getChildCount() 获得 ...
- Lisp语言简介
摘自维基百科,原链接为:http://zh.wikipedia.org/zh/LISP 因为Clojure是Lisp的一种的方言,所以我们可以先来了解一下Lisp这个比较小众的编程到底是什么~ --- ...
- sublime text3 插件CTags
1.打开Sublime Text 2/3软件,在Preferences(设置)菜单中打开Package Control(插件管理器)打开菜单后找到install packages,搜索ctags, 回 ...
- pycharm 变量批量重命名
Ctrl + R 替换 Ctrl + Shift + F 全局查找 Ctrl + Shift + R 全局替换
- git +vs2017 操作手册+目前工作流程图
分支名称介绍及命名规则: 测试分支:master 线上稳定分支:master-发布分支 功能分支:命名命名规则:V版本号-开发者姓名-功能名. 紧急修复分支:命名规则:fixbug-版本号-具体问题名 ...
- boost::bind 详解
使用 boost::bind是标准库函数std::bind1st和std::bind2nd的一种泛化形式.其可以支持函数对象.函数.函数指针.成员函数指针,并且绑定任意参数到某个指定值上或者将输入参数 ...
- text-align:justify 使用参考
对 text-align:justify 不大了解的,可以先看这里:从css text-align:justify 谈谈 text-align 文本对齐方式,讲的比较浅显易懂,本篇相对深入些,最好先看 ...