2

SPI デバイスからのデータを処理する Raspberry Pi で C/C++ ユーザー空間アプリケーションを開発しようとしています。IRQ イベントで pthreaded 割り込みハンドラーから呼び出される関数 (実際の割り込みハンドラー) を登録するWiringPiライブラリ (関数wirePiISR ) を使用しています。

STL コンテナーはスレッド セーフではないと聞きましたが、コールバック関数の実行中にミューテックス ロックを設定し、そこにあるバッファー/コンテナーにアクセスするときにメイン スレッドをロックするだけで十分でしょうか?

配線PiISRを介して登録された私の「実際の割り込みハンドラ」は次のようになります

std::deque<uint8_t> buffer;

static void irq_handler()
{
    uint8_t data;
    while (digitalRead(IRQ_PIN)==0)
    {
        data = spi_txrx(CMD_READBYTE);
        pthread_mutex_lock(&mutex1);
        callback(data);
        pthread_mutex_unlock(&mutex1);
    }
}

static void callback(uint8_t byte)
{
    buffer.push_back(byte);
}

または、スレッド化された ISR とメイン スレッド間のデータ交換を実現する簡単な方法はありますか?

4

1 に答える 1

0

それは本当の ISR ですか? とにかくミューテックスは、優先順位の逆転につながるため、ISR には適していません。2 つのスレッドを使用して、通常のミューテックスの使用法を見てみましょう。

  1. スレッド A が実行され、mmutex が取得されます
  2. 何らかの理由で、スレッド A が横取りされ、スレッド B が実行されます。
  3. スレッド B はミューテックスを取得しようとしますが、取得できません。
  4. スレッド B がスリープ状態になり、スレッド C やスレッド A などの別のスレッドが実行できるようになります。
  5. ...
  6. ある時点で、スレッド A は再スケジュールされ、操作を再開し、mutex を解放します。
  7. スレッド B が再びスケジュールされると、ミューテックスを取得します。

ISR に関して言えば、シナリオは大きく異なります。ISR は優先度の低いスレッドを優先してスリープ状態になることはないため、ISR にいる間はミューテックスを所有するスレッドは実行されず、ポイント 3 から抜け出すことはありません。

したがって、本当の問題は、「IRQ ハンドラーを実行しているときに、他のコードを実行することは可能ですか?」ということです。そうしないと、デッドロック状態になります!

于 2013-12-08T12:39:18.327 に答える