Interrupt Processing

I am reading Section 3.2 “Deferred Interrupt Processing” of FreeRTOS book Assuming the tick is 10ms (configTICKRATEHZ = 100) According to the book, when an external event happens, the ISR “gives” semaphor to the handler task in order to unblock it (I suppose ISR can accomplish this within sub-millisec) Now the questions is: would the handler task gets unblocked immediately, or it is only unblocked when the next tick interrupt (which is 10ms) happens?

Interrupt Processing

If Pre-emption is turn on, the unblocked task is now the highest priority ready task, and the ISR is written correctly (it activates the scheduler due to seeing the higher task woken flag), then the handler task will start immediately.

Interrupt Processing

Ok.. which means the task handler will not wait for the tick interrupt to trigger it?

Interrupt Processing

Exactly

Interrupt Processing

Now I’m confused. Refer to below scenario, assuming configTICKRATEHz = 100 (or tick interrupt of 10ms) Assuming task_1’s 5000ms expires and it wakes up, but then is almost immediately Blocked because of waiting for the mutex Then now task_2 gives the mutex Will (a) task_1 get the mutex *immediately* and goes into Running, or (b) it will *wait* until the current tick (10ms) period is up and the scheduler select it to run? I would suppose the answer is (b), because the Scheduler only executes at the end of each tick interrupt. Am I right? If I am right, then this scenario is in contrary with the scenario in my previos message, where the task handler gets Unblocked immediately, and start executing** immediately** ~~~ static void task1(void *p) //Priority: 2 { (void)p; for (;;) { if (dispmutextake()) { … dispmutexgive(); } ossleep(5000); } } ~~~ ~~~ static void task2(void *p) //Priority: 1 { (void)p; for (;;) { … if (dispmutextake()) { … dispmutex_give(); } } } ~~~

Interrupt Processing

Also in this scenario task2 goes into running state as soon as higher prio task1 falls asleep. Provided that your os_sleep is not a busy wait 😉 The scheduler is and obviously should be invoked on each task state transition.

Interrupt Processing

You incorrect assumption was that the scheduler only runs on the tick interrupt. On part of releasing a mutex is to see if any higher priority tasks were made ready, and if so, the scheduler is run, causing a context switch. The scheduler is run anytime the current task blocks, something happens that makes a higher priority task become ready, or (if time slicing is enabled) on a tick interrupt (to cause time slicing).

Interrupt Processing

@Richard: thanks for pointing out! I total missed the points Question: so time-slicing is used only when there are tasks with same priority?

Interrupt Processing

The system alway tries to run a highest priority ready task. Thus, you will only time slice between tasks of the same priority. Low priority in a RTOS sense doesn’t mean give it less time, it means give it time only if nothing higher is ready. As far as I know, the only case where a highest priority ready task would not be running is if Pre-emption is turn off, then the current task will continue to run, even if some interrupt makes another task ready, until the current task makes a call to a FreeRTOS function that can perform a context switch, the the switch will occur.

Interrupt Processing

Yes. I’d also recommend to have a look at the (free !) books e.g. Mastering the FreeRTOS Real Time Kernel chapter 3.12 Scheduling Algorithm s

Interrupt Processing

In this example time-slicing is enabled. Task1 & Task2 are continuos processing tasks with same priority (1). Another periodic task which uses vTaskDelayUntil(), is of higher priority (2). It was explained in the book that “At time t5 the** tick interrupt finds that the Periodic task block period has expired **so it moves the Periodic task into the Ready state” Q. Why is it that, the Periodic task enters Ready state only when the tick interrupt expires? It is of higher priority, and isn’t it supposed to be “event-driven” by the its own “periodic timer”, rather than the tick interrupt timer (I thought tick interrupt is only for tasks with same priority)? Or am I wrong altogether? Another question not related to this example: if configUSETIMESLICING = 0, would the tick interrupt still happens?

Interrupt Processing

All ttime periods are measured in ‘Ticks’, by the tick interrupt. vTaskDelay/vTaskDelayyUntil establish what count of the tick iinterrupt will put the task in a ready state. Many machines don’t have enough hardware timers to give tasks their own hardware timer, so FreeRTOS uses the Tick interrupt using the one timer that it needs to perform ALL its time base services. You should note that all delays/timeouts in FreeRTOS are specified in ‘Ticks’, which is the time period of the Tick Interrupt.

Interrupt Processing

Ok.. but what happen if the tick interrupt period is for example 10ms. And there is a event-driven task which must be put into Ready state within 1ms when the event arrives?

Interrupt Processing

..or put it another way. The tick is 10ms. So the interrupt happens at t=0, 10ms, 20ms, … Task1 (Priority 1) is periodic with period 2ms, Task2 (Priority 2) is event-driven by external event vTaskScheduler() is started at t=0 Q1. Would Task1 be in Running state at t=2ms, 4ms, 6ms…? Q2. Would Task2 be in Running state at, for example t=21ms, when the external event happens?

Interrupt Processing

You need something to happen for it to be an event. If you really need a task to run at a periodic rate of 2ms, and there isn’t some hardware interrupt about that event that happens at that rate, then youu better have the system tick be at 500 Hz (or some multiple thereof). YOU define the tick rate via FreeRTOSConfig,h, so it is part of your system definition, and need to be set appropriate for youur system needs, Not to fast to spend too much time processing the tick interupt and checking for periodic task scheduling, but also not to slow to not have a time base accurate enough to meet your needs. Myy experiance is that 10ms is fine to deal wiith Human Interactions, and tends to give good enough resolution for error timeouts, and that many things that need to be faster have interrupts that can trigger the operations. The one case where I find I need a faster tick would be a process control loop, to start sampling the system and updating the control, but even then, often there is a way to program the measurement to automatically kick itself off at the desired rate, and then I can use the conversion complete interrupt to kick off that process (which removes the jitter in the sampling time, which tends to reduce noise issues). So the question goes back to, your 2ms periodic task, is it purely a time based process, in which case you need a 500Hz tick rate, or is it tied to some hardware that can be told to run at 500Hz, and generatte interrupts to tthe processor, in which case your task isn’t really a ‘periodic’ task, but an event driven task.

Interrupt Processing

Ok so my understanding is:
  • To have a 2ms period software time-based task, I need to configure the tick to be at least 500Hz. This will make 2ms the smallest time unit for any other time-based tasks. All time-based tasks thereof must have period which is multiple COUNT of ticks (1x, 2x..)
  • Context switching can always happen between the ticks (eg. t = 3.1ms) when, i) a periodic task (with period 2ms) gets Blocked after running for 1.1ms, and a lower priority continuous process task gets switched in* immediately*, ii) an external interrupt happens at t = 3.1ms, and make another higher priority task Ready, and thus it gets switched in immediately, iii) a higher priority task which is currently Blocked, gets unblocked when it receives a mutex at t = 3.1ms, and thus it gets switched in immediately All the above 3 cases, the scheduler selects the new task to Run immediatly even before the next tick happens (ie. t = 3.1ms). Am I right?
Another question on the mechanism of taking and giving a semaphore: When Task1 calls xSemaphoreGive, Task2 (which calls xSemaphoreTake) gets “notified” immediately, right? How is this implemented? Does xSemaphoreGive() invokes an interrupt or something like that?

Interrupt Processing

Yes, All time delays are specified in Ticks, so any period needs to be based on a multiple of ticks. Assuming you have pre-emption enabled, then a context switch can be triggered by an interrupt, or a system call. For instance, calling a Delay function will always invoke a context switch. Giving a semaphore or mutex or putting or taking an item from a queue might also cause a context switch if the action makes ready a higher priority task. Depending on the processor and the port, this MIGHT be done by triggering an software interrupt, or it might not.

Interrupt Processing

or just use the source the see what’s going on 🙂 That’s another good thing about FreeRTOS besides that it’s free – you get the complete (high quality) code !