Linux 设备驱动开发思想 —— 驱动分层与驱动分离

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

1、XXX 设备驱动

2、XXX 核心层

3、XXX 主机控制器驱动

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


一、设备驱动的分层思想

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

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

[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  1. return_type core_funca(xxx_device * bottom_dev, param1_type param1, param1_type param2)  
  2. {  
  3.     if (bottom_dev->funca)  
  4.     return bottom_dev->funca(param1, param2);  
  5.     /* 核心层通用的funca代码 */  
  6.     ...  
  7. }  

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

再看一个例子:

[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  1. return_type core_funca(xxx_device * bottom_dev, param1_type param1, param1_type param2)  
  2. {  
  3.     /*通用的步骤代码A */  
  4.     ...  
  5.     bottom_dev->funca_ops1();  
  6.     /*通用的步骤代码B */  
  7.     ...  
  8.     bottom_dev->funca_ops2();  
  9.     /*通用的步骤代码C */  
  10.     ...  
  11.     bottom_dev->funca_ops3();  
  12. }  

    上述代码假定为了实现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的目的,最简单的方法是:

[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  1. return_type xxx_write_spi_yyy(...)  
  2. {  
  3.     xxx_write_spi_host_ctrl_reg(ctrl);  
  4.     xxx_ write_spi_host_data_reg(buf);  
  5.     while(!(xxx_spi_host_status_reg()&SPI_DATA_TRANSFER_DONE));  
  6.     ...  
  7. }  

     如果按照这种方式来设计驱动,结果是对于任何一个SPI外设来讲,它的驱动代码都是CPU相关的。也就是说,当然用在CPU XXX上的时候,它访问XXX的SPI主机控制寄存器,当用在XXX1的时候,它访问XXX1的SPI主机控制寄存器:

[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  1. return_type xxx1_write_spi_yyy(...)  
  2. {  
  3.     xxx1_write_spi_host_ctrl_reg(ctrl);  
  4.     xxx1_ write_spi_host_data_reg(buf);  
  5.     while(!(xxx1_spi_host_status_reg()&SPI_DATA_TRANSFER_DONE));  
  6.     ...  
  7. }  
      这显然是不能接受的,因为这意味着外设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)等子系统都典型地利用了这种分离的设计思想。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/401921.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

CortexM0开发 —— UART时序分析

通用异步收发传输器(UniversalAsynchronousReceiver/Transmitter),通常称作UART,是一种异步收发传输器。将数据由串行通信与并行通信间作传输转换,作为并行输入成为串行输出的芯片UART是一种通用串行数据总线,用于异步通信。该总线…

CortexM0开发 —— LPC11C14的UART使用方法

LPC1100系列微控制器UART LPC1100系列Cortex-M0微控制器具有一个符合16C550工业标准的异步串行口(UART)。此口同时增加了调制解调器(Modem)接口,DSR、DCD和RI Modem信号是只用于LQFP48和PLCC44封装的管脚配置。 特性…

Linux SD卡驱动开发(一) —— SD 相关基础概念

一.SD/MMC卡基础概念 1.1.什么是MMC卡 MMC:MMC就是MultiMediaCard的缩写,即多媒体卡。它是一种非易失性存储器件,体积小巧(24mm*32mm*1.4mm),容量大,耗电量低,传输速度快,广泛应用于消费类电子产品中。 1.2.什么是SD卡…

Linux SD卡驱动开发(二) —— SD 卡驱动分析HOST篇

回顾一下前面的知识,MMC 子系统范围三个部分: HOST 部分是针对不同主机的驱动程序,这一部是驱动程序工程师需要根据自己的特点平台来完成的。 CORE 部分: 这是整个MMC 的核心存,这部分完成了不同协议和规范的实现,并为…

MVC应用程序显示RealPlayer(rm)视频

本篇博文是演示MVC应用程序显示RealPlayer视频。 客户端能观看到RealPlayer视频,前提条件是需要安装RealPlayer客户端,就是想看Falsh或理WMV视频一样,均要安装客户端或相关插件等。 Insus.NET实现方法,还是在控制器中Render RealP…

Linux从入门到精通系列之PPTP

Linux从入门到精通系列之PPTP今天我们来说下怎么在linux环境下如何搭建PPTP-,PPTP(Point to Point Tunneling Protocol),即点对点隧道协议。该协议是在PPP协议的基础上开发的一种新的增强型安全协议,支持多协议虚拟专用…

Linux SD卡驱动开发(三) —— SD 卡驱动分析CORE篇

废话不多说,直接切进主题: Linux在内核源码的drivers/mmc/core文件夹下为我们的提供了一系列SD卡的接口服务函数。可以查看Makefile如下 可见,core文件夹下有针对总线的服务bus.c,针对主控制器的服务host.c,针对SD卡的…

Python数值计算:一 使用Pylab绘图(1)

Pylab的使用 学习使用Python进行科学计算,然而很难找到简单实用,又循序渐进的例子。正好手边有一本《Matlab可视化大学物理学》,里面的例子非常清晰地解释了Matlab在物理学中的应用。重新使用Python实现这些例子,学习了Python&…

Linux SD卡驱动开发(四) —— SD 控制器之真正的硬件操作

前面对SD卡控制器有了一个基本的介绍。其实SD控制器层更过的意义是为core层提供一种操作SD卡硬件的一种方法,当然不同的控制器对硬件控制的方法不尽相同,但是他们最终都能像core层提交一个统一的封装有操作方法的数据结构,那便是即将闪亮登场…

Linux SD卡驱动开发(五) —— SD 卡驱动分析Core补充篇

Core层中有两个重要函数 mmc_alloc_host 用于构造host,前面已经学习过,这里不再阐述;另一个就是 mmc_add_host,用于注册host 前面探测函数s3cmci_probe,现在就来回顾一下这个函数的作用。先简要的概括一下这个函数的功能&#xff…

navicat连接oracle 报 ORA-12737 set CHS16GBK

2019独角兽企业重金招聘Python工程师标准>>> 1首 先,我们打开“工具”-->"选项"菜单,见到如下界面,依据OCI library(oci.dll) 路径,导航到 navicat oci 目录下,备份里面的文件(通过…

Linux SD卡驱动开发(六) —— SD卡启动过程总体分析

一、工作流程 mmc驱动主要文件包括 drivers/mmc/card/block.c drivers/mmc/card/queue.c drivers/mmc/core/core.c drivers/mmc/core/host.c drivers/mmc/core/ 内核启动时,首先执行core/core.c的mmc_init,注册mmc、sd总线,以及一个host clas…

svn怎么上传文件 — 百度经验无耻推广

2019独角兽企业重金招聘Python工程师标准>>> svn怎么上传文件 — 欢乐地点进去捧场 PS:觉得笔者太无耻,直接在下方评论抨击 转载于:https://my.oschina.net/cenqingbo/blog/212284

apache 重写和虚拟目录配置

要求:假如我请求一个地址:www.lxy.com/news-sport-id123.html转成:www.lxy.com/show.php?catenews&classsport&id123步骤:①首先我们需要在apache中启用rewrite模块打开apache的httpd.conf文件,找到#LoadModu…

JavaScript代码片段

简介:本文收集了我常用的JavaScript代码片段,欢迎提意见! 大灰狼边敲门边说:“小兔子乖乖,把门儿开开!” 小兔子听到后,连忙去开门:“来喽!” 兔妈妈对小兔子喊道&#x…

路由器开发(一)—— 路由器硬件结构及软件体系

一、路由器的硬件构成 路由器主要由以下几个部分组成:输入/输出接口部分、包转发或交换结构部分(switching fabric)、路由计算或处理部分。如图所示 图1 路由器的基本组成 输入端口是物理链路和输入包的进口处。端口通常由线卡提供&#…

路由器开发(二)—— 路由器工作原理

当信息需要在两个网络之间传输时,常用路由器这种互连设备来负责数据的传输。路由器的主要工作是:路径的决定和数据包的转发(从路由器一个接口输入,然后选择合适接口输出);维护路由表。 路由器工作的方式非常…

Android颜色渐变的分隔线(ListView)

2019独角兽企业重金招聘Python工程师标准>>> shape.xml xx <?xml version"1.0" encoding"utf-8"?><shape xmlns:android"http://schemas.android.com/apk/res/android" > <gradient android:startColor&qu…

项目实践中Linux集群的总结和思考

2019独角兽企业重金招聘Python工程师标准>>> 前言&#xff1a;作为一名Linux/unix系统工程师、项目实施工程师&#xff0c;这几年一直在涉及到对外项目&#xff0c;经手过许多小中型网站的架构&#xff0c;F5、LVS及Nginx接触的都比较多&#xff0c;我想一种比较通俗…

路由器基础知识详解

第一章 网络互联 网络的根本目的非常简单&#xff1a;方便人们交换所获得的信息。但是网络的应用需求非常复杂&#xff1a;有的用户希望高带宽&#xff0c;但并不要求很长的传输距离&#xff1b;有的用户要求很长的距离&#xff0c;但对带宽要求很低&#xff1b;有的对网络的…