私は最終的にこれを解決しましたが、かなり非正統的な方法で。私はビットバンギングをあまりにも信頼できないものとして放棄し、ハードウェアを追加せずに同じことを可能にする他のソリューションを見つけようとしました。GPIOで割り込みをトリガーし、ピンをSPIに再構成し、SPIを使用してデータバイト全体を読み取るカーネルドライバーの作成を検討していましたが、より良いアイデアが得られました。
SPIを使用して、ボーレートの20倍でラインをサンプリングします。SCLKおよびSSピンを完全に無視し、RXラインをMISOに、TXラインをMOSIに接続します。これにより、RXラインにオシロスコープのような(1ビット)ビューが表示され、シリアルラインで送信されるビットが明確に表示されます。
00 00 00 00 00 00
00 00 00 00 01 FF
FF FF FF FF 00 00
01 FF FF FF FF FF
FF FF E0 00 00 00
00 00 07 FF FF FF
FF FF
このことから、実際のデータビットをサンプリングする正しい位置を把握することは、コーディングの簡単な問題です。送信側も同様に些細なことです。すべてのバイトを、開始ビットと停止ビットを含むビットの長いストリームに変換するだけです。
これがビットバンギングよりもうまく機能する理由は、SPIにはカーネルでフリーズしない独自のクロックがあり、SPI送受信ラインには転送用の16バイトFIFOがあり、これもカーネルフリーズから独立しているためです。9600ボーの場合、250kHzのSPIクロックを使用しているため、伝送エラーなしでFIFOの充てんと排出の間を1ミリ秒でもスリープできます。ただし、安全のために、私は300 µsのスリープを使用しています。これをどれだけプッシュできるかについて簡単にテストしましたが、少なくとも2MHzのSPIクロックがまだ使用可能であったため、このソリューションはより高いボーレートにも対応します。
このソリューションのoneい部分の1つは、カーネルSPIドライバーがこのようなストリーミングビット転送をサポートしていないことです。これは、カーネルSPIドライバーを使用して独自のカーネルモジュールを作成してこれを行うことはできず、ユーザーランドの/dev/sdidev0.0を使用してそれを行うこともできないことを意味します。ただし、Raspberry Piでは、mmap():n / dev / memを使用してユーザーランドからSPIやその他の周辺機器に直接アクセスでき、カーネル制御を完全にバイパスします。私はこれにそれほど満足していませんが、完璧に機能し、ユーザーランドのセグメンテーションフォールトがカーネルをクラッシュさせないという追加の利点を提供します(他の周辺機器を誤って混乱させない限り)。CPUの使用に関しては、300 µsのスリープによりCPU使用率は常に約7%になるようですが、私のコードは非常に最適ではありません。スリープ期間を長くすると、CPU使用率が直接低下します。
編集:言及することを忘れて、私は素敵なbcm2835ライブラリを使用してユーザーランドからSPIを制御し、必要に応じて拡張しました。
つまり、要約すると、Raspberry Piの250kHzで/ dev / memを介してSPIチップを直接使用することにより、ユーザーランドから完全に9600ボーシリアルリンクで確実に送受信できます。
reliability
アクションと期待に依存します。