1つの解決策は、リングバッファで動作する独自のsprintf
を実装することです。残念ながら、これはより基本的な問題に関してあなたを助けません:あなたのリングバッファがいっぱいで、あなたがsprintf
を呼び出すなら、あなたはどうしますか?
あなたの記憶の状況は、私はこの問題の別の解決策をお勧めしたい、それを余裕がある場合は、次の
アイデアがバッファの2つのリンクされたリストに基づいています(空きバッファに1つのリスト、送信キューとして1個のリスト) 。バッファは、最悪の場合の長さの文字列を格納できるように、同じサイズです。バッファは単純なヒープを作成します。単純なヒープでは、割り振り/割り振り解除は、フリーまたは送信リストから要素をデキュー/エンキューするだけです。
同じサイズのバッファを使用すると、メモリを動的に割り当てるときに "checkerboarding"のような外部断片化の影響を受けないことが保証されます。この仕事のための独自のヒープを構築することは、送信タスクに利用可能な合計バッファサイズを完全に制御することにもなります。次のように
私は、このランニングを想像することができます:
- あなたがにデータをレンダリングするためにフリーリストからバッファを割り当てます。
- DMAについて
を送信キューに送信するデータを追加(および必要に応じて送信をトリガ)バッファ内のデータをレンダリングするために、あなたのレンダリング機能(suchasのはsprintf)を使用し、あなたを転送します転送終了IRQを処理します。そこでは、単に "フリーリスト"に転送されたバッファを移動し、キュー内の次のバッファへの転送を設定します。
このソリューションはメモリ効率が良いとは言えませんが、メモリに一度しか書き込むことはできません。割り当て/割り当て解除はどこかでポインタを取得/格納するためです。もちろん、割り当てと割り当て解除のためにアプリケーションとIRQとの間で競合条件が発生しないようにする必要があります。
多分このアイデアは、あなたの要件を解決するインスピレーションを与えます。
興味深い要望ですが、「適切なコピー機能で循環バッファにコピーしてから、一時バッファにフォーマットする」よりもはるかに優れているとは思いません。 –