OS Scheduler Interval Timer - Where does it run? How to interact with it? - process

As it relates to process scheduling by the OS: I understand that the scheduler requires a "clock" like device, known as an interval timer, to keep track of the amount of time used by each process and when to switch to a ready process.
My question is - where does the interval timer run? It seems like it needs to be running constantly, parallel to any processes, so that it can always keep track of time, including the amount of time being used by the running process. But as we all know only one thing can run on a CPU at any one time, and if the process is running, it means the interval timer cannot run. So therefore, is the interval timer implemented in hardware rather than software? And if so, if I was building a custom OS and scheduler, how would I access and communicate with it in my custom scheduler code?

The "interval timer" as you call it is a hardware timer. It generates an interrupt at a fixed period. When the "RTOS tick" interrupt occurs, the tick handler (typically):
increments the tick counter,
updates any running software timers,
if a task delay or software timer expires, any task blocked on that becomes ready,
the scheduler is run, the highest priority ready task runs.
Note that this is not the only time the scheduler runs. For example scheduling occurs whenever a task explicitly suspends on a delay, timer, semaphore, mutex, event flag, or mailbox for example. Any RTOS call that causes the running task to block/wait causes the scheduler to run.
And if so, if I was building a custom OS and scheduler, how would I access and communicate with it in my custom scheduler code?
You would simply configure the hardware timer to generate the tick interrupt and proceed as above. You might take a look at an existing open-source RTOS to see how it is done. Although FreeRTOS which you tagged is not exactly conventional, uC/OS-II may be a better starting point - it is deliberately simple and was originally implemented to teach RTOS design and implementation. The associate book describing the kernel is freely available in PDF form at https://weston-embedded.com/micrium-books.

Related

difference between non preemptive and cooperative and rate-monotonic scheduler?

I have Read about co-operative Scheduler which not let higher priority task run till lower priority task block itself. so if there is no delay in task the lower task will take the CPU forever is it correct? because I have thought the non preemptive is another name for cooperative but there is another article which has confused me which say in non preemptive higher task can interrupt lower task at sys tick not in the middle between ticks so what's correct ?
is actually cooperative and non preemptive are the same?
and Rate monotonic is one type of preemptive scheduler right?
it's priority didn't set manually the scheduler Algo decide priority based on execution time or deadline it is correct?
is it rate monotonic better than fixed priority preemptive kernel (the one which FreeRtos Used)?
These terms can never fully cover the range of possibilities that can exist. The truth is that people can write whatever kind of scheduler they like, and then other people try to put what is written into one or more categories.
Pre-emptive implies that an interrupt (eg: from a clock or peripheral) can cause a task switch to occur, as well as it can occur when a scheduling OS function is called (like a delay or taking or giving a semaphore).
Co-operative means that the task function must either return or else call an OS function to cause a task switch.
Some OS might have one specific timer interrupt which causes context switches. The ARM systick interrupt is suitable for this purpose. Because the tasks themselves don't have to call a scheduling function then this is one kind of pre-emption.
If a scheduler uses a timer to allow multiple tasks of equal priority to share processor time then one common name for this is a "round-robin scheduler". I have not heard the term "rate monotonic" but I assume it means something very similar.
It sounds like the article you have read describes a very simple pre-emptive scheduler, where tasks do have different priorities, but task switching can only occur when the timer interrupt runs.
Co-operative scheduling is non-preemptive, but "non-preemptive" might describe any scheduler that does not use preemption. It is a rather non-specific term.
The article you describe (without citation) however, seems confused. Context switching on a tick event is preemption if the interrupted task did not explicitly yield. Not everything you read in the Internet is true or authoritative; always check your sources to determine thier level of expertise. Enthusiastic amateurs abound.
A fully preemptive priority based scheduler can context switch on "scheduling events" which include not just the timer tick, but also whenever a running thread or interrupt handler triggers an IPC or synchronisation mechanism on which a higher-priority thread than the current thread is waiting.
What you describe as "non-preemptive" I would suggest is in fact a time triggered preemptive scheduler, where a context switch occurs only in a tick event and not asynchronously on say a message queue post or a semaphore give for example.
A rate-monotonic scheduler does not necessarily determine the priority automatically (in fact I have never come across one that did). Rather the priority is set (manually) according to rate-monotonic analysis of the tasks to be executed. It is "rate-monotonic" in the sense that it supports rate-monotonic scheduling. It is still possible for the system designer to apply entirely inappropriate priorities or partition tasks in such a way that they are insufficiently deterministic for RMS to actually occur.
Most RTOS schedulers support RMS, including FreeRTOS. Most RTOS also support variable task priority as both a priority inversion mitigation, and via an API. But to be honest if your application relies on either I would argue that it is a failed design.

Is it possible to set a Timer with condition in Mongoose OS?

I am familiar with using mgos_msleep(value) or mgos_usleep(value). However, using sleep is not good for the device.
Can someone suggest a better approach?
It depends on the architecture of the system and use case with you.
The sleep call in mongoose OS does not cause a busy wait. The sleep call conveys to OS to not schedule the particular process until the sleep duration is over. The 'mgos_usleep' function is a sleep with greater resolution (microseconds) which should have very less impact, however this in turn is based on your requirement / use case.
With respect to timer, the Mongoose OS supports both software timers and hardware timers. The decision to use either software timer or hardware timer is in turn based on the application requirement with you.
The mgos_set_timer sets up a software timer with milliseconds timeout and the respective callback. The software timer frequency is specified in milliseconds and the number of software timers is not limited.The software timer callback is executed in mongoose task context. This timer seems to be with fairly low accuracy and high jitter.
The mgos_set_hw_timer sets up a hardware timer with microseconds timeout and the respective callback. The hardware timer callback is executed in the ISR context and hence the actions are limited due it. The hardware timers or counters shall be available as per the type of processor that you use, hence you may need to have a look at the datasheet. Accordingly, the number of hardware timers is limited and the frequency is specified in microseconds.

WDT in a preemptive RTOS kernel

I heard that the best way to use a watch dog timer in a preemptive kernel is to assign it to the lowest task/idle task and refresh it there, I fail to understand why though,what if high priority tasks keeps running and idle task doest run before timeout.
any clarifications?
Thanks.
fail to understand why though,what if high priority tasks keeps running and idle task doest run before timeout.
Well, that is kind of the point. If the lowest priority thread (or better, the idle thread) is starved, then your system will be missing deadlines, and is either poorly designed or some unexpected condition has occurred.
If it were reset at a high priority or interrupt, then all lower priority threads could be in a failed state, either running busy or never running at all, and the watchdog would be uselessly maintained while not providing any protection whatsoever.
It is nonetheless only a partial solution to system integrity monitoring. It addresses the problem of an errant task hogging the CPU, but it does not deal with the issue of a task blocking and never being scheduled as intended. There are any number of ways of dealing with that, but a simple approach is to have "software watchdogs", counters that get reset by each task, and decremented in a high- priority timer thread or handler. If any thread counter reaches zero, then the respective thread blocked for longer than intended, and action may be taken. This requires that each thread runs at an interval shorter than its watchdog counter reset value. For threads that otherwise block indefinitely waiting for infrequent aperiodic events, you might use a blocking timeout just to update the software watchdog.
There is no absolute rule about the priority of a watchdog task. It depends on your design and goals.
Generally speaking, if the watchdog task is the lowest priority task then it will fail to run (and the watchdog will reset) if any higher priority task becomes stuck or consumes too much of the CPU time. Consider that if the high priority task(s) is running 100% of the time then that's probably too much because lower priority tasks are getting starved. And maybe you want the watchdog to reset if lower priority tasks are getting starved.
But that general idea isn't a complete design. See this answer, and especially the "Multitasking" section of this article (https://www.embedded.com/watchdog-timers/) for a more complete watchdog task design. The article suggests making the watchdog task the highest priority task but discusses the trade-offs of the alternative.

What is "Interrupt" for transition of a process from running to ready?

Here is process state diagram from Modern Operating Systems. Transition from running to ready happens when the scheduler picks another process.
Here is process state diagram from Operating System Concepts.
What does "Interrupt" mean for transition from running to ready? Is it the same as "the scheduler picks another process" in the above?
Thanks.
There are two ways for a process to transition from the running state to the ready state depending on the OS implements multitasking:
With preemptive multitasking, the OS uses timer interrupts (there is one timer for each core or processor in the system) to regularly interrupt whatever process is currently running. The interrupt handler then invokes the OS scheduler to determine whether to schedule another process or continue running the same process. If the scheduler decided to run another process, then the current process transition from the running state to the ready state.
With cooperative multitasking, the OS does not use interrupts to scheduler processes. Instead, a running process should voluntarily yield control to the scheduler to allow it to schedule another process. So processes do not transition between the running and ready states using interrupts, but only voluntarily.
It seems to me that the figure from the Modern Operating Systems book applies to both multitasking methods while the figure from the Operating System Concepts is specifically about preemptive multitasking. Although by changing the word "interrupt" to something more inclusive like "yield," then the other figure would also apply to cooperative multitasking.

Is interruption between task is possible in Non RTOS system

If I have a non-RTOS single core system, can one task, say taskA interrupt another task, say taskB, where neither taskA or taskB are interrupt routines? Or is interruption of one task by another only possible through ISR(interrupt service routines) on non-RTOS systems?
For your system to have more than one non-ISR thread implies that there is some sort of multi-tasking - and multi-tasking is not exclusive to an RTOS. One task "interrupting" another is known as preemption. Preemption requires a preemptive scheduler, while an RTOS is necessarily a pre-emptive scheduler, so also are Windows and Linux for example - but these are not real-time since scheduling and preemption is not deterministic.
Preemptive multi-tasking is necessary to support preemption, but real-time deterministic scheduling is not required. Preemption however is not necessary to multi-tasking; some systems (Notably 16 bit versions of Windows prior to Win95, and MacOS prior to OSX) are cooperative multitasking systems where a running task must yield the CPU to allow other tasks to run.
In a preemptive multitasking system, the scheduler executes on exit from the interrupt context and whenever a task invokes a schedulable event (such as giving a semaphore, queuing a message or releasing a mutex. If when the scheduler runs a task becomes ready to run and the scheduling policy requires or allows it to preempt the current task, a context switch will occur.
So in short one non-ISR thread or process "interrupting" another requires an OS that supports preemption, which need not be an RTOS.
Control must be given to the task scheduler in order for a context switch to occur. That can happen as a result of an interrupt if the interrupt handler is designed to call the scheduler. Or it can happen as a result of some function call (such as yield, post, or pend) if that function calls the scheduler.
This task scheduler could be part of an RTOS. Or maybe it's some minimal task switching kernel that you don't consider to be an RTOS . Regardless, some sort of scheduler must get control in order to perform a task context switch.