組み込み Linux の一般的な spi ドライバーの spidev の使用法の概要

興味があったので、暇なときに imax6ul 開発ボードをいじってみました。Linux カーネルは spidev ドライバーを統合し、SPI デバイス用のユーザー空間 API を提供します。半二重通信用の読み取りおよび書き込みアクセス インターフェイスと、全二重通信および I/O 構成用の ioctl インターフェイスをサポートします。使用する場合、SPI スレーブ デバイスの互換性のある属性値を spidev ゾーンの spidev dt ids[] 配列に追加するだけで、SPI スレーブ デバイスを spidev デバイスとして作成できます。個別の spi デバイス ドライバーを作成したくない場合は、Linux カーネルによって提供される一般的な spidev デバイス ドライバーを使用するだけで十分です。このドライバーは、統一されたキャラクター デバイス操作を提供するため、読み取り、書き込み、および制御を行うだけで済みます。アプリケーション層。

spdevドライバーの概要

spidev は、SPI (シリアル ペリフェラル インターフェイス) デバイスと通信するための Linux カーネル ドライバーです。SPI は、マイクロコントローラーと外部デバイスのインターフェースに一般的に使用される全二重の同期シリアル通信プロトコルです。spidev ドライバーを使用すると、ユーザー空間プログラムが Linux デバイス ファイル インターフェイスを介して SPI デバイスと通信できるようになります。ユーザーは、デバイス ファイルを開いて読み書きすることで、SPI データを送受信できます。spidev ドライバーは、IO ポートと SPI パラメーターを制御するための ioctl コマンドのセットを提供します。

同時に、Linux カーネルには、ユーザー モードで spidev 動的関数をテストおよび検証するために使用される SPI テスト ツール spidev test も統合されています。

spidev デバイス ドライバーのソース コードの場所は、linux-imx-4.1.15\drivers\spi\spidev.c です。

ドライバーのフレーム図:

もちろん、spidev ドライバーを使用するだけでなく、独自の SPI ドライバーを作成することもできます。

既存の spidev ドライバを使用すると、アプリケーションで標準のファイル操作関数 (open、read、write、ioctl など) を直接使用して SPI デバイスを操作できる一連のユーザー空間インターフェイスが提供されるため、開発プロセスを簡素化できます。この方法は、ほとんどのアプリケーション シナリオ、特に機能を迅速に実現できる単純な SPI デバイス操作に適しています。

自作の SPI ドライバを使用する場合は、それほど面倒ではありませんが、SPI コントローラ ドライバ、SPI デバイス ドライバを含む SPI サブシステムをカーネルに実装し、最後にキャラクタ型デバイス ドライバの操作インターフェイスを実装する必要があります。上位層のアプリケーションをそのまま使用してください。

アプリケーション層の使用手順

ユーザー アプリケーション層で spidev ドライバーを使用する手順は次のとおりです。

1. SPI デバイス ファイルを開きます。ユーザーは /dev/spidevX.Y ファイルを開くことで SPI デバイスにアクセスできます。ここで、X は SPI コントローラの番号、Y は SPI デバイスの番号です。

2. SPI パラメータの構成: ユーザーは、ioctl コマンド SPI_IOC_WR_MODE、SPI_IOC_WR_BITS_PER_WORD、および SPI_IOC_WR_MAX_SPEED_HZ を使用して、SPI モード、データ ビット、クロック速度などのパラメータを設定できます。

3. データの送受信: ユーザーは読み取りおよび書き込みシステム コールを使用して SPI データを送受信できます。書き込まれたデータは SPI デバイスに転送され、デバイスから読み取られたデータはユーザー指定のバッファに保存されます。

4. SPI デバイス ファイルを閉じます。SPI デバイスと通信する必要がなくなったら、ユーザーは SPI デバイス ファイルを閉じる必要があります。

