2

カスタム ハードウェア用の SPI ドライバーを実装しようとしています。私は spidev ドライバーのコピーから始めました。これは、私が必要とするほとんどすべてをサポートしています。

コマンドビット(読み取り/書き込み)、アドレス、および任意の量のデータの3つの部分を持つプロトコルを使用しています。

これを行うには、単純に lseek 機能を追加するのが最善の方法であると想定していました。目的のアドレスを「シーク」してから、任意の数のバイトを読み書きします。新しいドライバーの file_operations でカスタム .llseek を作成しましたが、その関数が呼び出されるのを見たことがありません。fseek()、lseek()、および pread() を使用してみましたが、これらの関数のいずれも新しい my_lseek() 関数を呼び出していないようです。すべての呼び出しで「errno 29 ESPIPE Illegal Seek」が報告されます

デバイスは board.c ファイルで定義されています。

static struct spi_board_info my_spi_board_info[] __initdata = {
[0] = {
    .modalias      = "myspi",
    .bus_num        = 1,
    .chip_select    = 0,
    .max_speed_hz   = 3000000,
    .mode           = SPI_MODE_0,
    .controller_data = &spidev_mcspi_config,
}, ...

主に私が見つけた例が filp->f_pos を参照しているため、devファイルが作成される方法に何かがあるのではないかと思います

static int myspi_llseek(struct file *filp, loff_t off, int whence)
{
    ...
    newpos = filp->f_pos + off;
    ...
}

私の質問は次のとおりです。このドライバー (わずかに変更された spidev) が「シーク」呼び出しをサポートする方法はありますか? どの時点で errno 29 を返すように定義されますか? 新しいドライバーから始めなければならず、spi_board_info() と spi_register_board_info() のセットアップに頼ることができなくなりますか?

/drivers/spi ディレクトリ (spi-dw) 内の 1 つのドライバーのみが lseek を参照し、default_llseek 実装を使用します。すべてを立ち上げて実行するために私たちが思いついた「ハック」がいくつかありますが、私はそれを正しく行う方法を学びたい傾向があります.

どんな提案でも大歓迎です!(PS、OMAP Android システムのカーネル バージョンは 3.4.48 です)

4

1 に答える 1

4

Spi ドライバーは、llseek または fseek 機能をサポートしていません。これらの多くのコールバック関数があります。

 struct spi_driver {
    const struct spi_device_id *id_table;
    int                     (*probe)(struct spi_device *spi);
    int                     (*remove)(struct spi_device *spi);
    void                    (*shutdown)(struct spi_device *spi);
    int                     (*suspend)(struct spi_device *spi, pm_message_t mesg);
    int                     (*resume)(struct spi_device *spi);
    struct device_driver    driver;

};

これで、 drivers/spi/spi-dw.cが charter-driver (debugfs_create_file("registers", S_IFREG | S_IRUGO, dws->debugfs, (void *)dws, &dw_spi_regs_ops);) として登録されます。そのため、debugfs ファイルシステムにファイルを作成するように実装しています。lseek コールバック関数を実装しています。

static const struct file_operations dw_spi_regs_ops = {
    .owner          = THIS_MODULE,
    .open           = simple_open,
    .read           = dw_spi_show_regs,
    .llseek         = default_llseek,

}; file_operations 構造体は linux/fs.h で定義され、デバイス上でさまざまな操作を実行するドライバーによって定義された関数へのポインターを保持します。構造体の各フィールドは、要求された操作を処理するためにドライバーによって定義された関数のアドレスに対応します。

lseek -: lseek は、ファイル記述子の読み取り/書き込みポインターの位置を変更するために使用されるシステム コールです。

SPI -: "Serial Peripheral Interface" (SPI) は、マイクロコントローラをセンサー、メモリ、および周辺機器に接続するために使用される同期 4 ワイヤ シリアル リンクです。SPI は、lseek および fseek 機能を提供できません。

SPI ドライバーには 2 つのタイプがあります ( https://www.kernel.org/doc/Documentation/spi/spi-summary )

コントローラ ドライバ ... コントローラはシステム オン チップ プロセッサに組み込むことができ、多くの場合、マスターとスレーブの両方の役割をサポートします。これらのドライバーはハードウェア レジスタにアクセスし、DMA を使用する場合があります。または、GPIO ピンのみを必要とする PIO ビットバンガーにすることもできます。

プロトコル ドライバー ... これらはコントローラー ドライバーを介してメッセージを渡し、SPI リンクの反対側にあるスレーブまたはマスター デバイスと通信します。

ユーザーによる読み取り、書き込み、および llseek が必要な場合は、SPI の上にチャーター ドライバーを登録する必要があります。その後、取得を達成することができます。

于 2016-06-05T04:34:12.953 に答える