MicroC/OS-II Concepts kernel in ARM powered microcontroller


MicroC/OS-II Concepts
 Multitasking
 Multitasking is the process of scheduling and switching the CPU between several tasks; a single CPU switches its attention between several sequential tasks. Multitasking is like foreground/background with multiple backgrounds [1]. Multitasking maximize the utilization of the CPU and also provides for modular construction of applications. One of the most important aspects of multitasking is that it allows the application programmer to manage complexity inherent in real-time application. Application programs are typically easier to design and maintain if multitasking is used.
Task
 A task is a simple program that thinks it has the CPU all to itself. Each Task has
o   Its own stack space
o   A priority based on its importance
Task is assigned a unique priority .A task contains YOUR application code .A Real-Time application consists of several tasks executing concurrently. Task has its own set of CPU registers (backup in its stack) .Task is the basic unit for scheduling. Task status is stored in Task Control Block (TCB)
Task States
Each task typically is an infinite loop that can be in any one of five states: DORMANT, READY, RUNNING, and WAITING (for an event), and ISR (interrupted). 
Dormant State
It is the state corresponds to a task that resides in memory but has not been made available to the multitasking kernel. Deleting task stored in dormant state.
Ready State
A task is READY when it can execute but its priority is less than the currently running task. Simply say task is READY, but CPU is not available.
Running State
         A task is RUNNING when it as control of the CPU. Simply we can say task under execution is called RUNNING state. kernel-in-ARM-powered-microcontroller6
 Fig 4.1: Task States
Waiting State
         A task is WAITING when it require the occurrence of an event (waiting for an I/O operation to complete , a shared resource to be available ,a timing pulse to occur, time to expire, etc….) .Here CPU is ready, but task is not ready.
ISR State:
         A task is in the ISR state when an interrupt has occurred and the CPU is in the process of servicing the interrupt.
Context Switch (or Task Switch)
When a multitasking kernel decides to run a different task, it simply saves the current task’s context (CPU register) in the current task’s context storage area-its stack [3]. Once this operation is performed, the new task’s context is restored from its storage area then resumes execution of the new task’s code. This process is called a context switch or task switch.  kernel-in-ARM-powered-microcontroller8
 Fig 4.2:  Multitasking using a context switch
Context switching adds overhead to the application. The more registers a CPU has, the higher the overhead. The time required to perform a context switch is determined by how many register has to be saved and restored by the CPU. Performance of a real time kernel should not be judged by how many context switches the kernel is capable of doing per second.
Kernel
The kernel is the part of multitasking system responsible for the management of the tasks (i.e.., for managing the CPU’s time) and communication between tasks. The fundamental services provided by the kernel is context switching. The use real-time kernel generally simplifies the design of system by allowing the application to be divided into multiple tasks managed by the kernel. A kernel adds overheads to your system because it requires extra ROM (code space) and additional RAM for the kernel data structures. But most importantly, each task requires its own stack space, which has tendency to eat up your RAM quite quickly a kernel also consume CPU time (typically 2to 5 percent) [1].
Single-chip microcontrollers are generally not able to run a real-time kernel because they have very little RAM. A kernel allows you to make better use of your CPU by provided you with indispensible services a semaphore management, mailboxes, queue, time delay etc. once you design a system using a real-time kernel, you will not want to go back to the foreground/background system.
Real-Time Kernel
Software that manages the time of a microprocessor or microcontroller. Ensures that the most important code runs first! Allows Multitasking: Do more than one thing at the same time. Application is broken down into multiple tasks (up to 63) each handling one aspect of your application. It’s like having multiple CPUs! Provides valuable services to your application: Time delays, Resource sharing, Inter task communication and synchronization
Scheduler      
Scheduler is the part of the kernel responsible for determining which task will run next [1]. Most real-time kernels are priority based. Each task is assigned a priority based on its importance. The priority of each task is application specific. Control is always given to the highest priority task ready to run.
 Types of Kernel
 There are two types of priority based kernels,
         Non-Preemptive Kernel
         Preemptive Kernel
Non-Preemptive Kernel
Non-preemptive kernels require that each task does something do explicitly give up control of the CPU [3].  kernel-in-ARM-powered-microcontroller9
 Fig 4.3: Non-Preemptive Kernel