要約すると、spidev ドライバーは SPI デバイスと通信するためのシンプルかつ柔軟な方法を提供し、ユーザーが Linux システム上で SPI デバイスを簡単に開発および制御できるようにします。

カーネル構成

spidev ユーザーモードドライバーを有効にする

生成された構成ファイルでは、次の構成が有効になっていることがわかります。私のものは、imx6ul 開発ボードの imx_v7_defconfig の Linux カーネル設定ファイルにあります。

CONFIG_SPI=y
CONFIG_SPI_GPIO=y
CONFIG_SPI_IMX=y
CONFIG_SPI_SPIDEV=y

デバイスツリーの書き込み

&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" 表示该节点使能*/

	spidev: icm20608@0 {
	compatible = "alientek,icm20608";
        spi-max-frequency = <8000000>;
        reg = <0>;/*spi设备是没有设备地址的, 这里是指使用spi控制器的cs-gpios里的第几个片选io */
    };

	oled: oledsh1106@1 {
	compatible = "yang,oledsh1106";/*重要,会匹配spidev.c中指定的compatible*/
	spi-cpol;/*配置spi信号模式*/
	spi-cpha;
	spi-max-frequency = < 8000000 >;/* 指定spi设备的最大工作时钟 */
    reg = <1>;
    };
};

上記の注意: spi インターフェイスの下に複数のスレーブ デバイスがマウントされている場合は、fsl, spi-num-chipselects = <2> を設定する必要があります。デフォルト値は 1 です。もう 1 つ注意すべき点は、cs-gpios チップ選択信号を対応する番号で構成する必要があることです。上記は 2 つのチップ選択 GPIO ピンを設定するもので、最初のピンはデフォルトで、2 番目のピンは指定されています。スレーブ デバイスが 1 台のみの場合は、cs-gpio を設定できます。cs-gpio と cs-gpios の違いに注意してください。s を含む識別子は複数存在する可能性があります。

CS ピン数の設定が無視されると、次のエラーが発生します。

fsl,spi-num-chipselects = <2> を設定する必要があります。 

上記の互換性属性に注意してください。新しいバージョンの Linux カーネルでは、任意の文字列を書くことができます。「spidev」と書かないことをお勧めします。古いバージョンは「spidev」と書く必要があります。その理由は次のとおりです。spidev は、特定の互換文字列なしで DT 内で参照されるべきではありません 。これはハードウェアの説明ではなく、Linux の実装に関するものです。

さらに、追加の構成がいくつかあります。以下はカスタム属性で、動作タイミング方法やその他の機能設定を指定するために使用されます。CPOL を 1 に設定する必要がある場合は、spi デバイス ノードに「spi-cpol」属性を追加するだけで済みます。CPOL が 0 に設定されている場合は、「spi-cpol」属性を書き込むことはできません。

buswidth = <8>; /* 传输以8位为单位 */
mode = <0>; /* 使用第几种工作时序(CPOL, CPHA) */
/*但在现用的内核源码里发现, spi设备的工作时序并不是用mode属性值来指定的*/
/* 如CPOL需要设1, 则只需在spi设备节点里加上"spi-cpol"属性即可; CPOL设0,则不写"spi-cpol"属性即可 */
/* CPHA设1时,则在设备节点里加上"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*/
                    >;
            };

カーネルとデバイスツリーをコンパイルする

#加载环境
source /opt/fsl-imx-x11/4.1.15-2.1.0/environment-setup-cortexa7hf-neon-poky-linux-gnueabi
#编译内核
make zImage -j16
#编译指定的设备树
make imx6ull-14x14-nand-4.3-480x272-c.dtb

spdevドライバーを変更する

デフォルトの spidev.c は追加したデバイスと一致しないため、spidev.c コードを変更して互換性のある一致を追加する必要があります。

