<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>
"); //-->

博客專(zhuān)欄

EEPW首頁(yè) > 博客 > 嵌入式linux之iMX6ULL驅動(dòng)開(kāi)發(fā) | 通用spi驅動(dòng)之spidev使用總結

嵌入式linux之iMX6ULL驅動(dòng)開(kāi)發(fā) | 通用spi驅動(dòng)之spidev使用總結

發(fā)布人:電子禪石 時(shí)間:2024-02-03 來(lái)源:工程師 發(fā)布文章

因為興趣,業(yè)余時(shí)間把玩下手邊的imax6ul開(kāi)發(fā)板。Linux內核集成了spidev驅動(dòng),

提供了SPI設備的用戶(hù)空間API。支持用于半雙工通信的read和write訪(fǎng)問(wèn)接口以及用于

全雙工通信和I/O配置的ioctl接口。使用時(shí),只需將SPI從設備的compatible屬性值添加

到spidev區動(dòng)的spidev dt ids[]數組中,即可將該SPI從設備創(chuàng )建為spidev設備。

如果不想編寫(xiě)單獨的spi設備驅動(dòng),那么使用linux內核提供的通用spidev設備驅動(dòng)就夠了,

它提供統一的字符設備操作,那么只需要在應用層讀寫(xiě)和控制即可。

spidev驅動(dòng)

spidev是一個(gè)Linux內核驅動(dòng),用于與SPI(串行外設接口)設備進(jìn)行通信。SPI是一種全雙工、

同步的串行通信協(xié)議,常用于連接微控制器和外部設備。spidev驅動(dòng)允許用戶(hù)空間程序通過(guò)

Linux的設備文件接口與SPI設備進(jìn)行通信。用戶(hù)可以通過(guò)打開(kāi)和讀寫(xiě)設備文件來(lái)發(fā)送和

接收SPI數據。spidev驅動(dòng)提供了一組控制IO口和SPI參數的ioctl命令。


同時(shí)Linux內核也集成了SPI測試工具spidev test,用于在用戶(hù)態(tài)對spidev動(dòng)功能進(jìn)行測試

和驗證。


spidev設備驅動(dòng)源碼位置在:linux-imx-4.1.15driversspispidev.c

驅動(dòng)框架框圖:

1706957541784792.png

   

除了使用spidev驅動(dòng)外,當然也可以自己編寫(xiě)SPI驅動(dòng)。


使用現有的spidev驅動(dòng)可以簡(jiǎn)化開(kāi)發(fā)過(guò)程,因為它提供了一組用戶(hù)空間接口,

可以直接在應用程序中使用標準的文件操作函數(如open、read、write和ioctl)

來(lái)操作SPI設備。這種方式適用于大多數應用場(chǎng)景,特別是對于簡(jiǎn)單的SPI設備操作,

可以快速實(shí)現功能。


如果使用自己編寫(xiě)的SPI驅動(dòng)也可以,也不算麻煩,需要在內核中實(shí)現SPI子系統,

包括SPI控制器驅動(dòng)和SPI設備驅動(dòng),最后根據需要實(shí)現個(gè)如字符型設備驅動(dòng)操作接口,

供上層應用使用即可。

應用層使用步驟

用戶(hù)應用層使用spidev驅動(dòng)的步驟如下:


1. 打開(kāi)SPI設備文件:用戶(hù)可以通過(guò)打開(kāi)/dev/spidevX.Y文件來(lái)訪(fǎng)問(wèn)SPI設備,

其中X是SPI控制器的編號,Y是SPI設備的編號。


2. 配置SPI參數:用戶(hù)可以使用ioctl命令SPI_IOC_WR_MODE、

SPI_IOC_WR_BITS_PER_WORD和SPI_IOC_WR_MAX_SPEED_HZ來(lái)設置SPI模式

、數據位數和時(shí)鐘速度等參數。


3. 發(fā)送和接收數據:用戶(hù)可以使用read和write系統調用來(lái)發(fā)送和接收SPI數據。

寫(xiě)入的數據將被傳輸到SPI設備,而從設備讀取的數據將被存儲在用戶(hù)提供的緩沖區中。


4. 關(guān)閉SPI設備文件:當不再需要與SPI設備通信時(shí),用戶(hù)應該關(guān)閉SPI設備文件。


總結起來(lái),spidev驅動(dòng)提供了一種簡(jiǎn)單而靈活的方式來(lái)與SPI設備進(jìn)行通信,

使得用戶(hù)可以輕松地在Linux系統上開(kāi)發(fā)和控制SPI設備。

內核配置

使能spidev用戶(hù)態(tài)驅動(dòng)

1706957938689736.png在生成的config文件中可以看到以下配置生效了。我的是在imx6ul開(kāi)發(fā)板的imx_v7_defconfig的linux內核配置文件中。

CONFIG_SPI=y
CONFIG_SPI_GPIO=y
CONFIG_SPI_IMX=y
CONFIG_SPI_SPIDEV=y
編寫(xiě)設備樹(shù)

&ecspi3 {
        fsl,spi-num-chipselects = <2>;/*cs管腳數配置*/
        cs-gpios = <0>,<&gpio1 20 GPIO_ACTIVE_LOW>;/*cs管腳配置*/
        pinctrl-names = "default";
        pinctrl-0 = <&pinctrl_ecspi3>;
        status = "okay";/* status屬性值為"okay" 表示該節點(diǎn)使能*/
 
	spidev: icm20608@0 {
	compatible = "alientek,icm20608";
        spi-max-frequency = <8000000>;
        reg = <0>;/*spi設備是沒(méi)有設備地址的, 這里是指使用spi控制器的cs-gpios里的第幾個(gè)片選io */
    };
 
	oled: oledsh1106@1 {
	compatible = "yang,oledsh1106";/*重要,會(huì )匹配spidev.c中指定的compatible*/
	spi-cpol;/*配置spi信號模式*/
	spi-cpha;
	spi-max-frequency = < 8000000 >;/* 指定spi設備的最大工作時(shí)鐘 */
    reg = <1>;
    };
};

以上需要注意的是:如果該spi接口下掛載有多個(gè)從設備,

需要設置fsl,spi-num-chipselects = <2>;默認該值為1。還有需要注意的地方是,

cs-gpios 片選信號需要配置對應的個(gè)數。以上的為配置了兩路片選GPIO管腳,

第一個(gè)默認的,第二個(gè)是指定的。如果僅有一個(gè)從設備,可以配置cs-gpio就行了。

注意cs-gpio和cs-gpios的區別,帶s的標識可以有多個(gè)。

如果忽略cs管腳數配置,則會(huì )出現以下錯誤:

需要設置fsl,spi-num-chipselects = <2>; 


注意上面的compatible 屬性,在新版linux內核,可以寫(xiě)任意的字符串,

最好不再寫(xiě)”spidev”,老版的是要寫(xiě)成”spidev”。

給出的理由是: spidev should never be referenced in DT without a specific

 compatible string, it is a Linux implementation thing rather than a description 

of the hardware。


此外還有一些額外配置,以下為自定義屬性,用于指定工作時(shí)序方式及其它功能設置等。

如CPOL需要設1, 則只需在spi設備節點(diǎn)里加上"spi-cpol"屬性即可; CPOL設0,

則不寫(xiě)"spi-cpol"屬性即可 。

  • buswidth = <8>; /* 傳輸以8位為單位 */
    mode = <0>; /* 使用第幾種工作時(shí)序(CPOL, CPHA) */
    /*但在現用的內核源碼里發(fā)現, spi設備的工作時(shí)序并不是用mode屬性值來(lái)指定的*/
    /* 如CPOL需要設1, 則只需在spi設備節點(diǎn)里加上"spi-cpol"屬性即可;
  • CPOL設0,則不寫(xiě)"spi-cpol"屬性即可 */
    /* CPHA設1時(shí),則在設備節點(diǎn)里加上"spi-cpha"屬性即可 */

pinctrl的配置

pinctrl_ecspi3: ecspi3grp {
                fsl,pins = <
                        MX6UL_PAD_UART2_RTS_B__ECSPI3_MISO        0x100b1  /* MISO*/
                        MX6UL_PAD_UART2_CTS_B__ECSPI3_MOSI        0x100b1  /* MOSI*/
                        MX6UL_PAD_UART2_RX_DATA__ECSPI3_SCLK      0x100b1  /* CLK*/
                        MX6UL_PAD_UART2_TX_DATA__GPIO1_IO20       0x100b0  /* CS*/
                    >;
            };
編譯內核和設備樹(shù)
#加載環(huán)境
source /opt/fsl-imx-x11/4.1.15-2.1.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi
#編譯內核
make zImage -j16
#編譯指定的設備樹(shù)
make imx6ull-14x14-nand-4.3-480x272-c.dtb
修改spidev驅動(dòng)

默認的spidev.c中,是沒(méi)有匹配你添加的設備的,因此需要修改spidev.c代碼,增加compatible匹配。

/* The main reason to have this class is to make mdev/udev create the
 * /dev/spidevB.C character device nodes exposing our userspace API.
 * It also simplifies memory management.
 */
 
static struct class *spidev_class;
 
