📄 os_core.s43
字号:
; 852. /*
; 853. *********************************************************************************************************
; 854. * SCHEDULER
; 855. *
; 856. * Description: This function is called by other uC/OS-II services to determine whether a new, high
; 857. * priority task has been made ready to run. This function is invoked by TASK level code
; 858. * and is not used to reschedule tasks from ISRs (see OSIntExit() for ISR rescheduling).
; 859. *
; 860. * Arguments : none
; 861. *
; 862. * Returns : none
; 863. *
; 864. * Notes : 1) This function is INTERNAL to uC/OS-II and your application should not call it.
; 865. * 2) Rescheduling is prevented when the scheduler is locked (see OS_SchedLock())
; 866. *********************************************************************************************************
; 867. */
; 868.
; 869. void OS_Sched (void)
; 870. {
; 871. #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
; 872. OS_CPU_SR cpu_sr;
; 873. #endif
; 874. INT8U y;
; 875.
; 876.
; 877. OS_ENTER_CRITICAL();
DINT
; 878. if ((OSIntNesting == 0) && (OSLockNesting == 0)) { /* Sched. only if all ISRs done & not locked */
CMP.B #0,&OSIntNesting
JNE (?0161)
CMP.B #0,&OSLockNesting
JNE (?0161)
; 879. y = OSUnMapTbl[OSRdyGrp]; /* Get pointer to HPT ready to run */
MOV.B &OSRdyGrp,R13
MOV.B OSUnMapTbl(R13),R12
; 880. OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]);
MOV.B R12,R13
MOV.B OSRdyTbl(R13),R13
ADD.B R12,R12
ADD.B R12,R12
ADD.B R12,R12
ADD.B OSUnMapTbl(R13),R12
MOV.B R12,&OSPrioHighRdy
; 881. if (OSPrioHighRdy != OSPrioCur) { /* No Ctx Sw if current task is highest rdy */
CMP.B &OSPrioHighRdy,&OSPrioCur
JEQ (?0161)
; 882. OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
MOV.B &OSPrioHighRdy,R12
ADD R12,R12
MOV OSTCBPrioTbl(R12),&OSTCBHighRdy
; 883. OSCtxSwCtr++; /* Increment context switch counter */
ADD #1,&OSCtxSwCtr
ADDC #0,&(OSCtxSwCtr+2)
; 884. OS_TASK_SW(); /* Perform a context switch */
CALL #OSCtxSw
?0161:
; 885. }
; 886. }
; 887. OS_EXIT_CRITICAL();
EINT
; 888. }
RET
OS_TaskIdle:
; 889. /*$PAGE*/
; 890. /*
; 891. *********************************************************************************************************
; 892. * IDLE TASK
; 893. *
; 894. * Description: This task is internal to uC/OS-II and executes whenever no other higher priority tasks
; 895. * executes because they are ALL waiting for event(s) to occur.
; 896. *
; 897. * Arguments : none
; 898. *
; 899. * Returns : none
; 900. *
; 901. * Note(s) : 1) OSTaskIdleHook() is called after the critical section to ensure that interrupts will be
; 902. * enabled for at least a few instructions. On some processors (ex. Philips XA), enabling
; 903. * and then disabling interrupts didn't allow the processor enough time to have interrupts
; 904. * enabled before they were disabled again. uC/OS-II would thus never recognize
; 905. * interrupts.
; 906. * 2) This hook has been added to allow you to do such things as STOP the CPU to conserve
; 907. * power.
; 908. *********************************************************************************************************
; 909. */
; 910.
; 911. void OS_TaskIdle (void *pdata)
; 912. {
; 913. #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
; 914. OS_CPU_SR cpu_sr;
; 915. #endif
; 916.
; 917.
; 918. pdata = pdata; /* Prevent compiler warning for not using 'pdata' */
?0163:
; 919. for (;;) {
; 920. OS_ENTER_CRITICAL();
DINT
; 921. OSIdleCtr++;
ADD #1,&OSIdleCtr
ADDC #0,&(OSIdleCtr+2)
; 922. OS_EXIT_CRITICAL();
EINT
; 923. OSTaskIdleHook(); /* Call user definable HOOK */
CALL #OSTaskIdleHook
; 924. }
; 925. }
JMP (?0163)
OS_TaskStat:
; 926. /*$PAGE*/
; 927. /*
; 928. *********************************************************************************************************
; 929. * STATISTICS TASK
; 930. *
; 931. * Description: This task is internal to uC/OS-II and is used to compute some statistics about the
; 932. * multitasking environment. Specifically, OS_TaskStat() computes the CPU usage.
; 933. * CPU usage is determined by:
; 934. *
; 935. * OSIdleCtr
; 936. * OSCPUUsage = 100 * (1 - ------------) (units are in %)
; 937. * OSIdleCtrMax
; 938. *
; 939. * Arguments : pdata this pointer is not used at this time.
; 940. *
; 941. * Returns : none
; 942. *
; 943. * Notes : 1) This task runs at a priority level higher than the idle task. In fact, it runs at the
; 944. * next higher priority, OS_IDLE_PRIO-1.
; 945. * 2) You can disable this task by setting the configuration #define OS_TASK_STAT_EN to 0.
; 946. * 3) We delay for 5 seconds in the beginning to allow the system to reach steady state and
; 947. * have all other tasks created before we do statistics. You MUST have at least a delay
; 948. * of 2 seconds to allow for the system to establish the maximum value for the idle
; 949. * counter.
; 950. *********************************************************************************************************
; 951. */
; 952.
; 953. #if OS_TASK_STAT_EN > 0
; 954. void OS_TaskStat (void *pdata)
; 955. {
PUSH R10
PUSH R11
; 956. #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
; 957. OS_CPU_SR cpu_sr;
; 958. #endif
; 959. INT32U run;
; 960. INT32U max;
; 961. INT8S usage;
; 962.
; 963.
; 964. pdata = pdata; /* Prevent compiler warning for not using 'pdata' */
?0165:
; 965. while (OSStatRdy == FALSE) {
CMP.B #0,&OSStatRdy
JNE (?0164)
; 966. OSTimeDly(2 * OS_TICKS_PER_SEC); /* Wait until statistic task is ready */
MOV #400,R12
CALL #OSTimeDly
JMP (?0165)
?0164:
; 967. }
; 968. max = OSIdleCtrMax / 100L;
MOV &OSIdleCtrMax,R12
MOV &(OSIdleCtrMax+2),R13
MOV #100,R14
MOV #0,R15
CALL #?UL_DIVMOD_L03
MOV R12,R10
MOV R13,R11
?0168:
; 969. for (;;) {
; 970. OS_ENTER_CRITICAL();
DINT
; 971. OSIdleCtrRun = OSIdleCtr; /* Obtain the of the idle counter for the past second */
MOV &OSIdleCtr,&OSIdleCtrRun
MOV &(OSIdleCtr+2),&(OSIdleCtrRun+2)
; 972. run = OSIdleCtr;
MOV &OSIdleCtr,R12
MOV &(OSIdleCtr+2),R13
; 973. OSIdleCtr = 0L; /* Reset the idle counter for the next second */
MOV #0,&OSIdleCtr
MOV #0,&(OSIdleCtr+2)
; 974. OS_EXIT_CRITICAL();
EINT
; 975. if (max > 0L) {
MOV R10,R14
BIS R11,R14
CMP #0,R14
JEQ (?0170)
; 976. usage = (INT8S)(100L - run / max);
MOV R10,R14
MOV R11,R15
CALL #?UL_DIVMOD_L03
XOR.B #-1,R12
ADD.B #1,R12
ADD.B #100,R12
; 977. if (usage >= 0) { /* Make sure we don't have a negative percentage */
JL (?0172)
; 978. OSCPUUsage = usage;
MOV.B R12,&OSCPUUsage
; 979. } else {
JMP (?0174)
?0172:
; 980. OSCPUUsage = 0;
MOV.B #0,&OSCPUUsage
; 981. }
; 982. } else {
JMP (?0174)
?0170:
; 983. OSCPUUsage = 0;
MOV.B #0,&OSCPUUsage
; 984. max = OSIdleCtrMax / 100L;
MOV &OSIdleCtrMax,R12
MOV &(OSIdleCtrMax+2),R13
MOV #100,R14
MOV #0,R15
CALL #?UL_DIVMOD_L03
MOV R12,R10
MOV R13,R11
?0174:
; 985. }
; 986. OSTaskStatHook(); /* Invoke user definable hook */
CALL #OSTaskStatHook
; 987. OSTimeDly(OS_TICKS_PER_SEC); /* Accumulate OSIdleCtr for the next second */
MOV #200,R12
CALL #OSTimeDly
; 988. }
; 989. }
JMP (?0168)
OS_TCBInit:
; 990. #endif
; 991. /*$PAGE*/
; 992. /*
; 993. *********************************************************************************************************
; 994. * INITIALIZE TCB
; 995. *
; 996. * Description: This function is internal to uC/OS-II and is used to initialize a Task Control Block when
; 997. * a task is created (see OSTaskCreate() and OSTaskCreateExt()).
; 998. *
; 999. * Arguments : prio is the priority of the task being created
; 1000. *
; 1001. * ptos is a pointer to the task's top-of-stack assuming that the CPU registers
; 1002. * have been placed on the stack. Note that the top-of-stack corresponds to a
; 1003. * 'high' memory location is OS_STK_GROWTH is set to 1 and a 'low' memory
; 1004. * location if OS_STK_GROWTH is set to 0. Note that stack growth is CPU
; 1005. * specific.
; 1006. *
; 1007. * pbos is a pointer to the bottom of stack. A NULL pointer is passed if called by
; 1008. * 'OSTaskCreate()'.
; 1009. *
; 1010. * id is the task's ID (0..65535)
; 1011. *
; 1012. * stk_size is the size of the stack (in 'stack units'). If the stack units are INT8Us
; 1013. * then, 'stk_size' contains the number of bytes for the stack. If the stack
; 1014. * units are INT32Us then, the stack contains '4 * stk_size' bytes. The stack
; 1015. * units are established by the #define constant OS_STK which is CPU
; 1016. * specific. 'stk_size' is 0 if called by 'OSTaskCreate()'.
; 1017. *
; 1018. * pext is a pointer to a user supplied memory area that is used to extend the task
; 1019. * control block. This allows you to store the contents of floating-point
; 1020. * registers, MMU registers or anything else you could find useful during a
; 1021. * context switch. You can even assign a name to each task and store this name
; 1022. * in this TCB extension. A NULL pointer is passed if called by OSTaskCreate().
; 1023. *
; 1024. * opt options as passed to 'OSTaskCreateExt()' or,
; 1025. * 0 if called from 'OSTaskCreate()'.
; 1026. *
; 1027. * Returns : OS_NO_ERR if the call was successful
; 1028. * OS_NO_MORE_TCB if there are no more free TCBs to be allocated and thus, the task cannot
; 1029. * be created.
; 1030. *
; 1031. * Note : This function is INTERNAL to uC/OS-II and your application should not call it.
; 1032. *********************************************************************************************************
; 1033. */
; 1034.
; 1035. INT8U OS_TCBInit (INT8U prio, OS_STK *ptos, OS_STK *pbos, INT16U id, INT32U stk_size, void *pext, INT16U opt)
; 1036. {
PUSH R10
PUSH R11
MOV.B R12,R10
; 1037. #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
; 1038. OS_CPU_SR cpu_sr;
; 1039. #endif
; 1040. OS_TCB *ptcb;
; 1041.
; 1042.
; 1043. OS_ENTER_CRITICAL();
DINT
; 1044. ptcb = OSTCBFreeList; /* Get a free TCB from the free TCB list */
MOV &OSTCBFreeList,R11
; 1045. if (ptcb != (OS_TCB *)0) {
CMP #0,R11
JEQ (?0176)
; 1046. OSTCBFreeList = ptcb->OSTCBNext; /* Update pointer to free TCB list */
MOV 14(R11),&OSTCBFreeList
; 1047. OS_EXIT_CRITICAL();
EINT
; 1048. ptcb->OSTCBStkPtr = ptos; /* Load Stack pointer in TCB */
MOV R14,0(R11)
; 1049. ptcb->OSTCBPrio = (INT8U)prio; /* Load task priority into TCB */
MOV.B R10,29(R11)
; 1050. ptcb->OSTCBStat = OS_STAT_RDY; /* Task is ready to run */
MOV.B #0,28(R11)
; 1051. ptcb->OSTCBDly = 0; /* Task is not delayed */
MOV #0,26(R11)
; 1052.
; 1053. #if OS_TASK_CREATE_EXT_EN > 0
; 1054. ptcb->OSTCBExtPtr = pext; /* Store pointer to TCB extension */
MOV 14(SP),2(R11)
; 1055. ptcb->OSTCBStkSize = stk_size; /* Store stack size */
MOV 10(SP),6(R11)
MOV 12(SP),8(R11)
; 1056. ptcb->OSTCBStkBottom = pbos; /* Store pointer to bottom of stack */
MOV 6(SP),4(R11)
; 1057. ptcb->OSTCBOpt = opt; /* Store task options */
MOV 16(SP),10(R11)
; 1058. ptcb->OSTCBId = id; /* Store task ID */
MOV 8(SP),12(R11)
; 1059. #else
; 1060. pext = pext; /* Prevent compiler warning if not used */
; 1061. stk_size = stk_size;
; 1062. pbos = pbos;
; 1063. opt = opt;
; 1064. id
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -