Raspberry Piは9600ボーシリアルを確実にビットバンできますか?また、サンプルコードはありますか?


29

Raspberry PiのGPIOピンを介してビットバンギングを使用して9600ボーシリアルを駆動することがどのように実行可能かと思います。

明らかに、長時間(1〜10ミリ秒)CPUをブロックするドライバーやその他の割り込みが多数存在するため、Linuxはビットバンギングに適したプラットフォームではありません。ただし、最近は状況が大幅に改善されており、カーネルでプリエンプションが定期的に有効になっています。また、リアルタイムパッチを適用したカーネルをRaspberry Piで簡単に使用でき、接続されたハードウェアとドライバーを慎重に選択できると思います。

信頼性に関する私の基準は、ほとんどの場合、通常の9600ボーシリアルトレランス内に収まることです。現在、実際に許容できるエラーの数は不明ですが、プロトコルには再送信と確認応答があるため、少なくとも多少の許容範囲があります。

だから、私の質問は:

  • ユーザーランドソフトウェアは9600ボースピードを確実にビットバンできますか?
  • これにはリアルタイムのパッチが適用されたカーネルが必要ですか?
  • 一般に、いくつのエラーを予想する必要がありますか?

また、GPIOビットバンギングを介してシリアルを実行するサンプルコードはありますか?私はArduino SoftSerialを知っていますが、それはそれについてです。

念のため、質問を制限するために:これは標準のシリアルインターフェイスではなく、Raspberry PiのUARTは別のシリアルリンクに既に使用されています。外部ハードウェア(GertboardやArduinoなど)を示唆する回答も、UARTに依存する回答も希望しません。


1
+1良い質問です。これに対する答えにも興味があります。ただし、問題はreliabilityアクションと期待に依存します。
Jivings

2
RS-232には負の電圧が必要ですが、このシリアルリンクはRS-232電圧を使用しません。わからないが、RPiにはMAX232または多数の選択肢など、標準のTTLからRS-232へのコンバーターが必要だと思う。ただし、明確にするために、これは私の質問に関係ないので、答えたいだけです。
裸の

4
GPIOピン14と15にも2番目のUARTがあります。ただし、メインの機能ほどフル機能ではありません
ジョンラルーイ


1
@Nakedible作品を共有してもらえますか?似たような問題があるので、spiで2番目のシリアルをどのようにしたかを確認したいと思います。ありがとうMSP

回答:


15

私は最終的にこれを解決しましたが、かなり非正統的な方法で。私はビットバンギングをあまりにも信頼できないものとして放棄し、ハードウェアを追加せずに同じことを可能にする他のソリューションを見つけようとしました。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ボーシリアルリンクで確実に送受信できます。


@Nakedible-mmap()部分に少し詳しく説明したり、リンクを提供したりできますか?私は同じことに取り組んでいます。
ジェイK

SPIハードウェアを使用して送信も行っていますか?
チーター

はい、送信も同様に機能します。
裸の

3
コードを送受信する方法をステップごとに説明し、自分でパッチを適用したものを使用している場合は変更されたパッケージを共有してください... TIA!
バレンテット14

10

少なくともリアルタイムパッチ(CONFIG_PREEMPT_RT)がなければ、Raspberry Piは9600ボーシリアルを確実にビットバンできないと思われます。

Linux側のすべてを最適に設定するシンプルなレイテンシテスターを使用しました(sched_fifo、優先度99、cpu_dma_latench 0us、mlockall)。100 µsec(約9600ボー)スリープし、静かなシステムで2分間のレイテンシオーバーランをチェックしました。結果は次のとおりです。

最小:12マイクロ秒平均:24マイクロ秒最大:282マイクロ秒

これは一般的な結果のように見えました。最大値は、100 µsec〜300 µsecの低速測定で変化しました。分布も確認しましたが、大半は24 µsecの範囲にあるようです。50 µsecを超えるものはわずかですが、ほとんどの場合はいくつかあります。また、場合によっては4000 µsecなどの非常に大きなレイテンシもありますが、これらは無視できるほど一般的ではないため、少なくとも現時点ではそうです。

エラーが発生しないように9600ボーの最大レイテンシは50 µsec未満である必要があり、100 µsecを超えるレイテンシでは送信または受信でビットが完全に欠落します。

これはすべて、GPIOピンにまだ触れることもありません。私はわずか2秒でもクリーンランを取得できなかったため、リアルタイムパッチなしでは、Raspberry Piは9600ボーのシリアルリンクを深刻な時間でエラーを発生させずにビットバンできないと言っても安全だと思われます。

時間があれば、後でリアルタイムパッチをテストします。

(使用ツール:http : //git.kernel.org/?p=linux / kernel / git / clrkwllms / rt-tests.git ; a=summary

更新:CONFIG_PREEMPT_RTパッチセットでコンパイルされた場合、RPiカーネルはSDカードを検出せずにブート時にハングします。修正するのは簡単なことかもしれませんが、RPiソースの乱雑な差分を確認し、メインラインカーネルに追加されるまで待ちたいと思います。

それで、これをテストするのは難しすぎるので、私はそれを放棄しています。


0

あなたは強打する必要はありません。rx gpioでユーザーランド割り込みを設定して、開始ビットの立ち下がりを検出できます。次に、ビットの中央でサンプリングする時間割り込みを設定します。それを行うカーネルモジュールは実行可能です。


しかし、それはまだ少し強烈です。実際、これが通常の方法です。
フィリポス
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.