📄 os_core.s
字号:
;
; #if OS_EVENT_TBL_SIZE > 3
; *ptbl++ = 0x00;
; #endif
;
; #if OS_EVENT_TBL_SIZE > 4
; *ptbl++ = 0x00;
; #endif
;
; #if OS_EVENT_TBL_SIZE > 5
; *ptbl++ = 0x00;
; #endif
;
; #if OS_EVENT_TBL_SIZE > 6
; *ptbl++ = 0x00;
; #endif
;
; #if OS_EVENT_TBL_SIZE > 7
; *ptbl = 0x00;
; #endif
; }
; #endif
; /*$PAGE*/
; /*
; *********************************************************************************************************
; * SCHEDULER
; *
; * Description: This function is called by other uC/OS-II services to determine whether a new, high
; * priority task has been made ready to run. This function is invoked by TASK level code
; * and is not used to reschedule tasks from ISRs (see OSIntExit() for ISR rescheduling).
; *
; * Arguments : none
; *
; * Returns : none
; *
; * Notes : 1) This function is INTERNAL to uC/OS-II and your application should not call it.
; * 2) Rescheduling is prevented when the scheduler is locked (see OSSchedLock())
; *********************************************************************************************************
; */
;
; void OS_Sched (void)
; {
.dbline 743
; #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
; OS_CPU_SR cpu_sr;
; #endif
; INT8U y;
;
;
; OS_ENTER_CRITICAL();
rcall _OS_CPU_SR_Save
mov R10,R16
.dbline 744
; if ((OSIntNesting == 0) && (OSLockNesting == 0)) { /* Sched. only if all ISRs done & not locked */
lds R2,_OSIntNesting
tst R2
breq X8
rjmp L60
X8:
lds R2,_OSLockNesting
tst R2
breq X9
rjmp L60
X9:
.dbline 744
.dbline 745
; y = OSUnMapTbl[OSRdyGrp]; /* Get pointer to HPT ready to run */
ldi R24,<_OSUnMapTbl
ldi R25,>_OSUnMapTbl
lds R30,_OSRdyGrp
clr R31
add R30,R24
adc R31,R25
lpm R12,Z
.dbline 746
; OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]);
ldi R24,<_OSRdyTbl
ldi R25,>_OSRdyTbl
mov R30,R12
clr R31
add R30,R24
adc R31,R25
ldd R30,z+0
clr R31
ldi R24,<_OSUnMapTbl
ldi R25,>_OSUnMapTbl
add R30,R24
adc R31,R25
lpm R2,Z
clr R3
mov R4,R12
clr R5
lsl R4
rol R5
lsl R4
rol R5
lsl R4
rol R5
add R4,R2
adc R5,R3
sts _OSPrioHighRdy,R4
.dbline 747
; if (OSPrioHighRdy != OSPrioCur) { /* No Ctx Sw if current task is highest rdy */
lds R2,_OSPrioCur
cp R4,R2
breq L62
.dbline 747
.dbline 748
; OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
mov R2,R4
ldi R24,2
mul R24,R2
movw R30,R0
ldi R24,<_OSTCBPrioTbl
ldi R25,>_OSTCBPrioTbl
add R30,R24
adc R31,R25
ldd R2,z+0
ldd R3,z+1
sts _OSTCBHighRdy+1,R3
sts _OSTCBHighRdy,R2
.dbline 749
; OSCtxSwCtr++; /* Increment context switch counter */
ldi R20,1
ldi R21,0
ldi R22,0
ldi R23,0
lds R4,_OSCtxSwCtr+2
lds R5,_OSCtxSwCtr+2+1
lds R2,_OSCtxSwCtr
lds R3,_OSCtxSwCtr+1
add R2,R20
adc R3,R21
adc R4,R22
adc R5,R23
sts _OSCtxSwCtr+1,R3
sts _OSCtxSwCtr,R2
sts _OSCtxSwCtr+2+1,R5
sts _OSCtxSwCtr+2,R4
.dbline 750
; OS_TASK_SW(); /* Perform a context switch */
rcall _OSCtxSw
.dbline 751
; }
L62:
.dbline 752
; }
L60:
.dbline 753
; OS_EXIT_CRITICAL();
mov R16,R10
rcall _OS_CPU_SR_Restore
.dbline -2
L59:
rcall pop_gset4
.dbline 0 ; func end
ret
.dbsym r y 12 c
.dbsym r cpu_sr 10 c
.dbend
.dbfunc e OS_TaskIdle _OS_TaskIdle fV
; cpu_sr -> R10
; pdata -> R10,R11
.even
_OS_TaskIdle::
rcall push_gset3
movw R10,R16
.dbline -1
.dbline 778
; }
; /*$PAGE*/
; /*
; *********************************************************************************************************
; * IDLE TASK
; *
; * Description: This task is internal to uC/OS-II and executes whenever no other higher priority tasks
; * executes because they are ALL waiting for event(s) to occur.
; *
; * Arguments : none
; *
; * Returns : none
; *
; * Note(s) : 1) OSTaskIdleHook() is called after the critical section to ensure that interrupts will be
; * enabled for at least a few instructions. On some processors (ex. Philips XA), enabling
; * and then disabling interrupts didn't allow the processor enough time to have interrupts
; * enabled before they were disabled again. uC/OS-II would thus never recognize
; * interrupts.
; * 2) This hook has been added to allow you to do such things as STOP the CPU to conserve
; * power.
; *********************************************************************************************************
; */
;
; void OS_TaskIdle (void *pdata)
; {
.dbline 784
; #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
; OS_CPU_SR cpu_sr;
; #endif
;
;
; pdata = pdata; /* Prevent compiler warning for not using 'pdata' */
.dbline 785
L65:
.dbline 785
.dbline 786
rcall _OS_CPU_SR_Save
mov R10,R16
.dbline 787
ldi R20,1
ldi R21,0
ldi R22,0
ldi R23,0
lds R4,_OSIdleCtr+2
lds R5,_OSIdleCtr+2+1
lds R2,_OSIdleCtr
lds R3,_OSIdleCtr+1
add R2,R20
adc R3,R21
adc R4,R22
adc R5,R23
sts _OSIdleCtr+1,R3
sts _OSIdleCtr,R2
sts _OSIdleCtr+2+1,R5
sts _OSIdleCtr+2,R4
.dbline 788
rcall _OS_CPU_SR_Restore
.dbline 789
rcall _OSTaskIdleHook
.dbline 790
.dbline 785
.dbline 785
rjmp L65
X10:
.dbline -2
L64:
rcall pop_gset3
.dbline 0 ; func end
ret
.dbsym r cpu_sr 10 c
.dbsym r pdata 10 pV
.dbend
.dbfunc e OS_TCBInit _OS_TCBInit fc
; cpu_sr -> R20
; ptcb -> R22,R23
; opt -> y+18
; pext -> y+16
; stk_size -> y+12
; id -> y+10
; pbos -> y+8
; ptos -> R12,R13
; prio -> R10
.even
_OS_TCBInit::
rcall push_gset4
movw R12,R18
mov R10,R16
.dbline -1
.dbline 899
; for (;;) {
; OS_ENTER_CRITICAL();
; OSIdleCtr++;
; OS_EXIT_CRITICAL();
; OSTaskIdleHook(); /* Call user definable HOOK */
; }
; }
; /*$PAGE*/
; /*
; *********************************************************************************************************
; * STATISTICS TASK
; *
; * Description: This task is internal to uC/OS-II and is used to compute some statistics about the
; * multitasking environment. Specifically, OS_TaskStat() computes the CPU usage.
; * CPU usage is determined by:
; *
; * OSIdleCtr
; * OSCPUUsage = 100 * (1 - ------------) (units are in %)
; * OSIdleCtrMax
; *
; * Arguments : pdata this pointer is not used at this time.
; *
; * Returns : none
; *
; * Notes : 1) This task runs at a priority level higher than the idle task. In fact, it runs at the
; * next higher priority, OS_IDLE_PRIO-1.
; * 2) You can disable this task by setting the configuration #define OS_TASK_STAT_EN to 0.
; * 3) We delay for 5 seconds in the beginning to allow the system to reach steady state and
; * have all other tasks created before we do statistics. You MUST have at least a delay
; * of 2 seconds to allow for the system to establish the maximum value for the idle
; * counter.
; *********************************************************************************************************
; */
;
; #if OS_TASK_STAT_EN > 0
; void OS_TaskStat (void *pdata)
; {
; #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
; OS_CPU_SR cpu_sr;
; #endif
; INT32U run;
; INT8S usage;
;
;
; pdata = pdata; /* Prevent compiler warning for not using 'pdata' */
; while (OSStatRdy == FALSE) {
; OSTimeDly(2 * OS_TICKS_PER_SEC); /* Wait until statistic task is ready */
; }
; for (;;) {
; OS_ENTER_CRITICAL();
; OSIdleCtrRun = OSIdleCtr; /* Obtain the of the idle counter for the past second */
; run = OSIdleCtr;
; OSIdleCtr = 0L; /* Reset the idle counter for the next second */
; OS_EXIT_CRITICAL();
; if (OSIdleCtrMax > 0L) {
; usage = (INT8S)(100L - 100L * run / OSIdleCtrMax);
; if (usage >= 0) { /* Make sure we don't have a negative percentage */
; OSCPUUsage = usage;
; } else {
; OSCPUUsage = 0;
; }
; } else {
; OSCPUUsage = 0;
; }
; OSTaskStatHook(); /* Invoke user definable hook */
; OSTimeDly(OS_TICKS_PER_SEC); /* Accumulate OSIdleCtr for the next second */
; }
; }
; #endif
; /*$PAGE*/
; /*
; *********************************************************************************************************
; * INITIALIZE TCB
; *
; * Description: This function is internal to uC/OS-II and is used to initialize a Task Control Block when
; * a task is created (see OSTaskCreate() and OSTaskCreateExt()).
; *
; * Arguments : prio is the priority of the task being created
; *
; * ptos is a pointer to the task's top-of-stack assuming that the CPU registers
; * have been placed on the stack. Note that the top-of-stack corresponds to a
; * 'high' memory location is OS_STK_GROWTH is set to 1 and a 'low' memory
; * location if OS_STK_GROWTH is set to 0. Note that stack growth is CPU
; * specific.
; *
; * pbos is a pointer to the bottom of stack. A NULL pointer is passed if called by
; * 'OSTaskCreate()'.
; *
; * id is the task's ID (0..65535)
; *
; * stk_size is the size of the stack (in 'stack units'). If the stack units are INT8Us
; * then, 'stk_size' contains the number of bytes for the stack. If the stack
; * units are INT32Us then, the stack contains '4 * stk_size' bytes. The stack
; * units are established by the #define constant OS_STK which is CPU
; * specific. 'stk_size' is 0 if called by 'OSTaskCreate()'.
; *
; * pext is a pointer to a user supplied memory area that is used to extend the task
; * control block. This allows you to store the contents of floating-point
; * registers, MMU registers or anything else you could find useful during a
; * context switch. You can even assign a name to each task and store this name
; * in this TCB extension. A NULL pointer is passed if called by OSTaskCreate().
; *
; * opt options as passed to 'OSTaskCreateExt()' or,
; * 0 if called from 'OSTaskCreate()'.
; *
; * Returns : OS_NO_ERR if the call was successful
; * OS_NO_MORE_TCB if there are no more free TCBs to be allocated and thus, the task cannot
; * be created.
; *
; * Note : This function is INTERNAL to uC/OS-II and your application should not call it.
; *********************************************************************************************************
; */
;
; INT8U OS_TCBInit (INT8U prio, OS_STK *ptos, OS_STK *pbos, INT16U id, INT32U stk_size, void *pext, INT16U opt)
; {
.dbline 906
; #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
; OS_CPU_SR cpu_sr;
; #endif
; OS_TCB *ptcb;
;
;
; OS_ENTER_CRITICAL();
rcall _OS_CPU_SR_Save
mov R20,R16
.dbline 907
; ptcb = OSTCBFreeList; /* Get a free TCB from the free TCB list */
lds R22,_OSTCBFreeList
lds R23,_OSTCBFreeList+1
.dbline 908
; if (ptcb != (OS_TCB *)0) {
cpi R22,0
cpc R22,R23
brne X13
rjmp L70
X13:
X11:
.dbline 908
.dbline 909
; OSTCBFreeList = ptcb->OSTCBNext; /* Update pointer to free TCB list */
movw R30,R22
ldd R2,z+2
ldd R3,z+3
sts _OSTCBFreeList+1,R3
sts _OSTCBFreeList,R2
.dbline 910
; OS_EXIT_CRITICAL();
mov R16,R20
rcall _OS_CPU_SR_Restore
.dbline 911
; ptcb->OSTCBStkPtr = ptos; /* Load Stack pointer in TCB */
movw R30,R22
std z+1,R13
std z+0,R12
.dbline 912
; ptcb->OSTCBPrio = (INT8U)prio; /* Load task priority into TCB */
std z+11,R10
.dbline 913
; ptcb->OSTCBStat = OS_STAT_RDY; /* Task is ready to run */
clr R2
movw R30,R22
std z+10,R2
.dbline 914
; ptcb->OSTCBDly = 0; /* Task is not delayed */
clr R3
movw R30,R22
std z+9,R3
std z+8,R2
.dbline 923
;
; #if OS_TASK_CREATE_EXT_EN > 0
; ptcb->OSTCBExtPtr = pext; /* Store pointer to TCB extension */
; ptcb->OSTCBStkSize = stk_size; /* Store stack size */
; ptcb->OSTCBStkBottom = pbos; /* Store pointer to bottom of stack */
; ptcb->OSTCBOpt = opt; /* Store task options */
; ptcb->OSTCBId = id; /* Store task ID */
; #else
; pext = pext; /* Prevent compiler warning if not used */
.dbline 924
; stk_size = stk_size;
movw R30,R28
ldd R2,z+12
ldd R3,z+13
ldd R4,z+14
ldd R5,z+15
movw R30,R28
std z+12,R2
std z+13,R3
std z+14,R4
std z+15,R5
.dbline 925
; pbos = pbos;
.dbline 926
; opt = opt;
.dbline 927
; id = id;
.dbline 934
; #endif
;
; #if OS_TASK_DEL_EN > 0
; ptcb->OSTCBDelReq
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -