关于spi的半双工读写和全双工读写的一些理解

关于spi的半双工读写和全双工读写的一些理解

在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不为空来进行读写操作!否则很容易误判断! 

猜你喜欢

转载自blog.csdn.net/u013165704/article/details/80950226