/* 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

カーネルが正常にコンパイルされたら、カーネル ファイルとデバイス ツリー ファイルを更新します。デバイスを起動した後、spidev が /sys/class/spidev で列挙した spi デバイスの数を確認できます。

デバイスツリービュー

デバイス ツリーに新しく追加されたノードがあるかどうかを確認します。

ボードのデバイス ツリーを更新した後、spi デバイス ノードが生成されているかどうかを確認します。

オープンソースのテストツール

spidev ドライバーには既製のテスト ツールが含まれています。一般的に使用されるテスト ツールの 1 つは spi_test です。これは、spidev ドライバーに付属するテスト ツールであり、SPI デバイスのテストとデバッグに使用できます。spi_test は、コマンド ライン パラメータを通じて、デバイス ファイル、転送速度、バイト オーダーなどの SPI デバイスのさまざまなパラメータを設定できます。spi_test を使用して SPI データを送受信し、spidev ドライバーの機能とパフォーマンスを検証します。

ソース コードの linux-imx-4.1.15-2.1.0-v2.7\Documentation\spi パスには、テスト ツールの 2 つのソース コード ファイル、spidev_fdx.c ファイルと spidev_test.c ファイルがあります。実行可能ファイルに直接クロスコンパイルできます。これらのツールはすべて、spidev 汎用デバイス ドライバーおよび対応する ioctl コマンドに基づいて実装されており、spi 汎用ドライバーのテストに便利に使用できます。

コンパイル方法

#加载环境
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

ループバックテスト

まず、spi インターフェイスの MISO インターフェイスと MOSI インターフェイスを短絡します。

次に、テスト コードをコンパイルします。

ドキュメント/spi/spidev_test.c

たとえば、「string_to_send」文字列を /dev/spidev2.0 に送信し、送受信されたデータを表示します。

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

32 ビット/16 ビット データを送信する場合は、32 バイトのランダム データを生成するなど、最初にバイナリ ファイルを生成する必要があります。

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

hexdump を使用して、このバイナリ ファイルを表示します。

hexdump -v test_data -C

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

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

00000020

送信:

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

  

最後に、出力が入力と同じであれば、出力は正しいことになります。

エピローグ

ファストフード全盛の時代、自分らしさを主張し、ゆっくりと、集中して考え、畏敬の念を抱き、知識を理解することで、初めて根を掘り、天を突き抜け、世界とともに前進することができる背中に!

その他のリソース

spidev (SPI ユーザーモード API) の使用

spidev を使用して Linux ベースの OLED を駆動する - 組み込みテクノロジー - 電子ペーパー

0.96 インチ OLED スクリーンを mx6ull_AURORA1997 のブログ - CSDN ブログを搭載した Linux システムに移植

組み込み Linux ドライバー開発 - /sys/bus/spi/devices に対応する spi デバイス ファイルがない問題を解決 - プログラマーが探した

組み込み Linux ドライバー開発 - /sys/bus/spi/devices に対応する spi デバイス ファイルがない問題を解決する spidev0_blog_xu のブログ - CSDN ブログ

SPIデバイスドライバーの書き方_spiプログラムの作り方_ヒルベルト(*^*)のブログ-CSDNブログ

154 spidev: SPI "ユニバーサル" ドライバー_あなたのボードが煙を出している ブログ-CSDN ブログ

i.MX6ULL ドライバー開発 | 14 - Linux SPI ドライバー フレームワークに基づく ICM-20608 センサーを読む_MCUlover666 の技術ブログ_51CTO ブログ

デバイスツリー学習 (9) SPI デバイス登録 process_spi_lsb_first_kunkliu のブログ - CSDN ブログ

https://www.cnblogs.com/lknlfy/p/3265019.html

デバイス ツリー内の spi デバイスとカーネルから spi ノードまでの処理フロー

組み込み Linux_linux 用の 2 つの SPI ドライバー メソッド spidev_iot-lorawan のブログ - CSDN ブログ

おすすめ

転載: blog.csdn.net/qq8864/article/details/131918983