NOpE
NOpE

Reputation: 1

Avoiding Race Condition with event queue in event driven embedded system

I am trying to program stm32 and use event driven architecture. For example I am going to toggle a pin when timer interrupt occurs and transfer some data to external flash when ADC DMA buffer full interrupt occurs and so on..

There will be multiple interrupt sources each with same priority which disables nesting.

I will use the interrupts to set a flag to signal my main that interrupt occured and process data inside main. There will be no processing/instruction inside ISRs.

What bothers me is that accessing a variable(flags in this case) in main and ISRs may cause race condition bug in the long run.

So I want to use an circular event queue instead of flags.

Only ISRs will be able to write to event queue buffer and increment "head". Only main will be able to read the event queue(and execute instructions according to event) and increment "tail".

Since ISR nesting is disabled and each ISR will access different element of event queue array and main function will only react when there is new event on event queue, race condition is avoided right? or am I missing something?

Please correct me if I am doing something wrong.

Thank you.

Upvotes: 0

Views: 1318

Answers (1)

Tom V
Tom V

Reputation: 5470

If the interrupt only sets a variable and nothing gets done until main context is ready to do it then there is really no reason to have an interrupt at all.

For example: if you get a DMA complete hardware interrupt and set a variable then all you have achieved is to copy one bit of information from a hardware register to a variable. You could have much simpler code with identical performance and less potential for error by instead of polling a variable just not enabling the interrupt and polling the hardware flag directly.

Only enable the interrupt if you are actually going to do something in interrupt context that cannot wait, for example: reading a UART received data register so that the next character received doesn't overflow the buffer.

If after the interrupt has done the thing that cannot wait it then needs to communicate something with main-context then you need to have shared data. This will mean that you need some way of preventing race-conditions. The simplest way is atomic access with only one side writing to the data item. If that is not sufficient then the old-fashioned way is to turn off interrupts when main context is accessing the shared data. There are more complicated ways using LDREX/STREX instructions but you should only explore these once you are sure that the simple way isn't good enough for your application.

Upvotes: 0

Related Questions