Documentos de Académico
Documentos de Profesional
Documentos de Cultura
C/OS-II Configuration
(Application-Specific Code)
OS_CFG.H
INCLUDES.H
C/OS-II Port
(Processor-Specific Code)
OS_CPU.H
OS_CPU_A.ASM
OS_CPU_C.C
Software
Hardware
CPU
Timer
Development Tools
Directories & Files
Motorola
68HC11
\SOFTWARE\uCOS-II\68HC11
\OS_CPU.H
\OS_CPU_A.ASM
\OS_CPU_C.C
typedef
typedef
typedef
typedef
typedef
typedef
typedef
typedef
typedef
unsigned
unsigned
signed
unsigned
signed
unsigned
signed
float
double
BOOLEAN;
INT8U;
INT8S;
INT16U;
INT16S;
INT32U;
INT32S;
FP32;
FP64;
/*
/*
/*
/*
/*
/*
/*
/*
OS_STK;
#define
#define
#define
#define
#define
INT8S
INT8U
INT16U
INT32S
INT32U
BYTE
UBYTE
UWORD
LONG
ULONG
char
char
char
int
int
long
long
OS_CPU.H -- Critical
Section
#define
OS_CRITICAL_METHOD
#if
#define
#define
#endif
OS_CRITICAL_METHOD == 1
OS_ENTER_CRITICAL() asm
OS_EXIT_CRITICAL()
asm
Both the CLI and STI instructions execute in less that two clock
cycles each on this processor (a total of 4 cycles)
#if
#define
#define
#endif
OS_CRITICAL_METHOD == 2
OS_ENTER_CRITICAL() asm {PUSHF; CLI} /* Disable interrupts */
OS_EXIT_CRITICAL()
asm POPF /* Enable interrupts */
OS_CPU.H -- Miscellaneous
#define OS_STK_GROWTH 1
/* Stack grows from HIGH to LOW memory on 80x86
*/
*/
OS_CPU_A.ASM
OSStartHighRdy()
OSCtxSw()
OSIntCtxSw()
OSTickISR()
(1) OSStartHighRdy()
: , function, priority
task
:
OSInit() ( OS_CORE.C )
task (by calling OSTaskCreate() and
OSTaskCreateExt())
Called by OSStart(), OSStart()
OSStartHighRdy()
Pseudo code
Call user definable OSTaskSwHook();
Get the stack pointer of the task to resume:
Stack Pointer = OSTCBHighRdy OSTCBStkPtr;
OSRunning = TRUE;
Execute a return from interrupt instruction
OSStartHighRdy() (cont.)
OSStartHighRdy() (cont.)
_OSStartHighRdy PROC FAR
MOV
MOV
; Reload DS
CALL
;
;
INC
;
LES BX, DWORD PTR DS:_OSTCBHighRdy ; SS:SP = OSTCBHighRdy>OSTCBStkPtr
MOV SS, ES:[BX+2]
;
MOV SP, ES:[BX+0]
;
;
POP DS
POP ES
POPA
;
IRET
_OSStartHighRdy ENDP
; Run task
OSStartHighRdy() (cont.)
OSRunning
declaration( in uCOS_II.H)
OS_EXT BOOLEAN
OSRunning;
initialization(in OS_CORE.C)
OSRunning
= FALSE;
OSStartHighRdy() (cont.)
(2) OSCtxSw()
Pseudo code
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;
POP DS,POP ES,POPA
Execute a return from interrupt instruction;
OSCtxSw() (cont.)
OSSched () (in OS_CORE.C)
void OSSched (void)
{
INT8U y;
OS_ENTER_CRITICAL();
if ((OSLockNesting | OSIntNesting) == 0) { /* Task scheduling must be enabled and not ISR level */
y
= OSUnMapTbl[OSRdyGrp]; /* Get pointer to highest priority task ready to run */
OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]);
if (OSPrioHighRdy != OSPrioCur) {
/* No context switch if current task is highest ready */
OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
OSCtxSwCtr++;
/* Increment context switch counter
OS_TASK_SW();
/* Perform a context switch
}
}
OS_EXIT_CRITICAL();
}
*/
*/
OSCtxSw()
(3) OSIntCtxSw()
OSIntCtxSw() (cont.)
Task Response
Interrupt Request
Interrupt disabled
TASK
Vectoring
Interrupt Recovery
No New HPT Or
OSLockNesting=0
Processor regisisters.
TASK
Notify kernel
Interrupt Response
Notify kernel
Restore Context
Call OSIntExit()
New HPT
Interrupt Recovery
Task Response
TASK
OSIntCtxSw() (cont.)
OSIntExit in OS_CPU_C.C
OSIntCtxSw() (cont.)
called by OSIntExit(), OSCtxSw()
, :
- processor reg ISR
interrupt task
stack, regisisters( :no
PUSHA,PUSH ES,PUSH DS)
function interrupt disable
( OSIntExit() )
OSIntCtxSw() (cont.)
OSIntCtxSw() (cont.)
_OSIntCtxSw PROC FAR
;
; Ignore calls to OSIntExit and OSIntCtxSw
;
ADD SP,8
; (Uncomment if OS_CRITICAL_METHOD is 1, see OS_CPU.H)
ADD SP,10
; (Uncomment if OS_CRITICAL_METHOD is 2, see OS_CPU.H)
;
MOV AX, SEG _OSTCBCur
; Reload DS in case it was altered
MOV DS, AX
;
;
LES BX, DWORD PTR DS:_OSTCBCur
; OSTCBCur->OSTCBStkPtr = SS:SP
MOV ES:[BX+2], SS
;
MOV ES:[BX+0], SP
;
;
CALL FAR PTR _OSTaskSwHook
; Call user defined task switch hook
;
MOV AX, WORD PTR DS:_OSTCBHighRdy+2 ; OSTCBCur = OSTCBHighRdy
MOV DX, WORD PTR DS:_OSTCBHighRdy ;
MOV WORD PTR DS:_OSTCBCur+2, AX
;
MOV WORD PTR DS:_OSTCBCur, DX
;
;
MOV AL, BYTE PTR DS:_OSPrioHighRdy ; OSPrioCur = OSPrioHighRdy
MOV BYTE PTR DS:_OSPrioCur, AL
;
LES BX, DWORD PTR DS:_OSTCBHighRdy ; SS:SP = OSTCBHighRdy->OSTCBStkPtr
MOV SS, ES:[BX+2]
;
MOV SP, ES:[BX]
;
;
POP DS
; Load new task's context
POP ES
;
POPA
;
;
IRET
; Return to new task
;
_OSIntCtxSw ENDP
(4) OSTickISR()
OSTickISR() (cont.)
Pseudo code
Save processor registers;
OSIntNesting++;
OSTickDOSCtr--;
if (OSTickDOSCtr == 0) {
Chain into DOS by executing an INT 81H instruction;
} else {
Send EOI (End of Interrupt) command to PIC (Priority
Interrupt Controller);
}
OSTimeTick();
OSIntExit();
Restore processor registers;
Execute a return from interrupt instruction (IRET);
OSTickISR() (cont.)
OSInit();
OSStart();
}
OS_CPU_C.C
OSTaskStkInit() //necessary
OSTaskCreateHook()
OSTaskDelHook()
OSTaskSwHook()
OSTaskStatHook()
OSTimeTickHook()
(1) OSTaskStkInit()
OSTaskStkInit() (cont.)
OSTaskStkInit() (cont.)
void *OSTaskStkInit (void (*task)(void *pd), void *pdata, void *ptos, INT16U opt)
{
INT16U *stk;
opt
= opt;
/* 'opt' is not used, prevent warning */
stk
= (INT16U *)ptos;
/* Load stack pointer */
*stk-- = (INT16U)FP_SEG(pdata);
/* Simulate call to function with argument */
*stk-- = (INT16U)FP_OFF(pdata);
*stk-- = (INT16U)FP_SEG(task);
*stk-- = (INT16U)FP_OFF(task);
*stk-- = (INT16U)0x0202;
/* SW = Interrupts enabled */
*stk-- = (INT16U)FP_SEG(task);
/* Put pointer to task
on top of stack */
*stk-- = (INT16U)FP_OFF(task);
*stk-- = (INT16U)0xAAAA;
/* AX = 0xAAAA */
*stk-- = (INT16U)0xCCCC;
/* CX = 0xCCCC */
*stk-- = (INT16U)0xDDDD;
/* DX = 0xDDDD */
*stk-- = (INT16U)0xBBBB;
/* BX = 0xBBBB */
*stk-- = (INT16U)0x0000;
/* SP = 0x0000 */
*stk-- = (INT16U)0x1111;
/* BP = 0x1111 */
*stk-- = (INT16U)0x2222;
/* SI = 0x2222 */
*stk-- = (INT16U)0x3333;
/* DI = 0x3333 */
*stk-- = (INT16U)0x4444;
/* ES = 0x4444 */
*stk
= _DS;
/* DS = Current value of DS */
return ((void *)stk);
}