📄 os-task-switch.lst
字号:
(0051) return (OSERR_PRIO_EXIST);
0131 E003 LDI R16,3
0132 9624 ADIW R28,4
0133 D242 RCALL pop_gset3
0134 9508 RET
_OSTCBInit:
stk_size --> Y+6
ptos --> Y+4
prio --> R22
ptcb --> R20
0135 D235 RCALL push_gset2
0136 2F62 MOV R22,R18
0137 D2CD RCALL 0x0405
(0052) }
(0053) }
(0054)
(0055) /*
(0056) *********************************************************************************************************
(0057) * INITIALIZE TCB
(0058) *
(0059) * Description: This function is internal to uC/OS-II and is used to initialize a Task Control Block when
(0060) * a task is created (see OSTaskCreate() and OSTaskCreateExt()).
(0061) *
(0062) * Arguments : prio is the priority of the task being created
(0063) *
(0064) * ptos is a pointer to the task's top-of-stack assuming that the CPU registers
(0065) * have been placed on the stack. Note that the top-of-stack corresponds to a
(0066) * 'high' memory location is OS_STK_GROWTH is set to 1 and a 'low' memory
(0067) * location if OS_STK_GROWTH is set to 0. Note that stack growth is CPU
(0068) * specific.
(0069) *
(0070) * pbos is a pointer to the bottom of stack. A NULL pointer is passed if called by
(0071) * 'OSTaskCreate()'.
(0072) *
(0073) * id is the task's ID (0..65535)
(0074) *
(0075) * stk_size is the size of the stack (in 'stack units'). If the stack units are INT8Us
(0076) * then, 'stk_size' contains the number of bytes for the stack. If the stack
(0077) * units are INT32Us then, the stack contains '4 * stk_size' bytes. The stack
(0078) * units are established by the #define constant OS_STK which is CPU
(0079) * specific. 'stk_size' is 0 if called by 'OSTaskCreate()'.
(0080) *
(0081) * pext is a pointer to a user supplied memory area that is used to extend the task
(0082) * control block. This allows you to store the contents of floating-point
(0083) * registers, MMU registers or anything else you could find useful during a
(0084) * context switch. You can even assign a name to each task and store this name
(0085) * in this TCB extension. A NULL pointer is passed if called by OSTaskCreate().
(0086) *
(0087) * opt options as passed to 'OSTaskCreateExt()' or,
(0088) * 0 if called from 'OSTaskCreate()'.
(0089) *
(0090) * Returns : OS_NO_ERR if the call was successful
(0091) * OS_NO_MORE_TCB if there are no more free TCBs to be allocated and thus, the task cannot
(0092) * be created.
(0093) *
(0094) * Note : This function is INTERNAL to uC/OS-II and your application should not call it.
(0095) *********************************************************************************************************
(0096) */
(0097)
(0098) INT8U OSTCBInit (OS_TCB *ptcb,INT8U prio, OS_STK *ptos, INT16U stk_size)
(0099) {
(0100) #if OS_STRICT
(0101) if((0==ptcb)||(prio>OS_LOWEST_PRIO)||((INT16U)ptos<OS_HARDWARE_STACK_SIZE+40)||(stk_size<OS_HARDWARE_STACK_SIZE+40))
0138 F079 BEQ 0x0148
0139 E082 LDI R24,2
013A 1786 CP R24,R22
013B F060 BCS 0x0148
013C 818C LDD R24,4+Y
013D 819D LDD R25,5+Y
013E 3688 CPI R24,0x68
013F E0E0 LDI R30,0
0140 079E CPC R25,R30
0141 F030 BCS 0x0148
0142 818E LDD R24,6+Y
0143 819F LDD R25,7+Y
0144 3688 CPI R24,0x68
0145 E0E0 LDI R30,0
0146 079E CPC R25,R30
0147 F410 BCC 0x014A
(0102) OSError(0);
0148 2700 CLR R16
0149 D157 RCALL _OSError
(0103) #endif
(0104) OS_ENTER_CRITICAL();
014A 930A ST R16,-Y
014B B70F IN R16,P3F
014C 94F8 BCLR 7
014D 930F PUSH R16
014E 9109 LD R16,Y+
(0105) if ((OS_TCB *)0!=ptcb) {
014F 3040 CPI R20,0
0150 0745 CPC R20,R21
0151 F099 BEQ 0x0165
(0106) OS_EXIT_CRITICAL();
0152 930A ST R16,-Y
0153 910F POP R16
0154 BF0F OUT P3F,R16
0155 9109 LD R16,Y+
(0107) ptcb->OSTCBStkPtr = ptos; /* Load Stack pointer in TCB */
0156 2FE4 MOV R30,R20
0157 2FF5 MOV R31,R21
0158 800C LDD R0,4+Y
0159 801D LDD R1,5+Y
015A 8200 STD R0,0+Z
015B 8211 STD R1,1+Z
(0108) ptcb->OSTCBPrio = (INT8U)prio; /* Load task priority into TCB */
015C 8365 STD R22,5+Z
(0109) ptcb->OSTCBStat = OS_STAT_RDY; /* Task is ready to run */
015D E081 LDI R24,1
015E 8384 STD R24,4+Z
(0110) ptcb->OSTCBDly = 0; /* Task is not delayed */
015F 2422 CLR R2
0160 2433 CLR R3
0161 8222 STD R2,2+Z
0162 8233 STD R3,3+Z
(0111)
(0112) return (OS_NO_ERR);
0163 2700 CLR R16
0164 C005 RJMP 0x016A
(0113) } else {
(0114) OS_EXIT_CRITICAL();
0165 930A ST R16,-Y
0166 910F POP R16
0167 BF0F OUT P3F,R16
0168 9109 LD R16,Y+
(0115) return (OSERR_TCB_INVALID);
0169 E002 LDI R16,2
016A D209 RCALL pop_gset2
016B 9508 RET
(0116) }
(0117) }
(0118)
(0119) /*
(0120) *********************************************************************************************************
(0121) * SCHEDULER
(0122) *
(0123) * Description: This function is called by other uC/OS-II services to determine whether a new, high
(0124) * priority task has been made ready to run. This function is invoked by TASK level code
(0125) * and is not used to reschedule tasks from ISRs (see OSIntExit() for ISR rescheduling).
(0126) *
(0127) * Arguments : none
(0128) *
(0129) * Returns : none
(0130) *
(0131) * Notes : 1) This function is INTERNAL to uC/OS-II and your application should not call it.
(0132) * 2) Rescheduling is prevented when the scheduler is locked (see OSSchedLock())
(0133) *********************************************************************************************************
(0134) */
(0135)
(0136) void OSSched (void)
(0137) {
(0138) OS_ENTER_CRITICAL();
_OSSched:
016C 930A ST R16,-Y
016D B70F IN R16,P3F
016E 94F8 BCLR 7
016F 930F PUSH R16
0170 9109 LD R16,Y+
(0139) if ((OSLockNesting | OSIntNesting) == 0) { /* Task scheduling must be enabled and not ISR level */
0171 902001F9 LDS R2,_OSIntNesting
0173 903001F8 LDS R3,_OSLockNesting
0175 2832 OR R3,R2
0176 F4B9 BNE 0x018E
(0140) OSPrioHighRdy=OSGetPrioRdy();
0177 D047 RCALL _OSGetPrioRdy
0178 930001F6 STS R16,_OSPrioHighRdy
(0141) if(OSPrioHighRdy>OS_LOWEST_PRIO)
017A E082 LDI R24,2
017B 1780 CP R24,R16
017C F418 BCC 0x0180
(0142) {
(0143) #if OS_STRICT
(0144) OSError(0);
017D 2700 CLR R16
017E D122 RCALL _OSError
(0145) #endif
(0146) }else if (OSPrioHighRdy != OSPrioCur) { /* No context switch if current task is highest ready */
017F C00E RJMP 0x018E
0180 D279 RCALL 0x03FA
0181 F061 BEQ 0x018E
(0147) OSTCBHighRdy = OSpTCBList[OSPrioHighRdy];
0182 EF8A LDI R24,0xFA
0183 E091 LDI R25,1
0184 2DE3 MOV R30,R3
0185 D250 RCALL 0x03D6
0186 D25D RCALL 0x03E4
(0148) #if OS_STRICT
(0149) if(0==OSTCBHighRdy)
0187 2022 TST R2
0188 F421 BNE 0x018D
0189 2033 TST R3
018A F411 BNE 0x018D
(0150) OSError(0);
018B 2700 CLR R16
018C D114 RCALL _OSError
(0151) #endif
(0152) OS_TASK_SW(); /* Perform a context switch */
018D DEB0 RCALL _OSCtxSw
(0153) }//end OSPrioHighRdy != OSPrioCur
(0154) }//end nesting==0
(0155) OS_EXIT_CRITICAL();
018E 930A ST R16,-Y
018F 910F POP R16
0190 BF0F OUT P3F,R16
0191 9109 LD R16,Y+
(0156) }
0192 9508 RET
(0157)
(0158) /*
(0159) *********************************************************************************************************
(0160) * START MULTITASKING
(0161) *
(0162) * Description: This function is used to start the multitasking process which lets uC/OS-II manages the
(0163) * task that you have created. Before you can call OSStart(), you MUST have called OSInit()
(0164) * and you MUST have created at least one task.
(0165) *
(0166) * Arguments : none
(0167) *
(0168) * Returns : none
(0169) *
(0170) * Note : OSStartHighRdy() MUST:
(0171) * a) Call OSTaskSwHook() then,
(0172) * b) Set OSRunning to TRUE.
(0173) *********************************************************************************************************
(0174) */
(0175)
(0176) void OSStart (void)
(0177) {
(0178) if (OSRunning == FALSE) {
_OSStart:
0193 90200200 LDS R2,_OSRunning
0195 2022 TST R2
0196 F499 BNE 0x01AA
(0179) OSPrioHighRdy = 0;
0197 2422 CLR R2
0198 922001F6 STS R2,_OSPrioHighRdy
(0180) OSPrioCur = 0;
019A 922001F7 STS R2,_OSPrioCur
(0181) OSTCBHighRdy = OSpTCBList[OSPrioHighRdy]; /* Point to highest priority task ready to run */
019C EF8A LDI R24,0xFA
019D E091 LDI R25,1
019E 2DE2 MOV R30,R2
019F D236 RCALL 0x03D6
01A0 D243 RCALL 0x03E4
01A1 D268 RCALL 0x040A
(0182) OSTCBCur = OSTCBHighRdy;
(0183) #if OS_STRICT
(0184) if(0==OSTCBCur)
01A2 2022 TST R2
01A3 F421 BNE 0x01A8
01A4 2033 TST R3
01A5 F411 BNE 0x01A8
(0185) OSError(0);
01A6 2700 CLR R16
01A7 D0F9 RCALL _OSError
(0186) #endif
(0187) OSStartHighRdy(); /* Execute target specific code to start task */
01A8 DE87 RCALL _OSStartHighRdy
(0188) }
01A9 C002 RJMP 0x01AC
(0189) #if OS_STRICT
(0190) else OSError(0);
01AA 2700 CLR R16
01AB D0F5 RCALL _OSError
(0191) #endif
(0192) }
01AC 9508 RET
_OSTimeDly:
ticks --> R20
01AD D1A6 RCALL push_gset1
01AE D256 RCALL 0x0405
(0193)
(0194) /*
(0195) *********************************************************************************************************
(0196) * DELAY TASK 'n' TICKS (n from 0 to 65535)
(0197) *
(0198) * Description: This function is called to delay execution of the currently running task until the
(0199) * specified number of system ticks expires. This, of course, directly equates to delaying
(0200) * the current task for some time to expire. No delay will result If the specified delay is
(0201) * 0. If the specified delay is greater than 0 then, a context switch will result.
(0202) *
(0203) * Arguments : ticks is the time delay that the task will be suspended in number of clock 'ticks'.
(0204) * Note that by specifying 0, the task will not be delayed.
(0205) *
(0206) * Returns : none
(0207) *********************************************************************************************************
(0208) */
(0209)
(0210) void OSTimeDly (INT16U ticks)
(0211) {
(0212) if (ticks > 0) { /* 0 means no delay! */
01AF F069 BEQ 0x01BD
(0213) OS_ENTER_CRITICAL();
01B0 930A ST R16,-Y
01B1 B70F IN R16,P3F
01B2 94F8 BCLR 7
01B3 930F PUSH R16
01B4 9109 LD R16,Y+
01B5 D23A RCALL 0x03F0
(0214) OSTCBCur->OSTCBDly = ticks; /* Load ticks in TCB */
01B6 8342 STD R20,2+Z
01B7 8353 STD R21,3+Z
(0215) OS_EXIT_CRITICAL();
01B8 930A ST R16,-Y
01B9 910F POP R16
01BA BF0F OUT P3F,R16
01BB 9109 LD R16,Y+
(0216) OSSched(); /* Find next task to run! */
01BC DFAF RCALL _OSSched
(0217) }
(0218) }
01BD D199 RCALL pop_gset1
01BE 9508 RET
_OSGetPrioRdy:
ret --> R20
i --> R22
ptcb --> R10
01BF D1AE RCALL push_gset3
(0219)
(0220) INT8U OSGetPrioRdy(void)
(0221) {
(0222) INT8U i,ret=0xff;
01C0 EF4F LDI R20,0xFF
(0223) OS_TCB *ptcb;
(0224) for(i=0;i<OS_TASK_COUNT;i++)
01C1 2766 CLR R22
01C2 C026 RJMP 0x01E9
(0225) {
(0226) ptcb=OSpTCBList[i];
01C3 EF8A LDI R24,0xFA
01C4 E091 LDI R25,1
01C5 2FE6 MOV R30,R22
01C6 D20F RCALL 0x03D6
01C7 80A0 LDD R10,0+Z
01C8 80B1 LDD R11,1+Z
(0227) //OS_ENTER_CRITICAL();
(0228) if(ptcb)
01C9 20AA TST R10
01CA F411 BNE 0x01CD
01CB 20BB TST R11
01CC F0D9 BEQ 0x01E8
(0229) if((0==ptcb->OSTCBDly)&&
01CD 2DEA MOV R30,R10
01CE 2DFB MOV R31,R11
01CF 8022 LDD R2,2+Z
01D0 8033 LDD R3,3+Z
01D1 2022 TST R2
01D2 F4A9 BNE 0x01E8
01D3 2033 TST R3
01D4 F499 BNE 0x01E8
01D5 2DEA MOV R30,R10
01D6 2DFB MOV R31,R11
01D7 8184 LDD R24,4+Z
01D8 3081 CPI R24,1
01D9 F471 BNE 0x01E8
(0230) (OS_STAT_RDY==ptcb->OSTCBStat))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -