一点理解,不知道是否正确,请指正.
在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) |