Chinaunix首页 | 论坛 | 博客
  • 博客访问: 138886
  • 博文数量: 49
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 182
  • 用 户 组: 普通用户
  • 注册时间: 2013-03-14 13:22
个人简介

Linux的热爱者

文章存档

2014年(7)

2013年(42)

我的朋友

分类: 嵌入式

2013-05-03 11:14:10

原文地址:spi子系统解读 作者:waldmer

spi子系统综述
spi子系统从上到下分为:spi设备驱动层,核心曾和master驱动层。其中master驱动抽象出spi控制器的相关操作,
而spi设备驱动层楚翔出了用户空间api。

platform_device结构中描述了spi控制器的相关资源,同事在板级信息中将会添加spi设备的相关信息。
master驱动将以platform_driver形式体现出来,也就是说在主控制器master和主控制器驱动将挂载到platform总线上。
platform_driver的probe函数中将注册spi_master,同时将会获取在板级信息中添加的spi设备,将该信息转换成spi_device,
然后注册spi_device到spi总线上。spi_drvier结构用于描述spi设备驱动,也将挂载到spi总线上。连同spi_drvier一起注册
的是字符设备,该字符设备将提供5个api给用户空间。通过api,用户控件可以执行半双工读、半双工写和全双工读写。

struct spi_master{};
struct spi_device{};
struct spi_board_info{};
struct spi_driver{};
struct spi_transfer{};
struct spi_message{};

注册spi总线
drivers/spi/spi.c
struct bus_type spi_bus_type = {};


主控制器驱动程序arch/arm/plat-s3c24xx/devs.c
struct platform_device s3c_device_spi0 = {};
定义platform driver  drivers/spi/s3c24xx.c
static struct platform_driver s3c24xx_spi_driver = {};


spi设备驱动 drivers/spi/spidev.c
static struct file_operations spidev_fops = {};
static struct spi_driver spidev_spi = {};

spi_register_driver函数,该函数位于drivers/spi/spidev.c
int spi_register_driver(struct spi_driver *sdrv){}

在spi设备驱动层提供了两种数据传输方式。一种是半双工读访问,read方法提供了半双工写访问。
另一种就是全双工方式,ioctl调用将同时完成数据的传送与发送。

spi_ioc_transfer
在使用ioctl时,用户空间要使用一个数据结构来封装需要传输的数据,该结构为spi_ioc_transfer.而在write系统调用时,
只是简单的从用户空间复制数据过来。该结构中的很多字段将被复制到spi_transfer结构中相应的字段。也就是说一个
spi_ioc_transfer表示一个spi_transfer,用户空间可以定义多个spi_ioc_transfe,最后以数组形式传递给ioctl。

事实上,全双工io和半双工io的执行过程基本一样,只不过ioctl需要一个专用的结构体来封装传输的任务,
接着将该任务转化为对应的spi_transfer,最后交给spidev_sync。

阅读(1026) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~