1

In my firmware I write to MicroSD in a background task, and I've got a lot of higher-priorities interrupts enabled, some of which can take several milliseconds.

So the writing/reading from SPI can be interrupted at any moment, and for writes that may not be such a problem (if SPI behaves anything like UART), but during reads I'm afraid that my hardware SPI FIFO's will overflow if the task just happens to be interupted while the MicroSD card is sending a datablock.

Now the obvious solution would be to decrease the time that the higher priority interrupts take, but this seems very hard, because sometimes they have to wait on other peripherals too, and too prevent that I have to rewrite a lot of code that does polling now, to an interrupt-structure, which would make the overall code much more complicated.

I think in modern OSes this is solved by letting all those tasks run synchronously at the same priority, and give them all an equal time slice. But I don't have any mechanisms for threading, or an OS, so what would be the simplest way to solve this?

4

2 に答える 2

4

MicroSD への書き込み [...] ハードウェア SPI FIFO がオーバーフローする

あなたはSPIのマスターです。SPI クロックを制御します。SPI マスターは、転送するデータ フレームがある場合にのみクロック信号を生成します。それ以外の場合、クロックはアイドル状態になります。これは読み取り操作にも当てはまります。SPI は常に読み取りと書き込みを同時に行います。

つまり、あなたがマスターであれば、SPI がオーバーフローすることはありません。ハードウェア FIFO はこの事実を変更しません。

于 2013-02-02T17:47:07.840 に答える
0

「現代のOSでは、これらすべてのタスクを同じ優先度で同期的に実行し、すべてに等しいタイムスライスを与えることでこれが解決されると思います。しかし、私はスレッド化のメカニズムやOSを持っていません。これを解決する最も簡単な方法は?」

OS でのマルチタスクは、割り込みと同じではありません。

私は次のようにレイアウトします:

読み書き用の SPI 割り込みハンドラ。知っておく必要がある SPI FIFO があります。オーバーフローおよび「ウォーターマーク」状態で割り込みが発生する場合があります。これらを確実に処理してください。詳細については、MCU ユーザー ガイドをお読みください。ソフトウェアで割り込みハンドラに独自の循環キューを与えます。FIFO のサイズを考慮して、キューのサイズを適切に設定します (これは、ハードウェア FIFO のサイズ、読み書きするデバイスのページ サイズ、および使用可能なメモリに基づいて選択します)。

アプリケーションから呼び出されるステート マシン モジュール。これには独自の循環キューが必要です。ステート マシンには、データの読み取りと書き込みを行う関数と、「ポンプ」関数 (つまり、メイン ループから定期的に呼び出される関数、つまり、メイン ループから「スケジュールされた」関数) が必要です。

SPI デバイス ステート マシンから読み書きする「タスク」もステート マシンである必要があり、書き込みできない場合やデータの準備ができていない場合にも対処できる必要があります。一般に、ブロックしないでください。必要なものが準備できていない/利用できない場合は、後で呼び出されることを期待して終了するように関数を記述します。つまり、後で「スケジュール」されます。

したがって、一般的な流れは次のようになります。

[書き込みたいタスク]→キュー→[デバイスステートマシン]→キュー→[SPI割り込み]→ハードウェアキュー→[ハードウェア]→ワイヤ

ワイヤー -> [ハードウェア -> ハードウェア キュー -> [SPI 割り込み] -> キュー -> [デバイス ステート マシン] -> キュー -> [読み取りたいタスク]

アーキテクチャの詳細がなければ、詳細を提供するのは困難です。しかし、私はこのパターンを多くの組み込みデバイス ドライバーでうまく使用してきました。

于 2013-02-02T18:02:07.773 に答える