Armadilloフォーラム

I2Cドライバ仕様

kimizuka

2022年9月2日 16時54分

製品:Armadillo-X1

お世話になっております。
君塚と申します。

Armadillo-X1を使用しております。 
現在、Armadillo-X1とFPGAとの間でI2C通信を行っておりますが、たまにI2Cの意図しないアクセスが観測されます。
ソフトウェアとしてはLinux上でマルチスレッド化されたアプリからI2Cをアクセスしています。
このI2Cドライバはマルチスレッド対応と理解しておりますが正しいでしょうか?
I2Cドライバの最新のドキュメントはございますでしょうか?

より具体的な状況を示すべきと思っておりますが、どのような情報があればよいかご教授ください。

以上、よろしくお願いいたします。
君塚

コメント

at_mizo

2022年9月2日 17時08分

溝渕です。

> このI2Cドライバはマルチスレッド対応と理解しておりますが正しいでしょうか?

上記質問が、「他プロセスのI2C通信との競合が発生しないか?」という質問であるとするならば、発生しないです。

ドライバのソースコードを見てみましたが、1度の通信の開始から終了まではlockを取って実行されるので、通信が混ざることは無いと思います。

ただし、i2cdev経由で、1度の通信を複数回に分けた場合は当然競合すると思います。

> I2Cドライバの最新のドキュメントはございますでしょうか?

Linuxカーネルのソースコード内の、"Documentation/i2c/"以下の資料などがあります。

> より具体的な状況を示すべきと思っておりますが、どのような情報があればよいかご教授ください。

どのような結果を期待して、どのように操作して、どのような結果を得たかを教えていただけると助言しやすいです。

kimizuka

2022年9月7日 17時41分

> 溝渕です。
>
> > このI2Cドライバはマルチスレッド対応と理解しておりますが正しいでしょうか?
>
> 上記質問が、「他プロセスのI2C通信との競合が発生しないか?」という質問であるとするならば、発生しないです。
>
> ドライバのソースコードを見てみましたが、1度の通信の開始から終了まではlockを取って実行されるので、通信が混ざることは無いと思います。
>
> ただし、i2cdev経由で、1度の通信を複数回に分けた場合は当然競合すると思います。
>
> > I2Cドライバの最新のドキュメントはございますでしょうか?
>
> Linuxカーネルのソースコード内の、"Documentation/i2c/"以下の資料などがあります。
>
>
> > より具体的な状況を示すべきと思っておりますが、どのような情報があればよいかご教授ください。
>
> どのような結果を期待して、どのように操作して、どのような結果を得たかを教えていただけると助言しやすいです。
>

お世話になっております。君塚です。

マルチプロセスで、I2Cデバイスへのアクセス競合を試してみました。
内容としては
・プロセスA
  /dev/i2c-0ファイルをオープン
  その状態でwait
wait解除後、ioctlで設定実行
ファイルへのwriteを実行
  クローズして終了 

・プロセスB
  /dev/i2c-0ファイルをオープン
waitなしでioctlで設定実行
ファイルへのwriteを実行
  クローズして終了 

呼び出しは、プロセスA→プロセスBの順で実施

期待値:
 プロセスBはプロセスAのクローズ後に、オープン以下を実行

実動作:
 プロセスBのwrite結果を反映した後、wait時間後にプロセスAの結果を反映

この結果からプロセスAのi2cアクセスがlockされているのなら、プロセスBのwriteが先に実行されることはないと思うのですがいかがでしょうか?
何か別の要因でプロセスBの実行が優先されたのでしょうか?

あと、このi2cドライバはいわゆるマルチスレッドセーフというものなのでしょうか?

以上、ご教授のほどよろしくお願いいたします。

at_mizo

2022年9月8日 8時41分

溝渕です。

> マルチプロセスで、I2Cデバイスへのアクセス競合を試してみました。
> 内容としては
> ・プロセスA
>   /dev/i2c-0ファイルをオープン
>   その状態でwait
> wait解除後、ioctlで設定実行
> ファイルへのwriteを実行
>   クローズして終了 
>
> ・プロセスB
>   /dev/i2c-0ファイルをオープン
> waitなしでioctlで設定実行
> ファイルへのwriteを実行
>   クローズして終了 
>
> 呼び出しは、プロセスA→プロセスBの順で実施
>
> 期待値:
>  プロセスBはプロセスAのクローズ後に、オープン以下を実行

上記期待値より、I2Cバスの競合というより、プロセス間の競合を懸念されていると推測します。

プロセス間で実行順の保証をする場合は、セマフォを使ったり、FIFOを利用してI2Cアクセスを行うプロセスを単一化する等の実装が必要になると思います。

> この結果からプロセスAのi2cアクセスがlockされているのなら、プロセスBのwriteが先に実行されることはないと思うのですがいかがでしょうか?
> 何か別の要因でプロセスBの実行が優先されたのでしょうか?

linuxではcontext switchがいつ発生するか、基本的にはわかりません。それによって、実行順は保証されません。保証したい場合は前述のように同期を取る仕組みを作る必要があります。

> あと、このi2cドライバはいわゆるマルチスレッドセーフというものなのでしょうか?

I2Cアクセス自体が混ざる(例えばプロセスAのwriteの最中にプロセスBのwriteが割り込む)ことが無いという点に関して言えばスレッドセーフです。

I2Cアクセスを行うプロセスの実行順がシーケンシャル(他のプロセスの終了を待ってプロセスを開始する)という意味では無い点にご注意ください。