Sie sind auf Seite 1von 38

MicroC/OS-II

Kernel Structure-III

What do we mean by Porting?


Adapting a kernel to a microprocessor or a
micro-controller is called a port.

06/06/14

Requirements to port uCOS-II

Re-entrant code

Support for timely interrupts

'C' control of interrupts

Hardware stack

Instructions to operate on the stack


mechanism to access the CPU stack pointer

06/06/14

pointer.....or

Hardware/Software Architecture

06/06/14

Port Summary
Name
BOOLEAN
INT8U
INT8S
INT16U
INT16S
INT32U
INT32S
FP32
FP64
OS_STK
OS_CRITICAL_METHOD
OS_STK_GROWTH
OS_ENTER_CRITICAL()
OS_EXIT_CRITICAL()
OSStartHighRdy()
OSCtxSw()
OSTickISR()
OSIntCtxSw()
OSTaskStkInit()
OSInitHookBegin()
OSInitHookEnd()
OSTaskCreateHook()
OSTaskDelHook()
OSTaskSwHook()
OSTaskStatHook()
OSTCBInitHook()
OSTimeTickHook()

06/06/14

Type
Data Type
Data Type
Data Type
Data Type
Data Type
Data Type
Data Type
Data Type
Data Type
Data Type
#define
#define
Macro
Macro
Function
Function
Function
Function
Function
Function
Function
Function
Function
Function
Function
Function
Function

File
OS_CPU.H
OS_CPU.H
OS_CPU.H
OS_CPU.H
OS_CPU.H
OS_CPU.H
OS_CPU.H
OS_CPU.H
OS_CPU.H
OS_CPU.H
OS_CPU.H
OS_CPU.H
OS_CPU.H
OS_CPU.H
OS_CPU_A.ASM
OS_CPU_A.ASM
OS_CPU_A.ASM
OS_CPU_A.ASM
OS_CPU_C.C
OS_CPU_C.C
OS_CPU_C.C
OS_CPU_C.C
OS_CPU_C.C
OS_CPU_C.C
OS_CPU_C.C
OS_CPU_C.C
OS_CPU_C.C

C/ASM
C
C
C
C
C
C
C
C
C
C
C
C
C
C
ASM
ASM
ASM
ASM
C
C
C
C
C
C
C
C
C

Complexity
1
1
1
1
1
1
1
1
1
1
1
1
2
2
3
3
3
3
2
1
1
1
1
1
1
1
1

Five Steps for Porting UCOS


Setting the value of 3 #define constants

(OS_CPU.H)
Typedef10datatypes(OS_CPU.H)
Declaring2macros(OS_CPU.H)
Writing 8 simple and 1 complex function in C
(OS_CPU_C.C)
Writing 4 assembly language functions
(OS_CPU_A.ASM)

06/06/14

Testing the Port


Test with a simple Blinking
Application code
Test UART functionality

06/06/14

LED

INCLUDES.H
Master Header File
Allows every .C file in your project to be
written without concerns about which
header file will actually be needed
We can add our own header file

06/06/14

OS_CPU.H

Processor & Implementation specific


#define constants, macros and typedefs

06/06/14

06/06/14

10

OS_CPU.h - Typedefs
typedef
typedef
typedef
typedef
typedef
typedef
typedef
typedef
typedef

06/06/14

unsigned char
BOOLEAN;
unsigned char
INT8U;
signed
char
INT8S;
unsigned int
INT16U;
signed
int
INT16S;
unsigned long
INT32U;
signed
long
INT32S;
float
FP32;
unsigned char
OS_STK;
/* Each stack entry is 8-bit wide */

11

OS_CPU.h CRITICAL SECTIONS


Method I
#define OS_ENTER_CRITICAL asm(cli)
#define OS_ENTER_CRITICAL asm(sei)

Method II
#define OS_ENTER_CRITICAL
asm(push SREG ;\

cli)
#define OS_EXIT_CRITICAL asm(pop SREG)
06/06/14

12

OS_CPU.h - OS_STK_GROWTH
Some processor will have a Stack Growth
from High to Low or from Low to High
In case of AVR/ARM (High to Low)

#define OS_STK_GROWTH 1

06/06/14

13

OS_CPU_C.C

OSTaskStkInit()
OSTaskCreateHook()
OSTaskDelHook()
OSTaskSwHook()
OSTaskStatHook()
OSTimeTickHook()

06/06/14

14

OSTaskStkInit()

Called whenever a new task is created


Duties

Initialize the stack for the newly created task


Set the environment such that the task may be
brought into execution as though an interrupt
has occurred
Return the initialized top-of-stack

Note

Critical that you understand the context switch


flow for your processor

06/06/14

15

OSTaskStkInit()
OS_STK *OSTaskStkInit (void (*task) (void *pd),
void *pdata, OS_STK *ptos,
INT16U opt);
{
Simulate call to function with an argument (i.e. Pdata);
Simulate ISR vector;
Setup stack frame to contain desired initial values of all
registers
Return new top-of-stack pointer to caller
}

06/06/14

16

OSTaskStkInit()

06/06/14

17

Code Snippet

