6

PC シリアル ポート (115200 ボー) から大きなファイルをダウンロードし、SPI (~2 MHz) 経由でシリアル フラッシュ メモリに書き込む必要があるマイクロコントローラーがあります。フラッシュ書き込みは、書き込みコマンドとページ アドレスが先行する 256 バイト ブロック内にある必要があります。システムで使用可能な RAM の合計は 1 kB で、スタック サイズは 80 バイトです。

これは現在、UART から 256 バイト バッファを埋めてから、別の 256 バイト バッファにピンポンすることで機能しており、フラッシュがビジー書き込みで書き込まれている間に、RX バッファ準備完了信号の割り込みによって埋められています。バッファのスワッピングは、操作が完了するまで繰り返されます。

個別の循環バッファーで動作する SPI ポートと UART ポートの両方に TX/RX 割り込みハンドラーをセットアップすることをお勧めします。したがって、新しいバイトをポーリングして操作が完了するのを待つ代わりに、単純に TX バッファーを埋めて割り込みを有効にするか、着信データのバッファーをチェックすることができます。これにより、周辺機器を待機する代わりに、実際の作業により多くのクロック サイクルが提供されます。

128 バイトの循環バッファーを使用して IRQ を実装した後、UART RX バッファーでデータをポーリングし、すぐにそれを SPI TX バッファーに配置してファイル転送を行います。このアプローチで私が抱えている問題は、バッファ用に十分な RAM がなく、データをフラッシュ送信バッファに転送するよりも早く PC 受信バッファがいっぱいになることです。明らかに、転送速度は問題ではありません (入力 115.2 kHz、出力 2 MHz) が、256 バイトのページが送信されるたびに書き込みサイクルの待機が発生します。


頻繁な SPI 割り込みが UART 割り込みの一部をブロックし、バイトが失われているようです。私が選択した解決策は、UART 受信割り込みにリング バッファーを使用し、データを 256 バイトのページ バッファーにフィードすることでした。このページ バッファーは、バイト転送と書き込み完了をポーリングすることによってシリアル フラッシュに送信されます。128 リング バッファは、SPI 書き込み中のオーバーフローを防ぐのに十分な大きさです。

4

4 に答える 4

4

アプリケーションのUARTとPC側はRS-232ハンドシェイク(フロー制御)をサポートしていますか?その場合、受信バッファがいっぱいに近づいたら、ISRにCTSラインをドロップさせます。PC側がハードウェアフロー制御を尊重するように構成されている場合は、この状態が発生したときに送信を停止する必要があります。受信バッファを空にした(またはほとんど空にした)後、CTSを再度アサートすると、PCは送信を再開する必要があります。

これにより、組み込みデバイス上のソフトウェアがかなり複雑になることに注意してください。それがトレードオフであるかどうかは、あなたとあなたのマネージャーおよびチームが分析を行う必要があります。

于 2008-12-11T15:49:14.717 に答える
4

これはまさにフロー制御が作成された目的です。私はその大きな苦痛が設定されていることを知っていますが、シリアルラインでフロー制御を有効にすると、問題は履歴になります。

バイナリファイルを転送していると想定しているため、XON-XOFFは最適なソリューションではなく、ハードウェアフロー制御が残ります。

もう1つのオプションは、XModemなどの組み込みフロー制御を備えたプロトコルを使用することです。フラッシュが128バイトのページで書き込まれる同様の組み込みプロジェクトがあります。XModemが128バイトのチャンクでデータを送信し、次のデータを送信する前にACKを待機するのは偶然です。

于 2008-12-11T15:50:07.397 に答える
3

PCでスキャッターギャザーのようなことをします。次のような構造体のリンクリストを作成します。

typedef struct data_buffer {
    char flags;
    char[128] data;
}

フラグのビットの1つは「ReadyToFlash」を意味し、もう1つは「Flashing」を意味します。リンクリスト内のバッファの数を調整して、フラッシュが書き込み時にUARTをキャッチしないようにするか、またはその逆を行うことができるはずです。

フラッシュが「ReadyToFlash」ではないバッファブロックに到達すると、フラッシュが停止するため、UARTIRQでフラッシュを起動する必要があります。UARTが「ReadyToFlash」または「Flashing」のブロックに到達した場合、それは急速にいっぱいになり、おそらく別のバッファーが必要です。動的メモリがある場合は、実行時にこの調整を行い、その場でリストにバッファーを追加できます。 、それ以外の場合は、いくつかの経験的なテストを行う必要があります。

于 2008-12-11T16:24:22.757 に答える
1

ここで何が欠けているのかわかりませんが、PCからのデータの平均レートが、フラッシュに書き込むことができる平均レートよりも高い場合は、大量のRAMが必要になります。 、またはフロー制御が必要になります。

しかし、ブロックバッファーがある場合は機能したと言っていますが、バイトバッファーがある場合は、機能しません。

UART RX割り込みで満たされるブロックバッファを使い続けることができますか?各バッファがいっぱいになったら、SPI / Flashコードに渡して、SPI割り込みを使用してそのバッファを空にしますか?これにより、各バイトをコピーする手間が省けます。また、バイトごとに循環バッファロジックを2回実行する代わりに、ブロックごとに実行するだけで済みます。

于 2008-12-11T16:05:04.670 に答える