在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)
你的傳輸結束後需要加上這麼一句(不管是否使用中斷和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不為空來進行讀寫操作!否則很容易誤判斷!
Block使用中的一些疑問解答
本文主要是闡述一下block中如何的使用外部變數以及block本身的記憶體管理。先定義乙個block變數,作為後續的例子中使用 typedef void blockcc void blockcc block block中可以直接使用外部的變數,比如 int number 1 block 那麼實際上,...
Block使用中的一些疑問解答
本文主要是闡述一下block中如何的使用外部變數以及block本身的記憶體管理。先定義乙個block變數,作為後續的例子中使用 typedef void blockcc void blockcc block 1 block中引用外部變數 block中可以直接使用外部的變數,比如 int number...
關於HashMap的一些疑問與解答
1.為什麼treeify threshold要是8?treefy是有成本的,新增或刪除元素時有額外的操作,同時treenode是普通node體積的二倍,因而需要乙個平衡點。隨機hashcode下符合泊松分布,0 0.60653066 1 0.30326533 2 0.07581633 3 0.012...