Chinaunix首页 | 论坛 | 博客
  • 博客访问: 278407
  • 博文数量: 91
  • 博客积分: 2105
  • 博客等级: 大尉
  • 技术积分: 1050
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-14 19:30
文章分类
文章存档

2011年(11)

2010年(64)

2009年(16)

我的朋友

分类: LINUX

2010-04-19 14:25:14

一点理解,不知道是否正确,请指正.

在spidev.c有read write 以及spidev_message函数.分别实现半双工和全双工的功能.

不过最后调用的都是spi控制器驱动的transfer函数.

例如, atmel_spi_transfer() 【drivers\spi\atmel_spi.c 】

那么驱动如何判断应用程序要读还是写呢?

简单,判断tx_buf或者rx_buf是否为空即可!

例如read 的读写流程:

调用顺序:spi_read(spi.h)->spi_sync(spi.c)->spi_async(spi.h)->spi->master->transfer(总线的驱动)

所以,全双工函数实际上是同时给rx_buf何tx_buf赋了值。

有一点需要注意,spi_sync()函数是个阻塞函数,里面有一句话:

if (status == 0) {
        wait_for_completion(&done);
        status = message->status;
}

你的传输结束后需要加上这么一句(不管是否使用中断和dma):

msg->complete(msg->context);

否则spi_sync()就死等,当然内核没有死,不过你也干不了其他事了.

另外,在msg->complete(msg->context);之前,必须置位msg->status=0,否则spi_sync会返回这个状态,就是ioctl的返回值.

另请注意,在应用层,一般会使用ioctl(fd, SPI_IOC_MESSAGE(2), xfer);来进行读写一起的操作.在声明xfer后,必须初始化为0: 

struct spi_ioc_transfer xfer[2]; 

memset(xfer, 0, sizeof xfer); 

这是因为驱动层会判断tx_buf和rx_buf不为空来进行读写操作!否则很容易误判断! 



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

chinaunix网友2011-04-13 16:47:42

学习了,多谢楼主分享哦!也欢迎广大linux爱好者来我的论坛一起讨论arm哦!www.lt-net.cn