0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Linux设备驱动开发中两个重要思想

Q4MP_gh_c472c21 来源:互联网 作者:佚名 2018-04-21 08:35 次阅读

嵌入式Linux设备驱动开发之驱动分层/分离思想

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

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()。

再看一个例子:

copyreturn_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的目的,最简单的方法是:

copyreturn_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)等子系统都典型地利用了这种分离的设计思想。


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 嵌入式
    +关注

    关注

    5068

    文章

    19019

    浏览量

    303275
  • Linux
    +关注

    关注

    87

    文章

    11229

    浏览量

    208927

原文标题:嵌入式Linux设备驱动开发之驱动分层/分离思想

文章出处:【微信号:gh_c472c2199c88,微信公众号:嵌入式微处理器】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Linux驱动开发:字符设备驱动开发理论

    大部分学习者的最终目的就是学习 Linux驱动开发Linux的外设驱动可以分为:字符
    发表于 10-26 09:53 1098次阅读

    Linux设备驱动开发详解

    #《Linux设备驱动开发详解》电子书连载#第5章 Linux文件系统与设备文件系统,由于字符
    发表于 06-06 11:28

    Linux设备驱动程序开发 - Linux设备驱动类型

    的基本思想就是尽量抽取设备特性的共同点,把最复杂的设备驱动架构程序代码交给Linux的内核和驱动
    发表于 04-16 14:31

    嵌入式Linux设备驱动开发思想进阶之驱动分层与驱动分离

    的主要是设备驱动部分,主机控制器驱动部分也有少量编写,二者进行交互主要时由核心层提供的接口来实现;这样结构清晰,大大地有利于我们的驱动开发
    发表于 11-03 10:03

    嵌入式Linux设备驱动开发思想进阶之驱动分层与驱动分离

    的主要是设备驱动部分,主机控制器驱动部分也有少量编写,二者进行交互主要时由核心层提供的接口来实现;这样结构清晰,大大地有利于我们的驱动开发
    发表于 11-07 14:43

    Linux设备驱动开发两个重要思想解析

    嵌入式Linux设备驱动开发思想进阶之驱动分层与驱动
    发表于 02-19 06:40

    Linux设备驱动开发详解》第9章、Linux设备驱动的异步通知与异步IO

    Linux设备驱动开发详解》第9章、Linux设备驱动
    发表于 10-27 11:33 0次下载
    《<b class='flag-5'>Linux</b><b class='flag-5'>设备</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>详解》第9章、<b class='flag-5'>Linux</b><b class='flag-5'>设备</b><b class='flag-5'>驱动</b><b class='flag-5'>中</b>的异步通知与异步IO

    Linux设备驱动开发详解》第8章、Linux设备驱动的阻塞与非阻塞IO

    Linux设备驱动开发详解》第8章、Linux设备驱动
    发表于 10-27 11:35 9次下载
    《<b class='flag-5'>Linux</b><b class='flag-5'>设备</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>详解》第8章、<b class='flag-5'>Linux</b><b class='flag-5'>设备</b><b class='flag-5'>驱动</b><b class='flag-5'>中</b>的阻塞与非阻塞IO

    Linux设备驱动开发详解》第7章、Linux设备驱动的并发控制

    Linux设备驱动开发详解》第7章、Linux设备驱动
    发表于 10-27 11:37 10次下载
    《<b class='flag-5'>Linux</b><b class='flag-5'>设备</b><b class='flag-5'>驱动</b><b class='flag-5'>开发</b>详解》第7章、<b class='flag-5'>Linux</b><b class='flag-5'>设备</b><b class='flag-5'>驱动</b><b class='flag-5'>中</b>的并发控制

    Linux USB总线的两个链表

    USB 总线引出两个首要 的链表,一为 USB 设备链表,一为 USB 驱动链表。
    发表于 04-20 10:33 963次阅读

    Linux设备驱动思想在STM32编程的应用

    这几天看了一下Linux设备驱动,发现这套思想其实也可以用在普通的单片机编程上。这种思想较好的分割了驱动
    发表于 12-31 18:56 4次下载
    <b class='flag-5'>Linux</b><b class='flag-5'>设备</b><b class='flag-5'>驱动</b><b class='flag-5'>思想</b>在STM32编程<b class='flag-5'>中</b>的应用

    Linux设备驱动开发详解

    Linux设备驱动开发详解
    发表于 10-28 11:03 50次下载

    Linux如何比较两个文件的差异?

    Linux 如何比较两个文件的差异?答案是使用 diff 命令。
    的头像 发表于 01-17 17:30 5169次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>中</b>如何比较<b class='flag-5'>两个</b>文件的差异?

    冷链运输两个重要环节

    冷链运输两个重要环节
    的头像 发表于 01-28 17:13 1129次阅读
    冷链运输<b class='flag-5'>中</b>的<b class='flag-5'>两个</b><b class='flag-5'>重要</b>环节

    Linux如何比较两个文件的差异?

    Linux 如何比较两个文件的差异?答案是使用 diff 命令。
    的头像 发表于 01-30 16:04 1.2w次阅读
    <b class='flag-5'>Linux</b><b class='flag-5'>中</b>如何比较<b class='flag-5'>两个</b>文件的差异?