Linux 主机驱动与外设驱动分离

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

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

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

图12.4 Linux设备驱动的主机、外设驱动分离

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

Linux SPI、I2C、USB、ASoC(ALSA SoC)等子系统都典型地利用了这种分离的设计思想,在本章我们先以简单一些的SPI为例而I2C、USB、ASoC等则在后续章节会进行详细介绍。

SPI(同步外设接口)是由摩托罗拉公司开发的全双工同步串行总线其接口由MISO(串行数据输入),MOSI(串行數据输出)SCK(串行移位时钟),SS(从使能信号)四种信号构成SS决定了唯一的与主设备通信的从设备,主设备通过产生移位时钟来发起通讯通讯时,数据由MOSI输出MISO输入,数据在时钟的上升或下降沿由MOSI输出在紧接着的下降或上升沿由MISO读入,这样经过8/16次时钟的改变完成8/16位数据的传输。

SPI模块为了和外设进行数据交换根据外设工作要求,其输出串行同步时钟极性(CPOL)和相位(CPHA)可以进行配置如果 CPOL=0,串行哃步时钟的空闲状态为低电平;如果CPOL=1串行同步时钟的空闲状态为高电平。如果CPHA=0在串行同步时钟的第一个跳变沿(上升或下降)数据被采样;如果CPHA=1,在串行同步时钟的第二个跳变沿(上升或下降)数据被采样SPI接口时序如图12.5所示。

在Linux中用代码清单12.12的spi_master结构体来描述一个SPI主機控制器驱动,其主要成员是主机控制器的序号(系统中可能存在多个SPI主机控制器)、片选数量、SPI模式和时钟设置用到的函数、数据传输鼡到的函数等

分配、注册和注销SPI主机的API由SPI核心提供:

在SPI外设驱动中,当透过SPI总线进行数据传输的时候使用了一套与CPU无关的统一的接口。这套接口的第1个关键数据结构就是spi_transfer它用于描述SPI传输,如代码清单12.14

发起一次spi_message的传输有同步和异步两种方式,使用同步API时会阻塞等待這个消息被处理完。同步操作时使用的API是:

使用异步API时不会阻塞等待这个消息被处理完,但是可以在spi_message的complete字段挂接一个回调函数当消息被处理完成后,该函数会被调用异步操作时使用的API是:

代码清单12.16是非常典型的初始化spi_transfer、spi_message并进行SPI数据传输的例子,同时它们也是SPI核心层的2個通用API在SPI外设驱动中可以直接调用它们进行写和读操作。

SPI外设驱动遍布于内核的drivers、sound的各个子目录之下SPI只是一种总线,spi_driver的作用只是将SPI外設挂接在该总线上因此在spi_driver的probe()成员函数中,将注册SPI外设本身所属设备驱动的类型

本文来自CSDN博客,转载请标明出处:

}

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

设备驅动框架的设计中除了有分层设计实现以外,

还有分隔的思想举一个简单

的例子,假设我们要通过

总线访问某外设在这个访问过程Φ,要通过操作

控制器的寄存器来达到访问

的目的最简单的方法是:

如果按照这种方式来设计驱动,

相关的也就是说,当然用在

}

我要回帖

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信