To maintain the illusion of concurrency; this process must be done frequently. Non-preemptive scheduling is also called cooperative multitasking; tasks cooperative with each other to share the CPU. Asynchronous events are still handled by the ISRs. An ISR can make a higher priority task ready to run, but the ISR always returns to the interrupted task. The new higher priority task will gain control of the CPU only when the current task gives up the CPU.                    
One of the advantages of a non-preemptive kernel is that interrupt latency is typically low. At the task level, non-preemptive kernel can also use non-reentrant function. Non –reentrant function can be used by each task without fear of corruption by another task. This is because each task a can run to complication before it relinquishes the CPU
Task-level response using a non-preemptive kernel can be much lower than with foreground/background system because task-level response is now given by the time of the longer task.
Require that each task does something to explicitly give up the control of the CPU [1]. Also called cooperative multitasking .ISR always returns to the interrupted task.
Preemptive Kernel
A preemptive kernel is used when system responsiveness is important. Because of this, MicroC/OS-II and most commercial real time kernel are preemptive. The highest priority task ready to run is always given control of the CPU [3]. When a task makes a higher priority task ready to run, the current tasks is preempted (suspended) and the higher priority task is immediately given control of the CPU. If an ISR makes a higher priority task ready, when the ISR complete the interrupted task is suspended and the new higher priority task is resumed. kernel-in-ARM-powered-microcontroller10
 Fig 4.4: Preemptive Kernel
It is used when system responsiveness is important. High priority task ready to run is always given control of the CPU. Most real-time kernels are preemptive [1]. Application code using a preemptive kernel should not use non-reentrant functions or an appropriate mutual exclusion method should be applied to prevent data corruption. µC/OS-II is a Preemptive Kernel.
Starting mC/OS-II                         

kernel-in-ARM-powered-microcontroller11
Fig 4.5: Starting mC/OS-II
4.5. Initializing µC/OS-II
kernel-in-ARM-powered-microcontroller12

Program for Initializing kernel-in-ARM-powered-microcontroller13
4.6. Scheduling:(Delaying a Task)
Deciding whether there is a more important task to run. This occurs, when a task decides to wait for time to expire. When a task sends a message or a signal to another task [1]. When an ISR sends a message or a signal to a task. Occurs at the end of all nested ISRs.
The outcome is context switch if a more important task has been made ready-to-run or returns to the caller or the interrupted task.From the ready list a task is already running, and then the delay is given to a task. So that highest priority task able to run by the scheduling. Each task is assigned a unique priority level between 0 and OS_LOWEST_PRIO. From the ready list a task is already running, and then the delay is given to a task. So that highest priority task able to run by the scheduling. Each task is assigned a unique priority level between 0 and OS_LOWEST_PRIO.

 Fig 4.6: The µC/OS-II Ready List I 
Task priority OS_LOWEST_PRIO is always assigned to the idle task when Micro C/OS-II is initialized. Note that OS_MAX_TASKS and OS_LOWEST_PRIO are unrelated. Each task that is ready to run is placed in a ready list consisting of two variable, OSRdyGrp and OSRdyGrp[]. Task priorities are grouped (eight tasks per group) in OSRdyGrp. Each bit in OSRdyGrp indicates when a task in a group is ready to run. When the task is ready to run it also sets its corresponding bit in the ready table, OSRdyTbl[].  
Here the scheduling is done by providing some delay and change the priority 1 to 0, and check for the next higher priority and that task will be move for running state[1] . Then the delayed task move to ready state. The next step will be task will move from old TCB to new TCB (task control block).  
 Fig 4.7: The µC/OS-II Ready List II
C/OS-II always executes the highest priority task ready to run. The determination of which task has the highest priority, and thus which task will be next to run, is determined by the scheduler.  
 Fig 4.8: The µC/OS-II Ready List III
 Task level scheduling is performed by OSSched ().Task priority OS_LOWEST_PRIO is always assigned to the idle task when Micro C/OS-II is initialized. Note that OS_MAX_TASKS and OS_LOWEST_PRIO are unrelated. Each task that is ready to run is placed in a ready list consisting of two variable, OSRdyGrp and OSRdyGrp[]. Task priorities are grouped (eight tasks per group) in OSRdyGrp
 Task Structure
          A task is an infinite loop
Void Task (void *p_arg)
{
Do something with ‘argument’ p_arg;
Task initialization;
For (;;) {
/* Processing (Your Code)                  */
Wait for event;    /* Time to expire ...   */
/* Signal from ISR ... */
/* Signal from task ... */
/* Processing (Your Code)                  */
}
} 
4.8 Creating a Task with µC/OS-II
         To makes it ready for multitasking. The kernel needs to have information about your task:Its starting addressits top-of-stack (TOS)its priority,Arguments passed to the taskother information about your task [1].
 
Extended Call
  • You can also use OSTaskCreateExt() to create a task (preferable)
OSTaskCreateExt (void (*task) (void *parg),
                Void   *parg,
                OS_STK *pstk,
                INT8U   prio,
                INT16U id,
                OS_STK *pbos,
                INT32U stk_size,
                Void   *pext,
                INT16U opt);

0 comments:

Post a Comment