我在我的大学使用ARM微控制器进行实时系统课程。在我目前正在进行的项目中,我正在实施矢量场直方图(VFH)算法。这两个中断服务程序中的竞态条件是什么?
问题是:我需要在线程之间进行通信;更具体地说,我想要一个线程从测距仪获取传感器数据,对其进行必要的转换并将它们存入队列。他们,另一个线程必须得到这些数据和处理它等等。
目前,我使用它的一个更简单的版本 - 一个线程从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个元素的阵列)。
这听起来像是某种溢出,但我无法想象它是如何发生的。有人可以帮我找到它吗?
我知道这个问题的答案是“使用线程安全的队列”,但我想了解的竞争条件是如何发生在这里,索引是如何得到搞砸了,等等。谢谢!
我会开始更换'平均+ =传感器[SensorsTail]; SensorsTail ++;'by'average + = Sensors [SensorsTail ++];'并声明头部和尾部指针是易失性的。也许序列点是一个障碍(在这里插入dmr rant ;-) – wildplasser