test.lst
来自「基于mega128的ucos参考源码」· LST 代码 · 共 1,556 行 · 第 1/5 页
LST
1,556 行
(0267) }
(0268) /*$PAGE*/
(0269) /*
(0270) *********************************************************************************************************
(0271) * ENTER ISR
(0272) *
(0273) * Description: This function is used to notify uC/OS-II that you are about to service an interrupt
(0274) * service routine (ISR). This allows uC/OS-II to keep track of interrupt nesting and thus
(0275) * only perform rescheduling at the last nested ISR.
(0276) *
(0277) * Arguments : none
(0278) *
(0279) * Returns : none
(0280) *
(0281) * Notes : 1) This function should be called ith interrupts already disabled
(0282) * 2) Your ISR can directly increment OSIntNesting without calling this function because
(0283) * OSIntNesting has been declared 'global'.
(0284) * 3) You MUST still call OSIntExit() even though you increment OSIntNesting directly.
(0285) * 4) You MUST invoke OSIntEnter() and OSIntExit() in pair. In other words, for every call
(0286) * to OSIntEnter() at the beginning of the ISR you MUST have a call to OSIntExit() at the
(0287) * end of the ISR.
(0288) * 5) You are allowed to nest interrupts up to 255 levels deep.
(0289) * 6) I removed the OS_ENTER_CRITICAL() and OS_EXIT_CRITICAL() around the increment because
(0290) * OSIntEnter() is always called with interrupts disabled.
(0291) *********************************************************************************************************
(0292) */
(0293)
(0294) void OSIntEnter (void)
(0295) {
(0296) if (OSRunning == TRUE) {
_OSIntEnter:
0129 9180030D LDS R24,OSRunning
012B 3081 CPI R24,1
012C F439 BNE 0x0134
(0297) if (OSIntNesting < 255u) {
012D 91800315 LDS R24,OSIntNesting
012F 3F8F CPI R24,0xFF
0130 F418 BCC 0x0134
(0298) OSIntNesting++; /* Increment ISR nesting level */
0131 5F8F SUBI R24,0xFF
0132 93800315 STS OSIntNesting,R24
(0299) }
(0300) }
0134 9508 RET
_OSIntExit:
cpu_sr --> R10
0135 940E0E14 CALL push_gset3
(0301) }
(0302) /*$PAGE*/
(0303) /*
(0304) *********************************************************************************************************
(0305) * EXIT ISR
(0306) *
(0307) * Description: This function is used to notify uC/OS-II that you have completed serviving an ISR. When
(0308) * the last nested ISR has completed, uC/OS-II will call the scheduler to determine whether
(0309) * a new, high-priority task, is ready to run.
(0310) *
(0311) * Arguments : none
(0312) *
(0313) * Returns : none
(0314) *
(0315) * Notes : 1) You MUST invoke OSIntEnter() and OSIntExit() in pair. In other words, for every call
(0316) * to OSIntEnter() at the beginning of the ISR you MUST have a call to OSIntExit() at the
(0317) * end of the ISR.
(0318) * 2) Rescheduling is prevented when the scheduler is locked (see OS_SchedLock())
(0319) *********************************************************************************************************
(0320) */
(0321)
(0322) void OSIntExit (void)
(0323) {
(0324) #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
(0325) OS_CPU_SR cpu_sr;
(0326) #endif
(0327)
(0328)
(0329) if (OSRunning == TRUE) {
0137 9180030D LDS R24,OSRunning
0139 3081 CPI R24,1
013A F009 BEQ 0x013C
013B C07D RJMP 0x01B9
(0330) OS_ENTER_CRITICAL();
013C 940E09FC CALL _OS_CPU_SR_Save
013E 2EA0 MOV R10,R16
(0331) if (OSIntNesting > 0) { /* Prevent OSIntNesting from wrapping */
013F 2422 CLR R2
0140 90300315 LDS R3,OSIntNesting
0142 1423 CP R2,R3
0143 F420 BCC 0x0148
(0332) OSIntNesting--;
0144 2D83 MOV R24,R3
0145 5081 SUBI R24,1
0146 93800315 STS OSIntNesting,R24
(0333) }
(0334) if (OSIntNesting == 0) { /* Reschedule only if all ISRs complete ... */
0148 90200315 LDS R2,OSIntNesting
014A 2022 TST R2
014B F009 BEQ 0x014D
014C C069 RJMP 0x01B6
(0335) if (OSLockNesting == 0) { /* ... and not locked. */
014D 90200313 LDS R2,OSLockNesting
014F 2022 TST R2
0150 F009 BEQ 0x0152
0151 C064 RJMP 0x01B6
(0336) OSIntExitY = OSUnMapTbl[OSRdyGrp];
0152 E98C LDI R24,0x9C
0153 E090 LDI R25,0
0154 91E00310 LDS R30,OSRdyGrp
0156 27FF CLR R31
0157 0FE8 ADD R30,R24
0158 1FF9 ADC R31,R25
0159 91E4 LPM R30,0(Z)
015A 93E00314 STS OSIntExitY,R30
(0337) OSPrioHighRdy = (INT8U)((OSIntExitY << 3) + OSUnMapTbl[OSRdyTbl[OSIntExitY]]);
015C E08E LDI R24,0xE
015D E093 LDI R25,3
015E 27FF CLR R31
015F 0FE8 ADD R30,R24
0160 1FF9 ADC R31,R25
0161 81E0 LDD R30,Z+0
0162 27FF CLR R31
0163 E98C LDI R24,0x9C
0164 E090 LDI R25,0
0165 0FE8 ADD R30,R24
0166 1FF9 ADC R31,R25
0167 9024 LPM R2,0(Z)
0168 2433 CLR R3
0169 90400314 LDS R4,OSIntExitY
016B 2455 CLR R5
016C 0C44 LSL R4
016D 1C55 ROL R5
016E 0C44 LSL R4
016F 1C55 ROL R5
0170 0C44 LSL R4
0171 1C55 ROL R5
0172 0C42 ADD R4,R2
0173 1C53 ADC R5,R3
0174 92400311 STS OSPrioHighRdy,R4
(0338) if (OSPrioHighRdy != OSPrioCur) { /* No Ctx Sw if current task is highest rdy */
0176 90200312 LDS R2,OSPrioCur
0178 1442 CP R4,R2
0179 F409 BNE 0x017B
017A C03B RJMP 0x01B6
(0339) OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
017B 2C24 MOV R2,R4
017C E082 LDI R24,2
017D 9D82 MUL R24,R2
017E 01F0 MOVW R30,R0
017F EE8E LDI R24,0xEE
0180 E091 LDI R25,1
0181 0FE8 ADD R30,R24
0182 1FF9 ADC R31,R25
0183 8020 LDD R2,Z+0
0184 8031 LDD R3,Z+1
0185 92300203 STS OSTCBHighRdy+1,R3
0187 92200202 STS OSTCBHighRdy,R2
(0340) #if OS_TASK_PROFILE_EN > 0
(0341) OSTCBHighRdy->OSTCBCtxSwCtr++; /* Inc. # of context switches to this task */
0189 01C1 MOVW R24,R2
018A 9640 ADIW R24,0x10
018B E041 LDI R20,1
018C E050 LDI R21,0
018D E060 LDI R22,0
018E E070 LDI R23,0
018F 01FC MOVW R30,R24
0190 8040 LDD R4,Z+0
0191 8051 LDD R5,Z+1
0192 8062 LDD R6,Z+2
0193 8073 LDD R7,Z+3
0194 0E44 ADD R4,R20
0195 1E55 ADC R5,R21
0196 1E66 ADC R6,R22
0197 1E77 ADC R7,R23
0198 8240 STD Z+0,R4
0199 8251 STD Z+1,R5
019A 8262 STD Z+2,R6
019B 8273 STD Z+3,R7
(0342) #endif
(0343) OSCtxSwCtr++; /* Keep track of the number of ctx switches */
019C E041 LDI R20,1
019D E050 LDI R21,0
019E E060 LDI R22,0
019F E070 LDI R23,0
01A0 90400342 LDS R4,OSCtxSwCtr+2
01A2 90500343 LDS R5,OSCtxSwCtr+3
01A4 90200340 LDS R2,OSCtxSwCtr
01A6 90300341 LDS R3,OSCtxSwCtr+1
01A8 0E24 ADD R2,R20
01A9 1E35 ADC R3,R21
01AA 1E46 ADC R4,R22
01AB 1E57 ADC R5,R23
01AC 92300341 STS OSCtxSwCtr+1,R3
01AE 92200340 STS OSCtxSwCtr,R2
01B0 92500343 STS OSCtxSwCtr+3,R5
01B2 92400342 STS OSCtxSwCtr+2,R4
(0344) OSIntCtxSw(); /* Perform interrupt level ctx switch */
01B4 940E0A98 CALL _OSIntCtxSw
(0345) }
(0346) }
(0347) }
(0348) OS_EXIT_CRITICAL();
01B6 2D0A MOV R16,R10
01B7 940E09FF CALL _OS_CPU_SR_Restore
(0349) }
01B9 940E0E07 CALL pop_gset3
01BB 9508 RET
_OSSchedLock:
cpu_sr --> R20
01BC 940E0E18 CALL push_gset1
(0350) }
(0351) /*$PAGE*/
(0352) /*
(0353) *********************************************************************************************************
(0354) * PREVENT SCHEDULING
(0355) *
(0356) * Description: This function is used to prevent rescheduling to take place. This allows your application
(0357) * to prevent context switches until you are ready to permit context switching.
(0358) *
(0359) * Arguments : none
(0360) *
(0361) * Returns : none
(0362) *
(0363) * Notes : 1) You MUST invoke OSSchedLock() and OSSchedUnlock() in pair. In other words, for every
(0364) * call to OSSchedLock() you MUST have a call to OSSchedUnlock().
(0365) *********************************************************************************************************
(0366) */
(0367)
(0368) #if OS_SCHED_LOCK_EN > 0
(0369) void OSSchedLock (void)
(0370) {
(0371) #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
(0372) OS_CPU_SR cpu_sr;
(0373) #endif
(0374)
(0375)
(0376) if (OSRunning == TRUE) { /* Make sure multitasking is running */
01BE 9180030D LDS R24,OSRunning
01C0 3081 CPI R24,1
01C1 F469 BNE 0x01CF
(0377) OS_ENTER_CRITICAL();
01C2 940E09FC CALL _OS_CPU_SR_Save
01C4 2F40 MOV R20,R16
(0378) if (OSLockNesting < 255u) { /* Prevent OSLockNesting from wrapping back to 0 */
01C5 91800313 LDS R24,OSLockNesting
01C7 3F8F CPI R24,0xFF
01C8 F418 BCC 0x01CC
(0379) OSLockNesting++; /* Increment lock nesting level */
01C9 5F8F SUBI R24,0xFF
01CA 93800313 STS OSLockNesting,R24
(0380) }
(0381) OS_EXIT_CRITICAL();
01CC 2F04 MOV R16,R20
01CD 940E09FF CALL _OS_CPU_SR_Restore
(0382) }
01CF 940E0E1B CALL pop_gset1
01D1 9508 RET
_OSSchedUnlock:
cpu_sr --> R20
01D2 940E0E18 CALL push_gset1
(0383) }
(0384) #endif
(0385)
(0386) /*$PAGE*/
(0387) /*
(0388) *********************************************************************************************************
(0389) * ENABLE SCHEDULING
(0390) *
(0391) * Description: This function is used to re-allow rescheduling.
(0392) *
(0393) * Arguments : none
(0394) *
(0395) * Returns : none
(0396) *
(0397) * Notes : 1) You MUST invoke OSSchedLock() and OSSchedUnlock() in pair. In other words, for every
(0398) * call to OSSchedLock() you MUST have a call to OSSchedUnlock().
(0399) *********************************************************************************************************
(0400) */
(0401)
(0402) #if OS_SCHED_LOCK_EN > 0
(0403) void OSSchedUnlock (void)
(0404) {
(0405) #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
(0406) OS_CPU_SR cpu_sr;
(0407) #endif
(0408)
(0409)
(0410) if (OSRunning == TRUE) { /* Make sure multitasking is running */
01D4 9180030D LDS R24,OSRunning
01D6 3081 CPI R24,1
01D7 F509 BNE 0x01F9
(0411) OS_ENTER_CRITICAL();
01D8 940E09FC CALL _OS_CPU_SR_Save
01DA 2F40 MOV R20,R16
(0412) if (OSLockNesting > 0) { /* Do not decrement if already 0 */
01DB 2422 CLR R2
01DC 90300313 LDS R3,OSLockNesting
01DE 1423 CP R2,R3
01DF F4B0 BCC 0x01F6
(0413) OSLockNesting--; /* Decrement lock nesting level */
01E0 2D83 MOV R24,R3
01E1 5081 SUBI R24,1
01E2 93800313 STS OSLockNesting,R24
(0414) if (OSLockNesting == 0) { /* See if scheduler is enabled and ... */
01E4 2388 TST R24
01E5 F461 BNE 0x01F2
(0415) if (OSIntNesting == 0) { /* ... not in an ISR */
01E6 90200315 LDS R2,OSIntNesting
01E8 2022 TST R2
01E9 F421 BNE 0x01EE
(0416) OS_EXIT_CRITICAL();
01EA 940E09FF CALL _OS_CPU_SR_Restore
(0417) OS_Sched(); /* See if a HPT is ready */
01EC D291 RCALL _OS_Sched
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?