📄 test.lst
字号:
0329 9508 RET
(0266) #endif
(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:
032A 91800201 LDS R24,OSRunning
032C 3081 CPI R24,1
032D F439 BNE 0x0335
(0297) if (OSIntNesting < 255u) {
032E 91800208 LDS R24,OSIntNesting
0330 3F8F CPI R24,0xFF
0331 F418 BCC 0x0335
(0298) OSIntNesting++; /* Increment ISR nesting level */
0332 5F8F SUBI R24,0xFF
0333 93800208 STS OSIntNesting,R24
(0299) }
(0300) }
0335 9508 RET
_OSIntExit:
cpu_sr --> R10
0336 940E12E6 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) {
0338 91800201 LDS R24,OSRunning
033A 3081 CPI R24,1
033B F009 BEQ 0x033D
033C C07D RJMP 0x03BA
(0330) OS_ENTER_CRITICAL();
033D 940E0D0D CALL _OS_CPU_SR_Save
033F 2EA0 MOV R10,R16
(0331) if (OSIntNesting > 0) { /* Prevent OSIntNesting from wrapping */
0340 2422 CLR R2
0341 90300208 LDS R3,OSIntNesting
0343 1423 CP R2,R3
0344 F420 BCC 0x0349
(0332) OSIntNesting--;
0345 2D83 MOV R24,R3
0346 5081 SUBI R24,1
0347 93800208 STS OSIntNesting,R24
(0333) }
(0334) if (OSIntNesting == 0) { /* Reschedule only if all ISRs complete ... */
0349 90200208 LDS R2,OSIntNesting
034B 2022 TST R2
034C F009 BEQ 0x034E
034D C069 RJMP 0x03B7
(0335) if (OSLockNesting == 0) { /* ... and not locked. */
034E 90200206 LDS R2,OSLockNesting
0350 2022 TST R2
0351 F009 BEQ 0x0353
0352 C064 RJMP 0x03B7
(0336) OSIntExitY = OSUnMapTbl[OSRdyGrp];
0353 E688 LDI R24,0x68
0354 E090 LDI R25,0
0355 91E00203 LDS R30,OSRdyGrp
0357 27FF CLR R31
0358 0FE8 ADD R30,R24
0359 1FF9 ADC R31,R25
035A 91E4 LPM R30,0(Z)
035B 93E00207 STS OSIntExitY,R30
(0337) OSPrioHighRdy = (INT8U)((OSIntExitY << 3) + OSUnMapTbl[OSRdyTbl[OSIntExitY]]);
035D E082 LDI R24,2
035E E092 LDI R25,2
035F 27FF CLR R31
0360 0FE8 ADD R30,R24
0361 1FF9 ADC R31,R25
0362 81E0 LDD R30,Z+0
0363 27FF CLR R31
0364 E688 LDI R24,0x68
0365 E090 LDI R25,0
0366 0FE8 ADD R30,R24
0367 1FF9 ADC R31,R25
0368 9024 LPM R2,0(Z)
0369 2433 CLR R3
036A 90400207 LDS R4,OSIntExitY
036C 2455 CLR R5
036D 0C44 LSL R4
036E 1C55 ROL R5
036F 0C44 LSL R4
0370 1C55 ROL R5
0371 0C44 LSL R4
0372 1C55 ROL R5
0373 0C42 ADD R4,R2
0374 1C53 ADC R5,R3
0375 92400204 STS OSPrioHighRdy,R4
(0338) if (OSPrioHighRdy != OSPrioCur) { /* No Ctx Sw if current task is highest rdy */
0377 90200205 LDS R2,OSPrioCur
0379 1442 CP R4,R2
037A F409 BNE 0x037C
037B C03B RJMP 0x03B7
(0339) OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
037C 2C24 MOV R2,R4
037D E082 LDI R24,2
037E 9D82 MUL R24,R2
037F 01F0 MOVW R30,R0
0380 E882 LDI R24,0x82
0381 E091 LDI R25,1
0382 0FE8 ADD R30,R24
0383 1FF9 ADC R31,R25
0384 8020 LDD R2,Z+0
0385 8031 LDD R3,Z+1
0386 92300193 STS OSTCBHighRdy+1,R3
0388 92200192 STS OSTCBHighRdy,R2
(0340) #if OS_TASK_PROFILE_EN > 0
(0341) OSTCBHighRdy->OSTCBCtxSwCtr++; /* Inc. # of context switches to this task */
038A 01C1 MOVW R24,R2
038B 9640 ADIW R24,0x10
038C E041 LDI R20,1
038D E050 LDI R21,0
038E E060 LDI R22,0
038F E070 LDI R23,0
0390 01FC MOVW R30,R24
0391 8040 LDD R4,Z+0
0392 8051 LDD R5,Z+1
0393 8062 LDD R6,Z+2
0394 8073 LDD R7,Z+3
0395 0E44 ADD R4,R20
0396 1E55 ADC R5,R21
0397 1E66 ADC R6,R22
0398 1E77 ADC R7,R23
0399 8240 STD Z+0,R4
039A 8251 STD Z+1,R5
039B 8262 STD Z+2,R6
039C 8273 STD Z+3,R7
(0342) #endif
(0343) OSCtxSwCtr++; /* Keep track of the number of ctx switches */
039D E041 LDI R20,1
039E E050 LDI R21,0
039F E060 LDI R22,0
03A0 E070 LDI R23,0
03A1 90400282 LDS R4,OSCtxSwCtr+2
03A3 90500283 LDS R5,OSCtxSwCtr+3
03A5 90200280 LDS R2,OSCtxSwCtr
03A7 90300281 LDS R3,OSCtxSwCtr+1
03A9 0E24 ADD R2,R20
03AA 1E35 ADC R3,R21
03AB 1E46 ADC R4,R22
03AC 1E57 ADC R5,R23
03AD 92300281 STS OSCtxSwCtr+1,R3
03AF 92200280 STS OSCtxSwCtr,R2
03B1 92500283 STS OSCtxSwCtr+3,R5
03B3 92400282 STS OSCtxSwCtr+2,R4
(0344) OSIntCtxSw(); /* Perform interrupt level ctx switch */
03B5 940E0DA3 CALL _OSIntCtxSw
(0345) }
(0346) }
(0347) }
(0348) OS_EXIT_CRITICAL();
03B7 2D0A MOV R16,R10
03B8 940E0D10 CALL _OS_CPU_SR_Restore
(0349) }
03BA 940E12D9 CALL pop_gset3
03BC 9508 RET
_OSSchedLock:
cpu_sr --> R20
03BD 940E12EA 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 */
03BF 91800201 LDS R24,OSRunning
03C1 3081 CPI R24,1
03C2 F469 BNE 0x03D0
(0377) OS_ENTER_CRITICAL();
03C3 940E0D0D CALL _OS_CPU_SR_Save
03C5 2F40 MOV R20,R16
(0378) if (OSLockNesting < 255u) { /* Prevent OSLockNesting from wrapping back to 0 */
03C6 91800206 LDS R24,OSLockNesting
03C8 3F8F CPI R24,0xFF
03C9 F418 BCC 0x03CD
(0379) OSLockNesting++; /* Increment lock nesting level */
03CA 5F8F SUBI R24,0xFF
03CB 93800206 STS OSLockNesting,R24
(0380) }
(0381) OS_EXIT_CRITICAL();
03CD 2F04 MOV R16,R20
03CE 940E0D10 CALL _OS_CPU_SR_Restore
(0382) }
03D0 940E12ED CALL pop_gset1
03D2 9508 RET
_OSSchedUnlock:
cpu_sr --> R20
03D3 940E12EA 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 */
03D5 91800201 LDS R24,OSRunning
03D7 3081 CPI R24,1
03D8 F509 BNE 0x03FA
(0411) OS_ENTER_CRITICAL();
03D9 940E0D0D CALL _OS_CPU_SR_Save
03DB 2F40 MOV R20,R16
(0412) if (OSLockNesting > 0) { /* Do not decrement if already 0 */
03DC 2422 CLR R2
03DD 90300206 LDS R3,OSLockNesting
03DF 1423 CP R2,R3
03E0 F4B0 BCC 0x03F7
(0413) OSLockNesting--; /* Decrement lock nesting level */
03E1 2D83 MOV R24,R3
03E2 5081 SUBI R24,1
03E3 93800206 STS OSLockNesting,R24
(0414) if (OSLockNesting == 0) { /* See if scheduler is enabled and ... */
03E5 2388 TST R24
03E6 F461 BNE 0x03F3
(0415) if (OSIntNesting == 0) { /* ... not in an ISR */
03E7 90200208 LDS R2,OSIntNesting
03E9 2022 TST R2
03EA F421 BNE 0x03EF
(0416) OS_EXIT_CRITICAL();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -