シグナルハンドラ

シグナルハンドラ内では、malloc()やprintf()系が使えず、thread safe な関数しか呼べないので、シグナルハンドラではキューに記録して、メインルーチン内でキューを取り出して処理する形式を考えてみた。

実際に動作させてみると、0.5秒毎にタイマーが起動してキューにシグナル番号が積まれるが、メインルーチンで、0.05秒毎にキューをチェックするので、キューに積まれるシグナル番号は殆ど増える事は無く処理される。

30:30 sigevent:0
30:30 sigevent:0
30:30 sigevent:0
30:30 sigevent:0
30:30 sigevent:0
30:30 sigevent:0
31:31 sigevent:35
31:31 sigevent:0
31:31 sigevent:0
31:31 sigevent:0
31:31 sigevent:0
31:31 sigevent:0
31:31 sigevent:0

実行すると、こんな感じ。

表示しているのは、
キュー先頭(head):キュー末尾(tail) sigevent:シグナル番号
というフォーマットになっている。

しかし、Ctrl-Cを押しっぱなしにすると、メインルーチンでは、usleep()から抜けないので、キューにSIGINTが積まれまくる。

130:130 sigevent:0
131:131 sigevent:35
^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C^C132:42 sigevent:2
133:42 sigevent:2
134:42 sigevent:2
135:43 sigevent:2
136:43 sigevent:2
137:43 sigevent:2
138:43 sigevent:2
139:43 sigevent:2
140:43 sigevent:2
141:43 sigevent:2
142:43 sigevent:2
143:43 sigevent:2
144:44 sigevent:2
145:44 sigevent:35

ちなみにこのキューはオーバーフローすると、古いデータを捨てるようになっている。オーバフローを確認する方法は作ってない(笑)。

Ctrl-Cを離すと、メインルーチンでキューに溜まっているデータをせっせと処理し、キューの先頭のheadの数字と末尾のtailの数字がみるみる接近していくのが見て取れる。

これで、メインルーチンでシグナル割り込みを検知し、malloc()、printf()使いたい放題。
難点は、ちょっとリアルタイム性が悪くなるという点だな。

このプログラムはリアルタイムライブラリを使うので、コンパイル時には -lrt オプションがいる。

【買い物】フルーツグラノラ

20091018_1

業務用スーパーへ行ったら、フルーツグラノラのデザインが一新されていて、いつものデザインを探して、一瞬、品切れかと思った。

印刷代が安そう 🙂
業務用だから、実利が重要であって、虚飾は必要無いから、実に合理的だな。

棚にあるだけ9個全部購入。一応、店員に、「棚にあるだけしか無いのか?」と尋ねると、棚にあるだけとの返答で、今回は1ケースを注文しておいた。

ブログに書いておかないと、忘れてしまいそうだから、書いておく。

待ってくれないsleep

というC言語のプログラムだと、1秒待ってループってな感じだけど、create_timer()とかでタイマー作ってシグナル割り込みがあると、時間に関わらず、シグナルが発生した時点で、sleep()から抜けるんやな。

メイン処理で、sleep()で1秒間隔、タイマーの割り込みで0.5秒間隔でシグナルが発生するとすると、sleep()は必ず-1の戻り値で抜けてしまい、メイン処理は0.5秒間隔でループするんだな。

シグナルが来たら、メイン処理で何かするって組み方だと、sleep()がシグナルで抜けてくれた方がデッドロックが無くて良さそうだ。

歯の定期メンテナンス

先々週に上側やって、今日は下側の歯石取り。

虫歯も歯周病も細菌が原因で、口内細菌が安定しない幼児期に親から伝染され、一生、虫歯や歯周病の可能性に怯えながら生きていく事になる。

パーフェクトペリオってので治療すれば、歯周病原因菌を撲滅でき、そもそも歯周病にならなくなるから、やってみたい気がするな。

RBIO-2U

社長にRBIO-2Uを買ってもらった。

USBインターフェースだが、Ubuntu 9.04 Desktopのマシンに繋いだら、USB Serialportとしてサックリ認識。

ターミナルで”PCR01″とかコマンド送るとリレーがカチカチ作動する。

使い方は色々あるが、例えば、パソコンの温度が高い時に、外付けの強力な電動ファンのスイッチを自動で入れるとか、炭酸ガスボンベのソレノイドバルブを開閉するとか応用次第で色々楽しそうな事ができそうだ。

リレー出力10、入力4だが、入力ポートが結構おもしろい。GNDと入力の線を短絡させて、RBIOに”FB0″とコマンドを送ると”0″と返ってきて、開放状態だと、”255″という文字列がシリアルから返ってくる。

これも色々と応用が効くが、出力と入力と合わせて、電動ねずみ取り機とか作れるな(笑)

餌のチーズに触れると、入力で検知して、リレー出力で扉をガシャンと電動で閉じるってな具合。果てしなく無用の長物感がするが、まあパソコンで入力の判断と出力ができるってのが色々応用できて、おもちゃとして面白い。