OS_STK *OSTaskStkInit (void (*task)(void


void *p_arg, OS_STK *ptos, INT16U opt)
{
OS_STK *stk;
opt
= opt;
stk
= ptos;
*(stk)
= (OS_STK)task;
*(--stk) = (INT32U)0x14141414L;
*(--stk) = (INT32U)0x12121212L;
*(--stk) = (INT32U)0x02020202L;
*(--stk) = (INT32U)0x01010101L;
*(--stk) = (INT32U)p_arg;
*(--stk) = (INT32U)ARM_SVC_MODE;
return (stk);

06/06/14

18

*pd),

OSTaskCreateHook()
Called whenever OSTaskCreate() or
OSTaskCreateExt() are used
Called after setting up the Internal Data
Structure but before Scheduling
Interrupt are disabled before calling
Hence code in this function should be as
small as possible(Affects Interrupt Latency
directly)

06/06/14

19

OSTaskDelHook()
Called whenever a task is deleted
It is called before MicorC/OS unlinks the
internal data structure from linked list

06/06/14

20

OSTaskSwHook()
Called whenever a task switch occurs
This happens whether task switch is from
OSCtxSw() or OSIntCtxSw()
It can directly access OSTCBCur &
OSTCBHighRdy (since global)
Interrupts are disabled

06/06/14

21

OSTaskStatHook()
Is called by OSTaskStat() every one
second
We could keep track and display the
execution time of each task, the percentage
of the CPU that is used by each task, how
often each task executes and more

06/06/14

22

OSTimeTickHook()
Is called by OsTimeTick() at every System
Tick
This function is called before MicroC/OS
processes the tick
Hence helps in giving application the first
claim on tick

06/06/14

23

Scheduling
Bootup Scheduling
No task to be swapped out
Highest priority task should be scheduled
Task Level Scheduling
Out going task should be scheduled out
New Task should be scheduled in
ISR level scheduling
Context Saving already completed
Only Context Restoring should be performed

OS_CPU_A.ASM
OSStartHighRdy() - Bootup Scheduling
OSCtxSw() - Task Level Scheduling
OSIntCtxSw() - ISR Level Scheduling
OSTickISR() - Timer Interrupt

06/06/14

25

Bootup Scheduling
void OSStart (void)
{
INT8U y;
INT8U x;
if (OSRunning == FALSE) {
y = OSUnMapTbl[OSRdyGrp];
x = OSUnMapTbl[OSRdyTbl[y]];
OSPrioHighRdy = (INT8U)((y << 3) + x);
OSPrioCur = OSPrioHighRdy;
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
OSTCBCur = OSTCBHighRdy;
OSStartHighRdy();

}
}

OSStartHighRdy()

Called into execution for the very first task


that is started after the Multi-tasking kernel
is started
Duties

Load the CPU stack pointer with the address of


the stack pointer for the task to be scheduled
Restore the registers according to the defined
protocol
Execute a return from interrupt

Note
Careful about the popping order...... 27
06/06/14

OSStartHighRdy()
Call OSTaskSwHook()
Get Stack Pointer of the task to resume

Stack Pointer = OSTCBHighRdy->OSTCBStkPtr;

OSRunning = TRUE ;
Restore all processor registers from the new Task's
Stack
Execute Return from Interrupt

06/06/14

28

Task Level Scheduling


Task level scheduling is performed by calling OSSched()
Identify the highest priority task ready to run
Save the context of Previous Task onto its stack
Restore the context of New Task from its stack
Execute RETI
It will exit if called from
An ISR (ie OSIntNesting > 0)
Scheduling has been disabled.
OSSchedLock()
OSSchedUnlock()

void OSSched (void)


{
INT8U y;
OS_ENTER_CRITICAL();
if ((OSLockNesting | OSIntNesting) == 0) {
y = OSUnMapTbl[OSRdyGrp];
OSPrioHighRdy = (INT8U)((y << 3) +
OSUnMapTbl[OSRdyTbl[y]]);
if (OSPrioHighRdy != OSPrioCur) {
OSTCBHighRdy=OSTCBPrioTbl[OSPrioHighRdy];
OSCtxSwCtr++;
OS_TASK_SW();
}
}
OS_EXIT_CRITICAL();
}

OS_TASK_SW
Represents the flow of events during a task level context
switch........Therefore, instrument this macro to trigger a
software interrupt on the processor

If our processor does not have an Software Interrupt we


can directly make a call to OSCtxSw() function

In AVR/ARM
#define OS_TASK_SW

06/06/14

OSCtxSw()

31

OSCtxSw()

Handles the task level context switch in Micro C OS. Runs


in response to the function OS_TASK_SW()
Duties

Save the present context of the task being preempted

Manage OS pointers to represent newly scheduled task

Retrieve the context of the task scheduled

Return from interrupt


Note

Both context saving and retrieval are done here

06/06/14

32

OSCtxSw()
Save processor registers
Save the current tasks stack pointer into the current
tasks OS_TCB:
OSTCBCur->OSTCBStkPtr = Stack pointer
Call user definable OSTaskSwHook()
OSTCBCur = OSTCBHighRdy
OSPrioCur = OSPrioHighRdy
Get the stack pointer of the task to resume
Stack pointer = OSTCBHighRdy->OSTCBStkPtr
Restore all processor registers from the new tasks stack
Execute a return from interrupt instruction
06/06/14

33

Locking Scheduler
void OSSchedLock (void)
{
if (OSRunning == TRUE) {
OS_ENTER_CRITICAL();
OSLockNesting++;
OS_EXIT_CRITICAL();
}
}

UnLocking Scheduler
void OSSchedUnlock (void)
{
if (OSRunning == TRUE) {
OS_ENTER_CRITICAL();
if (OSLockNesting > 0) {
OSLockNesting--;
if ((OSLockNesting | OSIntNesting) == 0) {
OS_EXIT_CRITICAL();
OSSched();
} else {
OS_EXIT_CRITICAL();
}
} else {
OS_EXIT_CRITICAL();
}
}
}

Scheduling
Caution
OSSchedLock() and OSSchedUnlock() must be used in

pairs.
The task that calls OSSchedLock() keeps control of
CPU forever!
After calling OSSchedLock(), your task must not make
any kernel service that will suspend execution of the
current task.
No other task will be allowed to run!

Reference
OS_CORE.C

Of Kernel
Structure
PART-III

Das könnte Ihnen auch gefallen