Raspberry Pi用pigpio Library(番外編その2) [Raspberry Pi]
先日pigpioライブラリはスレッドセーフではないということに気がついた話をした。もちろんライブラリ全体として基本的にはスレッドセーフではないことにかわりはない(全部の組み合わせでスレッドセーフ性を保証するのは大変)。しかし、今日pigpioのSPIまわりのソースを見ていて驚いた。サイトにはなんの言及もないけど、SPIの二つのバスはそれぞれ独立なスレッドから呼べるように書いてあった。
具体的に言えば、ソースによるとふたつのバスは別々にpthreadのmutexで排他制御するように書かれていた。片方のSPIバスの異なるチャンネル(チップセレクト)を別のスレッドから同時に使うことはできない(排他制御を受ける)けど、一方のバスを使いながら、もう一方のバスを違うスレッドから使うぶんには問題がないように書かれていた。
それを見てびっくりしたので、あらためて今日実験用のコードを書いて試してみた。スレッドをふたつ立ち上げて一方のSPIに繋がったD/A(MCP4922)をループさせて正弦波や三角波を出力させながら、もう一方のSPIに繋がったA/D(MCP3208)から信号を読んでみた。D/Aはクロックが20MHzで2バイトで出力命令が完了するので、約1MHzのサンプリングが可能になる。A/Dのほうは2MHzクロックで3バイトを使うので、およそ70kHz弱のサンプリングが可能のはずである。
やってみるとほぼその通りの結果になった。D/Aのスレッドには波形出力以外なにもさせていないので、1kHzぐらいだとRaspberry Piからソフトウェアで生成したとは思えないようなきれいな正弦波や三角波が出力できたし、階段型になっているのがわかるけど50kHzぐらい(20段の階段)なら正弦波と三角波の区別がつくくらいの波形になった。
先日はなんでうまくいかなかったか、というとどうやらスレッドにいろんなことをさせすぎてたせいらしい。よけいなことをしてそれがたまたまスレッドセーフでない書きかたになってしまっていた(どこがポイントだったかは自分のコードを改めて見直してわかったけど、それは恥ずかしくてここに書けない)。ようするに僕のマルチスレッドの書き方がヘボだっただけだということ。D/Aで波形出力したかったら専用スレッドにしてD/Aだけをぶんまわすように書くべきだということがあらためてわかった。まあ知ってる人は知ってるんだろうけど。
ところで、Microchip Technology社のD/A、A/Dはどっちも数百円で手に入るけど、実に優秀だわ。僕みたいな素人がちょこちょこっと半田付けするだけでちゃんと動く。もちろん非直線エラーとかは個別に実測して較正しないといけないんだろうけど、誤差1%以下で十分な用途ならバカチョンで使えそうである。たいしたもんだ。
ということで、何度も言を翻すことになりましたが、もう一回修正します。pigpioを使えばそれぞれのSPIバスの最大スループットが同時に実現可能です。もちろんマルチスレッドの書き方に注意して、という条件付きで。
それとあらためて、読むことのできるソースは読んだい方がいい、と自戒を込めて主張する。還暦過ぎた僕がそう感じるのだから、若い人にはさらに自らを戒めてほしい、と思う。
具体的に言えば、ソースによるとふたつのバスは別々にpthreadのmutexで排他制御するように書かれていた。片方のSPIバスの異なるチャンネル(チップセレクト)を別のスレッドから同時に使うことはできない(排他制御を受ける)けど、一方のバスを使いながら、もう一方のバスを違うスレッドから使うぶんには問題がないように書かれていた。
それを見てびっくりしたので、あらためて今日実験用のコードを書いて試してみた。スレッドをふたつ立ち上げて一方のSPIに繋がったD/A(MCP4922)をループさせて正弦波や三角波を出力させながら、もう一方のSPIに繋がったA/D(MCP3208)から信号を読んでみた。D/Aはクロックが20MHzで2バイトで出力命令が完了するので、約1MHzのサンプリングが可能になる。A/Dのほうは2MHzクロックで3バイトを使うので、およそ70kHz弱のサンプリングが可能のはずである。
やってみるとほぼその通りの結果になった。D/Aのスレッドには波形出力以外なにもさせていないので、1kHzぐらいだとRaspberry Piからソフトウェアで生成したとは思えないようなきれいな正弦波や三角波が出力できたし、階段型になっているのがわかるけど50kHzぐらい(20段の階段)なら正弦波と三角波の区別がつくくらいの波形になった。
先日はなんでうまくいかなかったか、というとどうやらスレッドにいろんなことをさせすぎてたせいらしい。よけいなことをしてそれがたまたまスレッドセーフでない書きかたになってしまっていた(どこがポイントだったかは自分のコードを改めて見直してわかったけど、それは恥ずかしくてここに書けない)。ようするに僕のマルチスレッドの書き方がヘボだっただけだということ。D/Aで波形出力したかったら専用スレッドにしてD/Aだけをぶんまわすように書くべきだということがあらためてわかった。まあ知ってる人は知ってるんだろうけど。
ところで、Microchip Technology社のD/A、A/Dはどっちも数百円で手に入るけど、実に優秀だわ。僕みたいな素人がちょこちょこっと半田付けするだけでちゃんと動く。もちろん非直線エラーとかは個別に実測して較正しないといけないんだろうけど、誤差1%以下で十分な用途ならバカチョンで使えそうである。たいしたもんだ。
ということで、何度も言を翻すことになりましたが、もう一回修正します。pigpioを使えばそれぞれのSPIバスの最大スループットが同時に実現可能です。もちろんマルチスレッドの書き方に注意して、という条件付きで。
それとあらためて、読むことのできるソースは読んだい方がいい、と自戒を込めて主張する。還暦過ぎた僕がそう感じるのだから、若い人にはさらに自らを戒めてほしい、と思う。
2016-12-16 21:33
nice!(0)
コメント(0)
トラックバック(0)
コメント 0