Armadilloフォーラム

GPIOのエッジトリガで割込みハンドラを起動するには

funayama

2014年7月13日 10時08分

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

おかげさまで、
先日、GPIOでGPSのPPS信号をエッジトリガで検出できるようになりました。
その際、poll()システムコールをcallし割り込みが発生するまで待つことで実現しておりました。
そこで、
このエッジトリガで割り込みハンドラを起動し、poll()後の処理の「UART4受信処理」のみを
割り込みハンドラで行うものに変更したいのですが、
どのようにしたら良いのでしょうか。
手がかりがつかめません、ご教授下さい。
よろしくお願いいたします。

今の処理は、このようになっております。

fd=open("/sys/class/gpio/CON11_49/direction", O_RDWR);
 write(fd,"in",2);  // 入力に設定
open("/sys/class/gpio/CON11_49/edge", O_RDWR);
 write(fd,"rising",6);  // 立ち上がりエッジに設定
poll(&pfd,1,-1); // 割り込み待ち
  ・
UART4受信処理
コマンド解析処理
コメント

純粋な意味での割り込みハンドラとなると、
デバイスドライバ云々になって大ごとになりそうですね。
手軽なところで、別スレッドで処理すると言うところでしょうか。
その場合は、メインスレッドで諸々の設定をする前に別スレッドを起動しておき、
別スレッド側ではpoll()で待機していればよさそうです。

老婆心ながら、貼られたソースのopen()/write()の後にclose()がないのが気になります。

齊藤と申します
UART4の受信処理はlinuxの標準シリアルドライバーに任せて(バッファリングしてくれる)常時受信しっぱなしにしておき、
立ち上がりエッジのタイミングでそれを取り出すのではだめなんでしょうか?

あるいは、そもそも立ち上がりエッジは無視してUART受信だけでプログラムは構成できないのでしょうか?
「UART4に届くデータのうち PPS信号をエッジに届くデータだけを処理してそれ以外は無視したい」ってことがあるのですか?

お世話になっております。

返信が遅くなってしまい申し訳ありません。

izawaさん、齊藤さん、ありがとうございました。

>izawaさん
writeの次にcloseが実は入っております。
あとで気が付きました。
申し訳ありません。

>齊藤さん
なぜハンドラなのか、というところですが、
GPSの情報は常に更新される為、信頼性のある情報を受け取る為、となります。
また、情報量も多く(複数パターンがあり、パターンでサイズが異なりますが、今約700byte程度)、
その中にある必要な情報(Offsetの異なる複数データを合計して20byte程度)を取り出します。
問題なのは、PPSのタイミングで読出しをしないとサイズ、及び、Offsetが変わってしまい一定しないことです。
最後はフォーマット・キーとなるキーからのOffsetを見る形にはなりますが。
長くなりましたが、もう少し検討してみます。

ありがとうございました。

中村です。

ちょっと気になったので・・・

> 問題なのは、PPSのタイミングで読出しをしないとサイズ、及び、Offsetが変わってしまい一定しないことです。

GPSのデータは、PPSを見なくてもパースできるようになってませんか?

すみません。根本的なところで誤解していると困るので確認してください。

①GPSレシーバのありがちな挙動とすれば、測定値をシリアルにどんどん垂れ流してくるものです。
この場合、PPSエッジに同期してデータを読み出したとしてもそれは先にlinuxのシリアルデバイスの受信バッファにたまっていたデータをその時点で読み出しテルだけなので、PPSエッジと測位データのタイミングずれ 問題の解決にはなりません。

②PPSエッジ検出 → 現在の測地情報を出力せよとGPSモジュールに指示 →受け取る
 だと、指示コマンドをシリアルで送る分の遅延が入ります。これも割り込みハンドラを活用しても意味のある精度向上はないのでは?

というわけで、そもそも垂れ流しモードのGPSのNMEAフォーマットの1レコードには位置情報とその位置を得た時刻が1/1000秒単位で載ってますよね。PPSじゃなくてNMEAフォーマットに含まれる時刻値を使うのではだめなんでしょうか?