//#ifdef CONFIG_OF
static const struct of_device_id spidev_dt_ids[] = {
	{ .compatible = "rohm,dh2228fv" },
  { .compatible = "yang,oledsh1106" },
	{},
};
MODULE_DEVICE_TABLE(of, spidev_dt_ids);
//#endif

內核編譯成功后,更新內核和設備樹(shù)文件。啟動(dòng)設備后,在/sys/class/spidev下可以確認spidev枚舉出了多少個(gè)spi設備。


設備樹(shù)查看

查看設備樹(shù)是否有新添加的節點(diǎn):


更新設備樹(shù)到板子上后查看下是否有生成spi設備節點(diǎn):

                        


開(kāi)源測試工具

spidev驅動(dòng)有現成的測試工具。其中一個(gè)常用的測試工具是spi_test,

它是spidev驅動(dòng)自帶的測試工具,可以用于測試和調試SPI設備。

spi_test可以通過(guò)命令行參數設置SPI設備的各種參數,如設備文件、

傳輸速率、字節順序等。使用spi_test可以發(fā)送和接收SPI數據,

以驗證spidev驅動(dòng)的功能和性能。


在源碼linux-imx-4.1.15-2.1.0-v2.7\Documentation\spi路徑下,

有兩個(gè)測試工具的源碼文件,spidev_fdx.c和spidev_test.c文件。

可以直接交叉編譯為可執行文件使用。

這些工具都基于spidev通用設備驅動(dòng)以及對應的ioctl命令實(shí)現,

可以方便的用來(lái)對spi的通用型驅動(dòng)來(lái)進(jìn)行測試。


編譯方法

#加載環(huán)境
source /opt/fsl-imx-x11/4.1.15-2.1.0/
environment-setup-cortexa7hf-neon-poky-linux-gnueabi
#編譯
$(CC) spidev_fdx.c -o spidev_fdx
$(CC) spidev_test.c -o spidev_test
回環(huán)測試

首先,將spi接口的MISO和MOSI接口短接。

其次,編譯測試代碼:

Documentation/spi/spidev_test.c


如,在/dev/spidev2.0上發(fā)送"string_to_send"字符串,顯示發(fā)送和接收的數據:

 ./spidev_test -D /dev/spidev2.0 -v -p string_to_send

如果要發(fā)送32位/16位的數據,則需要先生成二進(jìn)制文件,如生成32字節的隨機數據:

dd if=/dev/urandom of=test_data bs=16 count=2

用hexdump來(lái)查看這個(gè)二進(jìn)制文件:

hexdump -v test_data -C


00000000 74 6a 59 3e 1e 81 73 fb 5a 3f 94 c7 d8 20 ca e9 |tjY>..s.Z?... ..|


00000010 24 2e a5 68 75 ab f7 12 af e6 c1 3d e2 d8 9a ba |$..hu......=....|


00000020


發(fā)送:

./spidev_test -D /dev/spidev2.0 -b 32 -v -i test_data————————————————

最后,輸出結果與輸入相同即為正確。

 

結語(yǔ)

在這樣一個(gè)速食的時(shí)代,堅持做自己,慢下來(lái),潛心琢磨,心懷敬畏,領(lǐng)悟知識,

才能向下扎到根,向上捅破天,背著(zhù)世界往前行!

原文鏈接:https://blog.csdn.net/yyz_1987/article/details/131918983

                        



                        



         

                    

                        


*博客內容為網(wǎng)友個(gè)人發(fā)布,僅代表博主個(gè)人觀(guān)點(diǎn),如有侵權請聯(lián)系工作人員刪除。



關(guān)鍵詞: spi

相關(guān)推薦

技術(shù)專(zhuān)區

關(guān)閉
国产精品自在自线亚洲|国产精品无圣光一区二区|国产日产欧洲无码视频|久久久一本精品99久久K精品66|欧美人与动牲交片免费播放
<dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><small id="yhprb"></small><dfn id="yhprb"></dfn><small id="yhprb"><delect id="yhprb"></delect></small><small id="yhprb"></small><small id="yhprb"></small> <delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"></dfn><dfn id="yhprb"></dfn><s id="yhprb"><noframes id="yhprb"><small id="yhprb"><dfn id="yhprb"></dfn></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><small id="yhprb"></small><dfn id="yhprb"><delect id="yhprb"></delect></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn> <small id="yhprb"></small><delect id="yhprb"><strike id="yhprb"></strike></delect><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn><dfn id="yhprb"><s id="yhprb"><strike id="yhprb"></strike></s></dfn><dfn id="yhprb"><s id="yhprb"></s></dfn>