SSブログ

Raspberry Pi用pigpio Library(番外編) [Raspberry Pi]

先日、pigpioのSPIが2本使えるので、独立に読み書きできる、と書いた。もちろん独立なのはそうなのだけど、僕がやりたかったA/DコンバータとD/Aコンバータをそれぞれのバスに繋いで、それぞれの最大スループットで読み書きできる、というのは嘘だった。ごめんなさい。

実際に回路を作って繋いでみるまで気がつかなかったのは僕がバカなんだけど、pigpioそのものはリエントラントには書かれていない。pigpioの関数群は基本的には排他制御が必要で、つまり僕がやりたかったような、それぞれのSPIバスを別々のスレッドから呼ぶなどと言うことことはできない。実際に繋いでドライブしてみてそれに初めて気がついた。

D/Aを高速で回すことはもちろんできた。ところがA/Dを読みに行くとD/Aが失速する。あれえ、おっかしいなあ、と思いながら回路を確認したけど、これは外付けもほとんどなくて間違いようがない。

自分の書いたpigpioを呼ぶ下位関数と、それを呼んでいる上位関数をしばらく眺めていて、気がついた。D/Aはスピードを出すために専用のスレッドから呼んでいる。A/Dのほうはpigpio関数の排他制御をせずにメインスレッドからときどき読みに行くように書いてしまった。とうぜん、A/Dを読みに行くとき、たまたまD/Aへの出力の最中だった場合データがぶっ壊れてしまう。よく考えたら、いやよく考えなくても当たり前だった。

ちゃんとmutex_lockを入れると、データが壊れることはなくなったけど、A/Dを読んでいる間(約15$\mu$秒)はD/Aの波形が止まってしまう。すっごい残念。

Raspberry Piに使われているSoCのSPIバスそのものは完全に独立しているので、SPIレジスタの読み書きさえ排他制御すれば問題ないし、レジスタの読み書きは実際には多くがアトミックな操作なので、注意して書けばロックは必要なくなる。でもpigpioにとっては排他制御が必要な部分とそうでない部分は入りくんでいるので、スレッドセーフにするのは容易ではない(少なくともSPIでの読み込みはSPIへの命令とは別にしないと実現できない)。

僕がやりたかったことを実現するにはpigpioでもダメで自分でレジスタアクセスのコードを書くしかない。

ということで、前回ふたつのSPIバスがいかにも完全に独立に使えるように書いたけど、それは嘘、間違いです。一部の単純な関数を除いてpigpioライブラリの各関数はスレッドセーフではありません。お気を付けください。そして、ごめんなさい。
nice!(0)  コメント(0)  トラックバック(0) 

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

Raspberry Pi用pigpio ..Raspberry Pi用pigpio .. ブログトップ

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。