Preferred way to ensure thread executes without interruption

Hi,
I have to threads not related to each other:
Thread A, when called, I don’t want it to be interrupts at all during a long portion of code execution.
Thread B, I want it to be interrupted only by one or two higher priority interrupts but NOT by same priority ones.

What is the preferred way to implement the to separate solutions?

I was thinking of dynamically changing the thread priority but not too sure how to do that and most important whether there are better solutions.

Any suggestions or guidelines?

Thank you :slight_smile:

There is a function to set the task priority (vTaskPrioritySet) if that is what you want to do, and that might be what needs to be done to handle your requirement.

Note, you need to #define INCLUDE_vTaskPrioritySet 1 in order to include the code for this into FreeRTOS.

If TaskA and B are not related why not just giving TaskA the highest prio ?
I’m not sure what you mean by TaskB interrupted by higher priority interrupts.
Interrupt and task preemption are not the same thing as interrupt priority is not related to task priority…
Dynamically changing task priorities is not commonly used because this can make the application/it’s behavior more complicated. I’d think twice if this is the right way to go.

Hartmut, the issue is that if, because of say an interrupt occurs, and a higher priority task becomes ready that causes Task A to be switched from, then when that higher priority task blocks again, FreeRTOS might move to another task of that same priority. Rik001 wants whichever task started first to run to completion before the other task gets time, and, at least currently, that requires that they have different prioritues.

I suspect, that what he then wants is that after Task A finishes, and Task B start, that Task B now needs higher priority than A because he want IT to finish before a starts to run again.

The one question that comes to my mind, is if this really is a hard and fast rule, maybe it would be better to have one task AB, that calls either function A when it needs to do operation A and wait for B, or function B when it needs to do operation B and wait for A.

Often, when you have two tasks that you define can never be doing stuff at the same time, that might say that they really should be the same task.

you may want to look at true cooperative multitasking (ie set configUSE_PREEMPTION to 0) in conjunction with equal pri tasks. It forces the tasks to voluntarily yield control.

Thanks Richard - got it :slight_smile: Although it’s still not crystal clear to me what Rick001 really needs/want’s to achieve…

Thank you Richard and Hartmut.

To explain in more details I have a series of stepper motors and for each of them a (large!) number of piezo micro-nozzles similar to a inkjet printer. The numbers of micro nozzles is 1280 and data controlling each of them is shifted serially at high clock rates, nevertheless, it does take quite a bit of time (variable depending on other circumstances).

Bottom line I need to:

  1. start the stepper motor PWM so it moves the motor in parallel in the background while step 3 below happens.
  2. the stepper needs to be moved only x number of steps so at every pulse the interrupt routine decreases a counter and once it reaches zero it disable the PWM
  3. the moment step 1 happened, the loading of the data into the nozzle serial registers begins so that it occurs while the stepper is moving forward
  4. Only after BOTH have completed then the “main” task can move on. The “main” task can be the same one that does the shifting or perhaps a separate one. Still haven’t worked that out, so any suggestions on that is also welcomed (this looks like what Richard suggests with Task AB).

Being a beginner in RTOS I might not be totally clear on the principles/philosophy or RTOS system so most likely missing some important understanding… :slight_smile:

Thank you

For me it sounds like the stepper and the nozzles are not really/completely independent and need to be controlled in a synchronized/coordinated way.
Task separation pays off best for independent / loosely coupled work.
Maybe their work can be done somehow interleaved in 1 task as Richard proposed.
I think it would help a lot if the nozzle data can be DMAed out of the serial interface i.e. truly simultaneously / in background. Is it ?

To me it sounds like ‘main’ needs to block on something until it is told to go on.

Alternatively, one of the operations runs in the main task, but perhaps in an function in a separate file.

My own design method would be to define an API in a header file, which defines a function that main calls to perform the operation and return whan done. The API provides design isolation. The function then can activate the needed operation, and either block or use this task for part of it.

Thank you both.

I forgot to re-mention that during those two tasks I don’t want any other threads to interrupt until those two have completed. That was one of my my main point in my OP. i.e. I don’t want USART, Ethernet or other to interrupt. Hence asking about the priority and locking all other tasks until these two (or three is a third one is used to manage those two) have completed.

Does that change anything in your two replies above?

Hartmut, yes, DMA might help. I am not familiar with it and whether it can do serial shifting but am reading now following your suggestion. And hopefully it will also help in the performance.

Thank you

The way you keep other tasks from interfering is you give the task a high priority. If the task is blocked it won’t use up time, but when unblocked it will get time.

Hello All,
My below response is with regards to the comment:

I have also recently started working with FreeRTOS. I assume that calling vTaskSuspendAll() from the currently executing task (be it Task A or Task B) (when it starts execution) may be a solution.

Further depending on the required implementation the Task A after completion (and just before going into BLOCKED STATE) may wake up Task B and vice versa.

Thanks,
Rajeev