avr-libcがおかしい?(7/16/2017)SR04を動かす分のソフト開発は大体終わった。SR04では使わない連続データの入出力機能などは開発済みだ。考えられる機能はほぼ実現したが、ただひとつ気になっているところがある。連続測定のとき、SR04のエコーが返ってくるまで余裕を見て50msの待ち時間を設けていることだ。用途から言って、そう短い測定間隔が必要なわけではない。実用上は全く問題ないのだが、距離が短くても、待ち時間は変わらない。そのあいだ何もしないというのも芸のない話だ。この間隔を短くするのは、超音波のエコーが返ってくるまでに、親機の方から、エコーが返ってきたがどうかを調べるコマンドを送れば良い。親機はそのフラグを見て、バッファーに収容されたデータを読む。トリガーをSR04にかけるまえに、フラグを0にし、帰ってきたらこれを1にする。親機は適宜マスター読み込み宣言でこのフラグを読み取って1になるのを待つ。造作のない話なのだが、これがつまづきの始まりだった。うまく動かないのである。フラグが1になったあとの計測データがでたらめになる。計測が割り込みを受けている間にデータが不正になるのである。慌ててAVRの参考文献を調べるが、AVRと、avr-libcは基本的にはリエントラント(複数のタスクを受け入れる)で、同じプログラムに複数のスレッドが通ることを許している。これまでにこうしたプログラムはいくつか作り、何の問題なく動いている。リニアPCMプレーヤーなどは、DACの音声発生、SDカードの読み込み、LCDの進捗表示と3段のマルチタスクで動いている。リエントラントといっても共通のグローバル変数や、printfなどの標準関数はリエントラントには動かない。I2CとSR04の計測ルーチンは全く無関係だ(とこのときは確信していた)。問題なく動くはずなのだが、現実にはデータが汚されている。ハングするならともかくまともに戻って動くのが気に入らない。満を持してロジアナを出動させる(オシロでは無理)。I2Cとエコー、実際にデータをセットするプロセスにプローブを入れ、状況を見る。確かに、エコー期間の時にI2Cが動くとデータが不正になる。共通リソースもないのにどうしてこんなことが起きるのだろう。