大学のリアルタイム システム コースで ARM マイクロコントローラを使用しています。現在取り組んでいるプロジェクトでは、ベクトル フィールド ヒストグラム (VFH) アルゴリズムを実装しています。
問題は次のとおりです。スレッド間で通信する必要があります。より具体的には、距離計からセンサー データを取得し、必要な変換を行い、それらをキューに入れるスレッドが必要です。それら、別のスレッドがこのデータを取得して処理する必要があります。
現時点では、より単純なバージョンを使用しています。1 つのスレッドが ADC からデータを取得し (SensorAcquisitionHandler)、別のスレッドが最初の 5 項目 (最大) の平均をディスプレイ (ControlSignalHandler) に出力します。
/* Queue used to store data from the rangefinder sensors. */
static unsigned int Sensors[100];
static int SensorsHead = 0;
static int SensorsTail = 0;
void SensorAcquisitionHandler(void) {
/* Clear the interrupt. */
ADCIntClear(ADC0_BASE, 1);
int i; /* Index for the measurements buffer. */
/* There are only 3 rangefinders used. */
if (ADCSequenceDataGet(ADC0_BASE, 1, rangeBuffer) == 3) {
/* Put rangeBuffer's data into SensorDataQueue. */
/* Also, when using SensorDataQueue, must put what's the direction of
the corresponding range measurement. */
/* Critical section ahead!!! Turn off interrupts!!! */
IntMasterDisable();
/* Temporarily using the simple FIFO... */
for (i = 0; i < 3; ++i) {
if (SensorsHead < 100) {
Sensors[SensorsHead] = rangeBuffer[i];
SensorsHead++;
}
}
/* All is fine, turn on interrupts. */
IntMasterEnable();
}
}
void ControlSignalHandler(void) {
/* Clear the timer interrupt. */
TimerIntClear(TIMER0_BASE, TIMER_TIMA_TIMEOUT);
unsigned char i; /* Index for the measurements buffer. */
unsigned long average = 0;
char buffer[20];
/* Average first n (n <= 5) elements from Sensors queue. */
for (i = 0; i < 5 && SensorsTail < SensorsHead; ++i) {
average += Sensors[SensorsTail];
SensorsTail++;
}
IntMasterDisable();
average /= i;
sprintf(buffer, "%d ", average);
average = 0;
if (SensorsTail >= SensorsHead) {
SensorsTail = 0;
SensorsHead = 0;
}
Display96x16x1StringDraw(buffer, 0, 0);
IntMasterEnable();
}
結果はしばらくの間比較的安定していますが、ランダムな間隔で非常に高くなります (結果はほぼ常に ~330 です)。また、「非常に高い値」の瞬間にシンボリック デバッガーを使用すると、SensorTail と SensorHead のインデックスが 300 以上になることがあります (キューは 100 要素の配列です)。
これはある種のオーバーフローのように聞こえますが、それがどのように起こっているかを視覚化することはできません. 誰かがそれを見つけるのを手伝ってくれますか?
問題に対する答えは「スレッドセーフなキューを使用する」ことだとわかっていますが、ここで競合状態がどのように発生しているか、インデックスがどのように混乱しているかなどを理解したいと思います。ありがとう!