sprintf
解決策の 1 つは、リング バッファで動作する独自の実装を行うことです。残念ながら、これはより基本的な問題に関しては役に立ちません: リングバッファがいっぱいで を呼び出したらどうしますsprintf
か?
メモリの状況に余裕がある場合は、この問題の別の解決策をお勧めします。
このアイデアは、バッファの 2 つのリンクされたリストに基づいています (1 つのリストはフリー バッファ用、もう 1 つのリストは送信キューとして)。バッファーは同じサイズであるため、最悪の場合の長さの文字列を格納できます。バッファは単純なヒープを構築します。割り当て/割り当て解除は、空きリストまたは転送リストから要素をデキュー/エンキューするだけです。
同じサイズのバッファーを使用すると、メモリを動的に割り当てる際に、"チェッカーボード" などの外側の断片化の影響を受けないことが保証されます。このジョブ用に独自のヒープを構築すると、送信タスクに使用できる合計バッファー サイズを完全に制御することもできます。
これが次のように実行されていると想像できます。
- フリー リストからバッファを割り当てて、データをレンダリングします。
- レンダリング関数 (sprintf など) を使用して、バッファー内のデータをレンダリングします。
- 送信するデータを送信キューに追加します (必要に応じて送信をトリガーします)。
DMA 転送の場合、転送終了 IRQ を処理します。そこで、転送されたバッファを「空きリスト」に移動し、キュー内の次のバッファの転送をセットアップします。
このソリューションはメモリ効率が最も高いわけではありませんが、メモリへの書き込みは1回だけで、割り当て/割り当て解除はどこかにポインタをフェッチ/保存するだけなので、ランタイム効率は良好です。もちろん、割り当て/割り当て解除のために、アプリケーションと IRQ の間で競合状態が発生しないようにする必要があります。
おそらく、このアイデアは、要件を解決するためのインスピレーションを与えるでしょう。