Passing data into interrupt service routine


I have been developing a control software (based on FreeRTOS) for field oriented control of three phase induction motor. My plan is to calculate the whole torque control loop in the interrupt service routine (ISR) associated with the “end of the A/D conversion” interrupt which will be invoked regularly with 100 us period. Besides the torque control loop the associated ISR will be also responsible for implementation of software oscilloscope. Operation of the software oscilloscope will be configurable in such a manner that it will be possible to set how many samples are reserved for the pre-trigger, to set the trigger variable and trigger condition (given variable greater than or less than the specified value).

My question is how to pass the oscilloscope configuration into the ISR (more precisely into the oscilloscope module which is invoked from the ISR) from a FreeRTOS task in such a manner that it is ensured that in all cases the oscilloscope works with consistent configuration i.e. always “new” pre-trigger setting, “new” trigger variable and “new” trigger condition are used together (it is not allowed to use let´s say “new” pre-trigger setting, “new” trigger variable with “old” trigger condition).

My first idea was to exploit the FreeRTOS queues for data exchange between ISR and FreeRTOS task. I have found that the functions xQueueSendToBack and xQueueReceive disabling interrupts for some not negligible time. I am afraid of deterioration of torque control loop parameters due to transport delay insertion resulting from interrupt disabling.

Could anybody recommend me some proven solution for exchanging data between ISR and FreeRTOS task suitable for my purposes? Thanks in advance for any suggestions.

You could use 2 structs containing the trigger settings and 1 shared pointer to one of them. Setup the config in the shadowed struct and atomically switch the current pointer e.g. by using taskDISABLE/ENABLE_INTERRUPTS.
That’s the fastest way in the sense of minimal interrupt disable time.
Alternatively you can also directly modify shared trigger config data enclosed by taskDISABLE/ENABLE_INTERRUPTS.

1 Like

Hello Hartmut Schaefer, thank you for elegant solution.

If the writing of a pointer value is atomic on the processor (and it often is), you don’t even need the taskDISABLE_INTERRUPTS.