2016-07-15 8 views
2

私はとしてユーザ空間に公開されたi2cアダプタを持っています。そのアダプタのi2c-toolsパッケージのi2cdetectを使用すると、このアダプタにデバイスが表示され、コマンドラインからget、set、およびdump操作を実行できます。i2c ioctlのENXIOとは何ですか?

ioctl I2C_RDWR操作を使用して書き込みを実行しようとするCコードがあります。

ここでは、私が取り組んでいる切り捨てられたコードがあります(コンテキストに対してのみ提供され、それを実行することは質問に答えることが重要ではありません)。

fd = open ("/dev/i2c-0", O_RDWR | O_NONBLOCK); 

/* other stuff happens here */ 

if (ioctl (fd, I2C_FUNCS, &funcs) != 0) 
    return -1; 
if (!(funcs & I2C_FUNC_I2C)) 
    return -1; 

/* i added this bit of debug just to be sure fd didn't 
* get inadvertently closed along the way. 
*/ 
if (fcntl (fd, F_GETFD) != 0) { 
    return -1; 
} 

/* build the ioctl message payload */ 

ret = ioctl (fd, I2C_RDWR, &payload) 
if (ret) { 
    fprintf (stderr, "ioctl returned %d. Reason: %s (errno=%d).", 
      ret, strerror(errno), errno); 
    return -1; 
} 

return 0; 

私はまた、このように見えるsmbus ioctl関数を使ってみました。すべての場合において

fd = open ("/dev/i2c-0", O_RDWR | O_NONBLOCK); 

/* other stuff happens here */ 

if (ioctl (fd, I2C_FUNCS, &funcs) != 0) 
    return -1; 
if (!(funcs & I2C_FUNC_SMBUS_WORD_DATA)) 
    return -1; 

/* i added this bit of debug just to be sure fd didn't 
* get inadvertently closed along the way. 
*/ 
if (fcntl (fd, F_GETFD) != 0) { 
    return -1; 
} 

/* build the ioctl smbus message payload */ 

if (ioctl (fd, I2C_SLAVE_FORCE, dev) != 0) 
    return -1; 

ret = ioctl (fd, I2C_SMBUS, &payload); 
if (ret) { 
    fprintf (stderr, "ioctl returned %d. Reason: %s (errno=%d).", 
      ret, strerror(errno), errno); 
    return -1; 
} 

return 0; 

、プログラムは常にfprintfに当たり、これが出力されます:

ioctlは返さ-1。理由:そのようなデバイスまたはアドレスはありません(errno = 6)。

man 3 ioctlによると、ENXIOエラーのために「一般的な」理由は次のとおりです。

ENXIO要求引数は、このデバイスドライバのために有効ですが、サービスが要求ARGこの特定のサブデバイスでは実行できません。

イアンはコメントで指摘したように、しかし、上記のmanページに記載されている情報に関するSTREAMSは、Linux上では関係ありません、私は​​使用しなければならない - 残念ながら、ほとんどはちょうどそれのioctlドン」と言い、実際にはどの標準にも合致しています。

これは3つの質問を提起します。

  1. これはi2cアダプタにはどういう意味がありますか?このデバイスのドライバは、このメソッドを使用して読み書きをサポートしていませんか?
  2. マニュアルページには、I_接頭辞付き操作の戻りコードの具体的な説明が含まれていますが、他の操作用の戻りコードはありません。 I2Cのioctl操作に固有の情報を探すことができる別の場所がありますか?
  3. i2c ioctl関数のソースはどこにありますか?
+1

STREAMSデバイスへの参照は、[STREAMS](https://en.wikipedia.org/wiki/STREAMS)をサポートしていないため、Linuxでは無関係です。実際には '' man 2 ioctl'(http://linux.die.net/man/2/ioctl)を見てください。 –

+0

@IanAbbott hmmm、ENXIOは言及していません。 : –

+0

「準拠する」セクションを参照してください。 –

答えて

0

通常、デバイスが応答しなかったことを示します。詳細はお使いのハードウェアによって異なります。

一般的なI2C ioctlコードは、lm-sensorsプロジェクトの一部であるi2c-devパッケージの一部です。これらのioctlは独自のマニュアルページを持っていませんが、documentation in the kernel source treeを持っています。

カーネルでは、実装はすべてdrivers/i2c/i2c-dev.cdrivers/i2c/i2c-core.cに保存されています。エントリポイントはi2cdev_ioctl()です。この共通コードのどれもENXIOを返しません。

最終的に、この共通コードは、i2cバス上のハードウェアレベルのドライバ機能を呼び出す必要があります。 i2cバスのハードウェアドライバはdrivers/i2c/busses/に格納されています。これらのドライバのそれぞれは、 ioctlsのために使用されるmaster_xferまたは(I2C_SMBUSのために使用される)機能のうちの1つまたは両方を実装することができる。

私の場合、デバイスは実際に専用のi2cハードウェアを持たず、機能bit_xfer of drivers/i2c/algos/i2c-algo-bit.cに実装されたビットバンギングソフトウェアエミュレーションのように見えます。 ENXIOは関数bit_doAddressから来ました。

+0

ヒント: 'dmesg'を使ってカーネルログを読み込みます。通常、何かが失敗した理由があります(たとえば、デバイスが応答しなかった場合のI2Cタイムアウトエラー)。 –

関連する問題