2013年(13)
分类: 嵌入式
2013-04-27 15:36:48
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。