Confused about how task works

paparika wrote on Tuesday, December 11, 2018:

Hi, I’m a beginner for FreeRTOS. I have learned that there are 4 states for a task: running, suspended, ready and blocked. I have questions about how task works.
Can a task be suspended at anytime? What exactly happens when a task is suspended from running state? I find it’s hard for me to understand you can just suspend the process when it’s in the middle of something. AFAIK, for a java program, you may interrupt a thread only when it’s blocked. I mean if the task is suspended when it’s in the middle of operating some peripherals, so it just leave the peripheral in an unknown status there?

richarddamon wrote on Tuesday, December 11, 2018:

Not familiar with Java threading, but if Java can only interrrupt a thread when blocked, that sounds like that would be the FreeRTOS Non-Premptive mode.

In FreeRTOS, the current Task will continue to run until one of several thigs happen:

  1. The task makes a call that makes it block or yield, in which case the schedule will find the new highest priority ready task.
  2. The task makes a call that moves another, higher priority task, into the ready state, at which point the scheduler will switch to that task.
  3. An interrupt occures (including the tick interrupt) which moves another higher priority task to the ready state or which suspends the current running task, and then runs the scheduler to switch to the new highest priority task. (In Non-Preemptive mode, the tick interrupt will not call the scheduler).

At the hardware level, the CPU can generally be interrupted between almost any instruction, so the last case can happen just about anywhere. If there are short sections of time when you want to prevent this sort of switch, you use a critical section which will disable the interrupts, allowing the action to complete uninterrupted.

Generally, any shared resource should be protected in some way from multiple tasks trying to manipulate it at the same time. This can be with a critical section for short manipulations or using something like a mutex (or other locking primative) to get exclusive access. Following this rule, if a task gets suspended (or even just moved ffrom running to ready due to a higher priority task becoming active) in the middle of working with a device, the device isn’t in an ‘unknown’ state, but is in a state where it is ‘owned’ by that task, and when the task resumes, it will continue its actions, and any other task attempting to use it will find that it is busy. If the device can’t take the pause in its use, then the update needs to use a critical section that prevents the system from switching to another task.