應用程序和驅動中使用SPI設備的流程

應用程序和驅動中使用SPI設備的流程

編寫SPI設備驅動有兩種方法。一種是利用系統給我們提供的spidev.c來實現一個spi適配器的設備文件。然後通過在應用層操作spi適配器來控制spi設備。另一種是爲spi設備,獨立編寫一個設備驅動。注意:在後一種情況下,是不需要使用spidev.c的。

前一種方法也就是說只要系統實現了spi適配器的驅動並生成了設備文件, 那麼掛在其上面的spi設備也可以在應用層直接通過操作這個設備文件來間接控制這個spi設備, 這樣就省去了專門爲這個設備編寫驅動的麻煩。本文將詳細描述在應用層和驅動層分別控制spi設備的流程。

關於在應用層如何使用spidev驅動的問題, 可以參考源碼的documenation/spi目錄下的文檔, 其中spidev_test.c就是一個測試程序,可以參考。

下面將結合本人工作中實現的一個例子來介紹應用層使用spidev的流程。實際上流程比較簡單:打開設備文件 -> 配置設備 -> 讀寫設備 -> 關閉設備文件。

1.      打開設備文件:

#defineICCARD_DEVICE_FILE   ("/dev/spidev0.0")      /*spi controller device file*/

/*1.open lcd device*/

fd_iccard= open(ICCARD_DEVICE_FILE, O_WRONLY);

if(fd_iccard< 0) {

           LOGE("can'topen ICCARD device file");

           return0;

         }

跟打開普通的文件沒有什麼區別。

2.      配置設備:

static uint8_ticcard_spi_mode   = SPI_MODE_3;    /*spi operation mode*/

/*2.initialize SPI controller*/

/*

 * spi mode

 */

ret= ioctl(fd_iccard, SPI_IOC_WR_MODE, &iccard_spi_mode);

if (ret< 0) {

           LOGE("can'tset spi mode");

           gotoinit_failed;

}

 

ret =ioctl(fd_iccard, SPI_IOC_RD_MODE, &iccard_spi_mode);

if (ret< 0) {

           LOGE("can'tget spi mode");

           gotoinit_failed;

}

 

/*

 * bits per word

 */

ret =ioctl(fd_iccard, SPI_IOC_WR_BITS_PER_WORD, &iccard_spi_bits);

if (ret< 0) {

           LOGE("can'tset bits per word");

           gotoinit_failed;

}

ret =ioctl(fd_iccard, SPI_IOC_RD_BITS_PER_WORD, &iccard_spi_bits);

if (ret< 0) {

           LOGE("can'tget bits per word");

           gotoinit_failed;

}

 

/*

 * max speed hz

 */

ret =ioctl(fd_iccard, SPI_IOC_WR_MAX_SPEED_HZ, &iccard_spi_speed);

if (ret< 0) {

           LOGE("can'tset max speed hz");

           gotoinit_failed;

}

ret =ioctl(fd_iccard, SPI_IOC_RD_MAX_SPEED_HZ, &iccard_spi_speed);

if (ret< 0) {

           LOGE("can'tget max speed hz");

           gotoinit_failed;

    }

通過ioctl系統調用設置spi的工作模式(4種模式之一, 參考SPI協議),每個傳輸單元的位數,最大工作頻率等。

3.      讀寫設備:

static structspi_ioc_transfer iccard_spi_msg = {  /*spi message for transfer*/

.speed_hz = 2000000,

.bits_per_word = 8,

.delay_usecs = 0,

};   /*每個傳輸必須封裝成這種格式*/

iccard_spi_msg.tx_buf= (unsigned long) NULL;  /*我們的設備只需要讀, 所以沒有tx_buf*/

 

while(index< ICCARD_DATA_LEN)

{

           iccard_spi_msg.rx_buf = (unsignedlong)&ic_data_ptr[index]; /*讀到的數據緩存*/

           iccard_spi_msg.len= 1;  /*每次讀1個字節*/

           ret= ioctl(fd_iccard, SPI_IOC_MESSAGE(1), &iccard_spi_msg);

           if(ret < 0)

           {

                    LOGE("[AARON]read iccard failed");

                    return0;

           }

 

           index++;

      }

同樣的,通過ioctl系統調用,發送SPI_IOC_MESSAGE命令給設備,來讀取或寫入數據。

4.      關閉設備:

close(fd_iccard);

 

如上描述, spidev給開發人員提供了一種比較簡單的操作SPI設備的方式, 開發人員可以不用會編寫spi驅動就能使用spi設備。

 

 

參考:

http://blog.chinaunix.net/uid-25445243-id-4059262.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章