📄 os_core.src
字号:
; /*
; *********************************************************************************************************
; * uC/OS-II
; * The Real-Time Kernel
; * CORE FUNCTIONS
; *
; * (c) Copyright 1992-2002, Jean J. Labrosse, Weston, FL
; * All Rights Reserved
; *
; * File : OS_CORE.C
; * By : Jean J. Labrosse
; *********************************************************************************************************
; */
;
; #ifndef OS_MASTER_FILE
; #define OS_GLOBALS
; #include "includes.h"
; #endif
;
; /*
; *********************************************************************************************************
; * MAPPING TABLE TO MAP BIT POSITION TO BIT MASK
; *
; * Note: Index into table is desired bit position, 0..7
; * Indexed value corresponds to bit mask
; *********************************************************************************************************
; */
;
; INT8U const OSMapTbl[] = {0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80};
;
; /*
; *********************************************************************************************************
; * PRIORITY RESOLUTION TABLE
; *
; * Note: Index into table is bit pattern to resolve highest priority
; * Indexed value corresponds to highest priority bit position (i.e. 0..7)
; *********************************************************************************************************
; */
;
; INT8U const OSUnMapTbl[] = {
; 0, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x00 to 0x0F */
; 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x10 to 0x1F */
; 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x20 to 0x2F */
; 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x30 to 0x3F */
; 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x40 to 0x4F */
; 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x50 to 0x5F */
; 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x60 to 0x6F */
; 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x70 to 0x7F */
; 7, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x80 to 0x8F */
; 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0x90 to 0x9F */
; 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xA0 to 0xAF */
; 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xB0 to 0xBF */
; 6, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xC0 to 0xCF */
; 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xD0 to 0xDF */
; 5, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0, /* 0xE0 to 0xEF */
; 4, 0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2, 0, 1, 0 /* 0xF0 to 0xFF */
; };
;
; /*
; *********************************************************************************************************
; * FUNCTION PROTOTYPES
; *********************************************************************************************************
; */
; static void OS_InitEventList(void);
; static void OS_InitMisc(void);
; static void OS_InitRdyList(void);
; static void OS_InitTaskIdle(void);
; static void OS_InitTaskStat(void);
; static void OS_InitTCBList(void);
;
; /*$PAGE*/
; /*
; *********************************************************************************************************
; * INITIALIZATION
; *
; * Description: This function is used to initialize the internals of uC/OS-II and MUST be called prior to
; * creating any uC/OS-II object and, prior to calling OSStart().
; *
; * Arguments : none
; *
; * Returns : none
; *********************************************************************************************************
; */
;
; void OSInit (void) reentrant
RSEG ?PR?_?OSInit?OS_CORE
_?OSInit:
USING 0
; SOURCE LINE # 85
; {
; #if OS_VERSION >= 204
; OSInitHookBegin(); /* Call port specific initialization code */
; SOURCE LINE # 88
LCALL OSInitHookBegin
; #endif
;
; OS_InitMisc(); /* Initialize miscellaneous variables */
; SOURCE LINE # 91
LCALL OS_InitMisc
;
; OS_InitRdyList(); /* Initialize the Ready List */
; SOURCE LINE # 93
LCALL OS_InitRdyList
; OS_InitTCBList(); /* Initialize the free list of OS_TCBs */
; SOURCE LINE # 94
LCALL OS_InitTCBList
; OS_InitEventList(); /* Initialize the free list of OS_EVENTs */
; SOURCE LINE # 95
LCALL OS_InitEventList
;
; #if (OS_VERSION >= 251) && (OS_FLAG_EN > 0) && (OS_MAX_FLAGS > 0)
; OS_FlagInit(); /* Initialize the event flag structures */
; #endif
;
; #if (OS_MEM_EN > 0) && (OS_MAX_MEM_PART > 0)
; OS_MemInit(); /* Initialize the memory manager */
; #endif
;
; #if (OS_Q_EN > 0) && (OS_MAX_QS > 0)
; OS_QInit(); /* Initialize the message queue structures */
; #endif
;
; OS_InitTaskIdle(); /* Create the Idle Task */
; SOURCE LINE # 109
LCALL OS_InitTaskIdle
; #if OS_TASK_STAT_EN > 0
; OS_InitTaskStat(); /* Create the Statistic Task */
; #endif
;
; #if OS_VERSION >= 204
; OSInitHookEnd(); /* Call port specific init. code */
; SOURCE LINE # 115
LJMP OSInitHookEnd
; END OF _?OSInit
; #endif
; }
; /*$PAGE*/
; /*
; *********************************************************************************************************
; * ENTER ISR
; *
; * Description: This function is used to notify uC/OS-II that you are about to service an interrupt
; * service routine (ISR). This allows uC/OS-II to keep track of interrupt nesting and thus
; * only perform rescheduling at the last nested ISR.
; *
; * Arguments : none
; *
; * Returns : none
; *
; * Notes : 1) This function should be called ith interrupts already disabled
; * 2) Your ISR can directly increment OSIntNesting without calling this function because
; * OSIntNesting has been declared 'global'.
; * 3) You MUST still call OSIntExit() even though you increment OSIntNesting directly.
; * 4) You MUST invoke OSIntEnter() and OSIntExit() in pair. In other words, for every call
; * to OSIntEnter() at the beginning of the ISR you MUST have a call to OSIntExit() at the
; * end of the ISR.
; * 5) You are allowed to nest interrupts up to 255 levels deep.
; * 6) I removed the OS_ENTER_CRITICAL() and OS_EXIT_CRITICAL() around the increment because
; * OSIntEnter() is always called with interrupts disabled.
; *********************************************************************************************************
; */
;
; void OSIntEnter (void) reentrant
RSEG ?PR?_?OSIntEnter?OS_CORE
_?OSIntEnter:
USING 0
; SOURCE LINE # 144
; {
; if (OSRunning == TRUE) {
; SOURCE LINE # 146
MOV R0,#LOW (OSRunning)
MOV A,@R0
CJNE A,#01H,?C0004
; if (OSIntNesting < 255) {
; SOURCE LINE # 147
MOV DPTR,#OSIntNesting
MOVX A,@DPTR
CLR C
SUBB A,#0FFH
JNC ?C0004
; OSIntNesting++; /* Increment ISR nesting level */
; SOURCE LINE # 148
MOVX A,@DPTR
INC A
MOVX @DPTR,A
; }
; SOURCE LINE # 149
; }
; SOURCE LINE # 150
; }
; SOURCE LINE # 151
?C0004:
RET
; END OF _?OSIntEnter
; /*$PAGE*/
; /*
; *********************************************************************************************************
; * EXIT ISR
; *
; * Description: This function is used to notify uC/OS-II that you have completed serviving an ISR. When
; * the last nested ISR has completed, uC/OS-II will call the scheduler to determine whether
; * a new, high-priority task, is ready to run.
; *
; * Arguments : none
; *
; * Returns : none
; *
; * Notes : 1) You MUST invoke OSIntEnter() and OSIntExit() in pair. In other words, for every call
; * to OSIntEnter() at the beginning of the ISR you MUST have a call to OSIntExit() at the
; * end of the ISR.
; * 2) Rescheduling is prevented when the scheduler is locked (see OS_SchedLock())
; *********************************************************************************************************
; */
;
; void OSIntExit (void) reentrant
RSEG ?PR?_?OSIntExit?OS_CORE
_?OSIntExit:
USING 0
; SOURCE LINE # 172
; {
;
;
;
; if (OSRunning == TRUE) {
; SOURCE LINE # 177
MOV R0,#LOW (OSRunning)
MOV A,@R0
XRL A,#01H
JZ $ + 5H
LJMP ?C0009
; OS_ENTER_CRITICAL();
; SOURCE LINE # 178
CLR EA
; if (OSIntNesting > 0) { /* Prevent OSIntNesting from wrapping */
; SOURCE LINE # 179
MOV DPTR,#OSIntNesting
MOVX A,@DPTR
SETB C
SUBB A,#00H
JC ?C0006
; OSIntNesting--;
; SOURCE LINE # 180
MOVX A,@DPTR
DEC A
MOVX @DPTR,A
; }
; SOURCE LINE # 181
?C0006:
; if ((OSIntNesting == 0) && (OSLockNesting == 0)) { /* Reschedule only if all ISRs complete ... */
; SOURCE LINE # 182
MOV DPTR,#OSIntNesting
MOVX A,@DPTR
JZ $ + 5H
LJMP ?C0007
MOV DPTR,#OSLockNesting
MOVX A,@DPTR
JNZ ?C0007
; OSIntExitY = OSUnMapTbl[OSRdyGrp]; /* ... and not locked. */
; SOURCE LINE # 183
MOV DPTR,#OSRdyGrp
MOVX A,@DPTR
ADD A,#LOW (OSUnMapTbl)
MOV DPL,A
CLR A
ADDC A,#HIGH (OSUnMapTbl)
MOV DPH,A
MOVX A,@DPTR
MOV DPTR,#OSIntExitY
MOVX @DPTR,A
; OSPrioHighRdy = (INT8U)((OSIntExitY << 3) + OSUnMapTbl[OSRdyTbl[OSIntExitY]]);
; SOURCE LINE # 184
MOVX A,@DPTR
MOV R7,A
ADD A,#LOW (OSRdyTbl)
MOV DPL,A
CLR A
ADDC A,#HIGH (OSRdyTbl)
MOV DPH,A
MOVX A,@DPTR
ADD A,#LOW (OSUnMapTbl)
MOV DPL,A
CLR A
ADDC A,#HIGH (OSUnMapTbl)
MOV DPH,A
MOVX A,@DPTR
MOV R6,A
MOV A,R7
RLC A
RLC A
RLC A
ANL A,#0F8H
MOV R7,A
MOV A,R6
ADD A,R7
MOV R7,A
MOV R0,#LOW (OSPrioHighRdy)
MOV @R0,A
; if (OSPrioHighRdy != OSPrioCur) { /* No Ctx Sw if current task is highest rdy */
; SOURCE LINE # 185
DEC R0
MOV A,@R0
XRL A,R7
JZ ?C0007
; OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
; SOURCE LINE # 186
INC R0
MOV A,@R0
MOV B,#03H
MUL AB
ADD A,#LOW (OSTCBPrioTbl)
MOV DPL,A
CLR A
ADDC A,#HIGH (OSTCBPrioTbl)
MOV DPH,A
MOVX A,@DPTR
MOV R3,A
INC DPTR
MOVX A,@DPTR
MOV R2,A
INC DPTR
MOVX A,@DPTR
MOV R0,#LOW (OSTCBHighRdy)
MOV @R0,AR3
INC R0
MOV @R0,AR2
INC R0
MOV @R0,A
; OSCtxSwCtr++; /* Keep track of the number of ctx switches */
; SOURCE LINE # 187
MOV DPTR,#OSCtxSwCtr
MOVX A,@DPTR
MOV R4,A
INC DPTR
MOVX A,@DPTR
MOV R5,A
INC DPTR
MOVX A,@DPTR
MOV R6,A
INC DPTR
MOVX A,@DPTR
ADD A,#01H
MOV R7,A
CLR A
ADDC A,R6
MOV R6,A
CLR A
ADDC A,R5
MOV R5,A
CLR A
ADDC A,R4
MOV R4,A
MOV DPTR,#OSCtxSwCtr
LCALL ?C?LSTXDATA
; OSIntCtxSw(); /* Perform interrupt level ctx switch */
; SOURCE LINE # 188
LCALL OSIntCtxSw
; }
; SOURCE LINE # 189
; }
; SOURCE LINE # 190
?C0007:
; OS_EXIT_CRITICAL();
; SOURCE LINE # 191
SETB EA
; }
; SOURCE LINE # 192
; }
; SOURCE LINE # 193
?C0009:
RET
; END OF _?OSIntExit
; /*$PAGE*/
; /*
; *********************************************************************************************************
; * PREVENT SCHEDULING
; *
; * Description: This function is used to prevent rescheduling to take place. This allows your application
; * to prevent context switches until you are ready to permit context switching.
; *
; * Arguments : none
; *
; * Returns : none
; *
; * Notes : 1) You MUST invoke OSSchedLock() and OSSchedUnlock() in pair. In other words, for every
; * call to OSSchedLock() you MUST have a call to OSSchedUnlock().
; *********************************************************************************************************
; */
;
; #if OS_SCHED_LOCK_EN > 0
; void OSSchedLock (void) reentrant
RSEG ?PR?_?OSSchedLock?OS_CORE
_?OSSchedLock:
USING 0
; SOURCE LINE # 212
; {
;
;
;
; if (OSRunning == TRUE) { /* Make sure multitasking is running */
; SOURCE LINE # 217
MOV R0,#LOW (OSRunning)
MOV A,@R0
CJNE A,#01H,?C0012
; OS_ENTER_CRITICAL();
; SOURCE LINE # 218
CLR EA
; if (OSLockNesting < 255) { /* Prevent OSLockNesting from wrapping back to 0 */
; SOURCE LINE # 219
MOV DPTR,#OSLockNesting
MOVX A,@DPTR
CLR C
SUBB A,#0FFH
JNC ?C0011
; OSLockNesting++; /* Increment lock nesting level */
; SOURCE LINE # 220
MOVX A,@DPTR
INC A
MOVX @DPTR,A
; }
; SOURCE LINE # 221
?C0011:
; OS_EXIT_CRITICAL();
; SOURCE LINE # 222
SETB EA
; }
; SOURCE LINE # 223
; }
; SOURCE LINE # 224
?C0012:
RET
; END OF _?OSSchedLock
; #endif
;
; /*$PAGE*/
; /*
; *********************************************************************************************************
; * ENABLE SCHEDULING
; *
; * Description: This function is used to re-allow rescheduling.
; *
; * Arguments : none
; *
; * Returns : none
; *
; * Notes : 1) You MUST invoke OSSchedLock() and OSSchedUnlock() in pair. In other words, for every
; * call to OSSchedLock() you MUST have a call to OSSchedUnlock().
; *********************************************************************************************************
; */
;
; #if OS_SCHED_LOCK_EN > 0
; void OSSchedUnlock (void) reentrant
RSEG ?PR?_?OSSchedUnlock?OS_CORE
_?OSSchedUnlock:
USING 0
; SOURCE LINE # 244
; {
;
;
; if (OSRunning == TRUE) { /* Make sure multitasking is running */
; SOURCE LINE # 248
MOV R0,#LOW (OSRunning)
MOV A,@R0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -