GPIOピン(ARMプラットフォーム、mach-davinci、カーネル2.6.27)でクロック信号を生成しようとしています。これは、100kHz付近に何かがあります。そのために優先度の高いタスクレットを使用します。理論は単純で、gpioを高く設定し、5usにudelayを設定し、gpioを低く設定し、別の5usを待ちますが、奇妙な問題が発生します。まず、この5usのdalayを取得することはできませんが、問題はなく、hwのパフォーマンスの問題のように見えるので、period = 40us(〜25kHzを与える)に移動しました。2番目の問題は最悪です。〜10msごとに1回、udelayは通常の3倍長く待機します。今回はヒアビートだと思いますが、プロトコル(これに加えて実装される)の観点からは受け入れられません。たとえば、500msの間、ハートビート手順を一時的に無効にする方法はありますか?それとも私は最初からそれを間違っているのでしょうか?コメントはありますか?
3 に答える
ソフトウェアで非同期にクロックを生成することは適切ではありません。よりうまく機能する2つの代替案を考えることができます。
プロセッサには、カーネルまたは別のドライバーによってまだ使用されていない組み込みのクロック ジェネレーター ペリフェラルがある場合があります。これらのいずれかを設定するとき、クロックを実行する速度を指定すると、パルスが不足し始めます。
プロセッサのデータシートを入手して調べてください。
「クロック」自体と呼ばれるペリフェラルは見つからないかもしれませんが、PWM ペリフェラルのように、サービスを開始できる同様のものを見つけることができます。
話している他のデバイスは、実際には通常のクロックを必要としない場合があります。「クロック」ラインを必要とする一部のチップは、読み取るビットがあるときにハイになり、データラインが変化しているときにローになるラインを必要とするだけです。この場合、あなたが読んでいる 100 kHz は、正確にその周波数のクロックの厳しい要件ではなく、クロック ライン (したがってデータ ライン) の速度の上限にすぎません。移行が許可されています。
クロックよりもはるかに高速な CPU では、これを 2 つの半分に分割する必要があります。
「上半分」はデータラインの状態を正しく設定し、次にクロックラインを上げます。次に、割り込みまたはカーネル タイマーを使用して、5 μs 後に下半分を実行するようにスケジュールします。
割り込みまたはタイマーによって呼び出される「下半分」で、クロックラインを元に戻し、5 μs 後に再び実行するように上半分をスケジュールします。
この種のジョブには tasklet を使用できません。タスクレットは、割り込みによってプリエンプトされる可能性があります。場合によっては、タスクレットをプロセス コンテキストで実行することもできます。
絶対にこの方法で行う必要がある場合は、割り込みハンドラーを使用します。割り込みを無効にし、必要なことをすべて行い、できるだけ早く終了します。
タイマー タスクレットをカーネル タイマーよりも高い優先度で実行できない限り、常にこの種のジッターの影響を受けやすくなります。本当にビットギャングでこれを行う必要がありますか? ハードウェア タイマーまたは PWM ジェネレータを使用する方がはるかに簡単です。タイマーを希望の速度で実行するように構成し、ピンを出力に設定すれば完了です。
各ビット周期でソフトウェア制御が必要な場合は、タスクレットを短い周期 (40 us 遅延の 4 分の 3 など) で実行するように設定することで、他のタスクを回避することができます。タスクレットで、割り込みを無効にし、正しい 40 us タイムスロットになるまでクロックをポーリングし、I/O 状態を設定し、割り込みを再度有効にして終了します。しかし、これは事実上、時計を見ることでシステムの 25% をタイプアップします。