views:

240

answers:

4

This is actually a design question for firmware in an embedded system I have two ISRs (of same priority) executed independently . These ISRs are triggered when the h/w generates data. I want a mechanism which must be put in place to synchronise between task1 and task2. task 2 must know about the certain values calculated in task1 which must then be taken into account while computing certain values in task2. I don't have OS primitives to use ie the system does not have any Operating system. Task1 is executed within the context of ISR1 and task2 within the context of ISR2. The processor which we use is a STMicroelectronics 32 controller

EDIT: additional info The processor is connected to certain IPs which trigger interrupts when they are ready with data. These IPs act as type of Accumulators on input streaming frame data.

+1  A: 
  • Disable interrupts before reading or writing to the shared values
  • Re-enable interrupts after reading or writing to the shared values
Matthew Murdoch
+2  A: 
Adriaan
Could you make your illustration larger, please?
Matthew Murdoch
done. Accidentally had a link to a thumbnail....
Adriaan
Great, thank you!
Matthew Murdoch
+1 for the diagram.
pierr
+4  A: 

I wouldn't do heavy processing in interrupt context, just read the data and set a flag.

The flags can then be checked in a simple scheduler in the main loop to execute the tasks as necessary. So tasks can't interrupt each other and can't see inconsistent output of the other task.

A task could also set such a flag to activate another task. E.g. Task1 could activate Task2 because Task2 needs values from Task1.

For the data that is read in the ISR you need some buffer. Depending on the timing of your incoming data that might be a ring buffer or a double buffer.

starblue
+2  A: 

I'm coming at this from a standpoint of no OS, no real framework other than C and registers and such. The way I would do it is to have a state variable for each ISR that can be seen by the other ISR. Then when you enter ISR1 you just check the state of ISR2's task and operate as necessary. Then ISR2 gets called and checks its own state and ISR1's state and operates as it sees fit. I'd use an ENUM in a header file to enumerate the states for clarity (INIT, WAITONDATA, etc) and then a switch in the ISR to handle each state. Then you just have to make sure that the data that needs to be shared can be seen by both ISRs and you're set.

Of course as others have said you don't want to do many calculations in ISRs. You just want to set a flag that an event has occurred or some data is present and then handle the data in the main loop. Then your system isn't blocked for too long handling an ISR. You do this in the same way - a state variable that can be seen in the main loop (or at least the function you call to do the data manipulation FROM the main loop) and the ISR. Change its state in the ISR and check that state in the main loop function. Do chores as needed.

Don't forget - if you are updating variables in ISRs they must be defined as volatile!

volatile uint8 state = INIT;

for example.

Stephen Friederichs