5.15.44 raspiカーネルとライブパッチを適用したGentooを実行するRaspberry Pi 4Bがあります。コアはCONFIG_PREEMPT_RT
(驚くべきことに)、、CONFIG_HZ_PERIODIC
(CPU_FREQ_DEFAULT_GOV_PERFORMANCE
頭では覚えていないいくつかの異なるオプション)で構成されており、Raspi自体は1,800 GHzのクロック速度で動作します。
私が解決したい問題は次のとおりです。
外部デバイスをRaspiのGPIOピンに接続しました。このデバイスは入出力に1ピンを使用します。入出力の場合、4us(マイクロ秒)ごとに1ビットを転送して通信が行われます。低ビット(0)は3usの低信号、1usの高信号に分けられます。高ビット(1)は、1usの低信号と3usの高信号に分けられます。
外部デバイスは定期的に000000001シーケンスをraspiに送信します(約36usかかります)。その後、64ビット応答が予想されます。外部デバイスからデータを読み取るために現在のピン状態を読み取り、プログラムが開始されてからの時間をマイクロ秒単位で印刷する小さなプログラムをC ++で書いた。
以下は、プログラムが送信される値0のビットを読み取る例である。
Pin State: 0 | Time Dif: 7365.79
Pin State: 0 | Time Dif: 7365.92
Pin State: 0 | Time Dif: 7366.05
Pin State: 0 | Time Dif: 7366.36
Pin State: 0 | Time Dif: 7366.49
Pin State: 0 | Time Dif: 7366.62
Pin State: 0 | Time Dif: 7366.75
Pin State: 0 | Time Dif: 7366.88
Pin State: 0 | Time Dif: 7367.01
Pin State: 0 | Time Dif: 7367.14
Pin State: 0 | Time Dif: 7367.27
Pin State: 0 | Time Dif: 7367.4
Pin State: 0 | Time Dif: 7367.55
Pin State: 0 | Time Dif: 7367.68
Pin State: 0 | Time Dif: 7367.81
Pin State: 0 | Time Dif: 7367.94
Pin State: 0 | Time Dif: 7368.07
Pin State: 0 | Time Dif: 7368.2
Pin State: 0 | Time Dif: 7368.33
Pin State: 0 | Time Dif: 7368.46
Pin State: 0 | Time Dif: 7368.61
Pin State: 0 | Time Dif: 7368.74
Pin State: 0 | Time Dif: 7368.86
Pin State: 0 | Time Dif: 7368.99
Pin State: 0 | Time Dif: 7369.12
Pin State: 0 | Time Dif: 7369.25
Pin State: 0 | Time Dif: 7369.38
Pin State: 0 | Time Dif: 7369.51
Pin State: 0 | Time Dif: 7369.66
Pin State: 0 | Time Dif: 7369.79
Pin State: 1 | Time Dif: 7369.92
Pin State: 1 | Time Dif: 7370.05
Pin State: 1 | Time Dif: 7370.18
Pin State: 1 | Time Dif: 7370.31
Pin State: 1 | Time Dif: 7370.44
(これは印刷中であることに注意してください。後ろにプログラムはこの値を読み取っている間ではなく実行を完了しました)
今まではそんなに良くなった。しかし、私が理解していない小さな問題が1つあります。時々、プログラムは数マイクロ秒をスキップします。これは、複数ビットの情報が失われるという意味なので、このユースケースでは大きな問題です。
Pin State: 0 | Time Dif: 7384.2
Pin State: 0 | Time Dif: 7384.33
Pin State: 1 | Time Dif: 7390.4
Pin State: 1 | Time Dif: 7390.53
ここに見られるように、ほぼ6マイクロ秒が速くなり、これは1.5ビットの情報が失われたことです。単にデバイスからポーリング要求を受信することはあまり問題ではありませんが、デバイスに情報を送信すると、すべてがめちゃくちゃになるのではないかと心配されます(デバイスはどのようなエラー修正も行いません)。 。
今私の質問は、これが起こらないようにする方法です。特定の優先順位でプロセスを設定または実行できるカーネル構成はありますか?私は試しましたが、chrt -rr 99 <program>
成功しませんでした。どんな助けでも大変感謝します。
答え1
SCHED_RRプログラムを予約する正しい選択をしました。
RTパッチを使用してIRQをSCHED_RRでスレッド化できるようにし、GPIOに関連するIRQスレッドの優先順位を上げたいと思います。
最終的には、「プログラム」を1つのコアに固定し、GPIO IRQスレッドを別のコアに固定し、別のコアに管理タスクを実行させる必要があります。
待つ時間のために値を印刷するのを忘れることもあります。後で使用するためにいくつかのtmpfsファイルに書き留めてください。