`
tomhibolu
  • 浏览: 1383209 次
文章分类
社区版块
存档分类
最新评论

Linux驱动修炼之道-SPI驱动框架源码分析(下)

 
阅读更多

努力成为linux kernel hacker的人李万鹏原创作品,为梦而战。转载请标明出处

http://blog.csdn.net/woshixingaaa/article/details/6574224

这篇文档主要介绍spi数据传输过程。

当应用层要向设备传输数据的时候,会通过ioctl向设备驱动发送传输数据的命令。如图,向SPI从设备发送读写命令,实际的读写操作还是调用了主机控制器驱动的数据传输函数。transfer函数用于spi的IO传输。但是,transfer函数一般不会执行真正的传输操作,而是把要传输的内容放到一个队列里,然后调用一种类似底半部的机制进行真正的传输。这是因为,spi总线一般会连多个spi设备,而spi设备间的访问可能会并发。如果直接在transfer函数中实现传输,那么会产生竞态,spi设备互相间会干扰。所以,真正的spi传输与具体的spi控制器的实现有关,spi的框架代码中没有涉及。像spi设备的片选,根据具体设备进行时钟调整等等都在实现传输的代码中被调用。spi的传输命令都是通过结构spi_message定义,设备程序调用transfer函数将spi_message交给spi总线驱动,总线驱动再将message传到底半部排队,实现串行化传输。



在spidev.c中实现了file_operations:

这里看spidev_ioctl的实现:

下面跟踪spidev_message看看:

看spidev_sync的实现:

spi_async在spi.h中定义的:

这里的master->transfer是在spi_bitbang_start中进行赋值的:

bitbang->master->transfer= spi_bitbang_transfer;

看spi_bitbang_transfer的实现:

分析工作队列的处理函数:


这个工作队列的处理函数中调用了spi controller driver中的传输函数:

下面来分析中断函数:

至此spi数据传输过程完成,如果不想为自己的SPI设备写驱动,那么可以用Linux自带的spidev.c提供的驱动程序,只要在登记时,把设备名设置成spidev就可以了。spidev.c会在device目录下自动为每一个匹配的SPI设备创建设备节点,节点名"spi%d"。之后,用户程序可以通过字符型设备的通用接口控制SPI设备。需要注意的是,spidev创建的设备在设备模型中属于虚拟设备,他的class是spidev_class,他的父设备是在boardinfo中定义的spi设备。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics