In this blog, I will discuss RTOS, which I will be using and demonstrating in this design challenge.
1. What is RTOS ?
RTOS is a real-time operating system (RTOS). It is an operating system (OS) for real-time computing applications that have critically defined time constraints.
2. Hard RTOS and Soft RTOS
RTOS are classified into Hard RTOS and Soft RTOS. Hard RTOS is what is needed for clinical especially ICU or to save in accidents like in modern vehicles, cars, planes, trains, as not able to meet time constraints in theses scenarios would be catastrophic. Hard RTOS meet these deadlines deterministically, which can be defined in finite-state machine or finite state automata . Hard RTOS has less jitter than Soft RTOS.
3. Context switching
Using RTOS context switching, the deadlines for these crticial ICU or vehicles brakes etc can be achieved by taking benefit of its process switching latency, thread switching latency and interrupt latency.
4. Mutex
Mutex is a synchronization primitive that prevents state from being modified or accessed by multiple threads of execution at once, wiz., semaphore. If one do not code it properly, it can cause deadlock or livelock.
5. Scheduling
5.1 Cooperative scheduling
Cooperative multitasking is a non-preemptive multitasking where context switch is never initiated
5.2 Preemptive scheduling
In preemptive scheduling, context switch is initiated.
In kernel preemption also, one can enable or disable, but otherwise it can result in deadlock. The linux kernal which I m using is a pre-emptive one, thus, spinlocks operations are no more no-ops.
Preemptive scheduling is implemented in many ways, wiz., rate-monotonic scheduling, round-robin scheduling, fixed-priority pre-emptive scheduling, preemptive time slicing, fixed-priority scheduling with deferred preemption, fixed-priority non-preemptive scheduling, critical section preemptive scheduling, static-time scheduling.
5.3 Earliest Deadline First approach
5.4 Stochastic digraphs with multi-threaded graph traversal
6. Implementation on Microchip SAM E51 Curiosity Nano Evaluation Kit
If you search at available examples, you will find that there is no example of the implementation of FreeRTOS like other microcontrollers from Microchip. And moreover, there is no RTOS core available which can be easily integrated. But as I have in my blog2, SysTick in programmer's model and exceptions; using this SysTick I will implement RTOS,FreeRTOS tick timer. Below is sample code and is part of the code using which I will implement RTOS, in which I will do add on and changes
volatile static SYSTICK_OBJECT systick;
void SYSTICK_TimerInitialize ( void )
{
SysTick->CTRL = 0U;
SysTick->VAL = 0U;
SysTick->LOAD = 0x249F00U - 1U;
SysTick->CTRL = SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_CLKSOURCE_Msk;
systick.tickCounter = 0U;
systick.callback = NULL;
}
void SYSTICK_TimerRestart ( void )
{
SysTick->CTRL &= ~(SysTick_CTRL_ENABLE_Msk);
SysTick->VAL = 0U;
SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
}
void SYSTICK_TimerStart ( void ){ SysTick->VAL = 0U; SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk;
}
void SYSTICK_TimerStop ( void ){ SysTick->CTRL &= ~(SysTick_CTRL_ENABLE_Msk);}
void SYSTICK_TimerPeriodSet ( uint32_t period ){ SysTick->LOAD = period - 1U;}
uint32_t SYSTICK_TimerPeriodGet ( void ){ return(SysTick->LOAD);}
uint32_t SYSTICK_TimerCounterGet ( void ){ return (SysTick->VAL);}
uint32_t SYSTICK_TimerFrequencyGet ( void ){ return (SYSTICK_FREQ);}
void SYSTICK_DelayMs ( uint32_t delay_ms)
{ uint32_t elapsedCount=0U, delayCount;
uint32_t deltaCount, oldCount, newCount, period;
period = SysTick->LOAD + 1U;
delayCount=(SYSTICK_FREQ/1000U)*delay_ms;
if((SysTick->CTRL & SysTick_CTRL_ENABLE_Msk) == SysTick_CTRL_ENABLE_Msk)
{
oldCount = SysTick->VAL;
while (elapsedCount < delayCount)
{
newCount = SysTick->VAL;
deltaCount = oldCount - newCount;
if(newCount > oldCount)
{
deltaCount = period - newCount + oldCount;
}
oldCount = newCount;
elapsedCount = elapsedCount + deltaCount;
}
}
}
void SYSTICK_DelayUs ( uint32_t delay_us)
{
uint32_t elapsedCount=0U, delayCount;
uint32_t deltaCount, oldCount, newCount, period;
period = SysTick->LOAD + 1U;
delayCount=(SYSTICK_FREQ/1000000U)*delay_us;
if((SysTick->CTRL & SysTick_CTRL_ENABLE_Msk) == SysTick_CTRL_ENABLE_Msk)
{
oldCount = SysTick->VAL;
while (elapsedCount < delayCount)
{
newCount = SysTick->VAL;
deltaCount = oldCount - newCount;
if(newCount > oldCount)
{
deltaCount = period - newCount + oldCount;
}
oldCount = newCount;
elapsedCount = elapsedCount + deltaCount;
}
}
}
uint32_t SYSTICK_GetTickCounter(void)
{
return systick.tickCounter;
}
void SYSTICK_StartTimeOut (SYSTICK_TIMEOUT* timeout, uint32_t delay_ms)
{
timeout->start = SYSTICK_GetTickCounter();
timeout->count = (delay_ms*1000U)/SYSTICK_INTERRUPT_PERIOD_IN_US;
}
void SYSTICK_ResetTimeOut (SYSTICK_TIMEOUT* timeout)
{
timeout->start = SYSTICK_GetTickCounter();
}
bool SYSTICK_IsTimeoutReached (SYSTICK_TIMEOUT* timeout)
{
bool valTimeout = true;
if ((SYSTICK_GetTickCounter() - timeout->start) < timeout->count)
{
valTimeout = false;
}
return valTimeout;
}
void SYSTICK_TimerCallbackSet ( SYSTICK_CALLBACK callback, uintptr_t context )
{
systick.callback = callback;
systick.context = context;
}
void __attribute__((used)) SysTick_Handler(void)
{
uintptr_t context = systick.context;
(void)SysTick->CTRL;
systick.tickCounter++;
if(systick.callback != NULL)
{
systick.callback(context);
}
}
In the above code, I have SYSTICK Timer -Initialize,Restart,Start,Stop,Period Set; Get Period, Counter & Frequency ,Call back, Tick Counter,Star timeOut,ResetTimeOut,TimeoutReached.
Above part is successful but whether I m getting the desired result or not, I have to check (this needs lot of time, and this I cannot do in this time constraint but I will implement, fixed-priority pre-emptive scheduling, and will try to integrate core or part of FreeRTOS core with four task states - running, ready, blocked and suspended.)
Note : You can use SysTick even without implementation of RTOS.
The proof of successful compilation of SysTick would be shown in the coming blogs.