📄 test.lst
字号:
(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:
FD 9180 0B3D LDS R24,OSRunning
FF 3081 CPI R24,1
100 F439 BNE 0x0108
(0297) if (OSIntNesting < 255u) {
101 9180 0B4B LDS R24,OSIntNesting
103 3F8F CPI R24,0xFF
104 F418 BCC 0x0108
(0298) OSIntNesting++; /* Increment ISR nesting level */
105 5F8F SUBI R24,0xFF
106 9380 0B4B STS OSIntNesting,R24
(0299) }
(0300) }
108 9508 RET
_OSIntExit:
cpu_sr --> R10
109 940E 0F98 CALL push_xgset300C
(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) {
10B 9180 0B3D LDS R24,OSRunning
10D 3081 CPI R24,1
10E F009 BEQ 0x0110
10F C07F RJMP 0x018F
(0330) OS_ENTER_CRITICAL();
110 940E 0BB7 CALL _OS_CPU_SR_Save
112 2EA0 MOV R10,R16
(0331) if (OSIntNesting > 0) { /* Prevent OSIntNesting from wrapping */
113 E080 LDI R24,0
114 9020 0B4B LDS R2,OSIntNesting
116 1582 CP R24,R2
117 F420 BCC 0x011C
(0332) OSIntNesting--;
118 2D82 MOV R24,R2
119 5081 SUBI R24,1
11A 9380 0B4B STS OSIntNesting,R24
(0333) }
(0334) if (OSIntNesting == 0) { /* Reschedule only if all ISRs complete ... */
11C 9020 0B4B LDS R2,OSIntNesting
11E 2022 TST R2
11F F009 BEQ 0x0121
120 C06B RJMP 0x018C
(0335) if (OSLockNesting == 0) { /* ... and not locked. */
121 9020 0B49 LDS R2,OSLockNesting
123 2022 TST R2
124 F009 BEQ 0x0126
125 C066 RJMP 0x018C
(0336) OSIntExitY = OSUnMapTbl[OSRdyGrp];
126 E98C LDI R24,0x9C
127 E090 LDI R25,0
128 91E0 0B46 LDS R30,OSRdyGrp
12A 27FF CLR R31
12B 0FE8 ADD R30,R24
12C 1FF9 ADC R31,R25
12D 9026 ELPM R2,2886(Z)
12E 9220 0B4A STS OSIntExitY,R2
(0337) OSPrioHighRdy = (INT8U)((OSIntExitY << 3) + OSUnMapTbl[OSRdyTbl[OSIntExitY]]);
130 2C42 MOV R4,R2
131 E38E LDI R24,0x3E
132 E09B LDI R25,0xB
133 2DE2 MOV R30,R2
134 27FF CLR R31
135 0FE8 ADD R30,R24
136 1FF9 ADC R31,R25
137 81E0 LDD R30,Z+0
138 27FF CLR R31
139 E98C LDI R24,0x9C
13A E090 LDI R25,0
13B 0FE8 ADD R30,R24
13C 1FF9 ADC R31,R25
13D 9026 ELPM R2,0(Z)
13E 2433 CLR R3
13F 2455 CLR R5
140 0C44 LSL R4
141 1C55 ROL R5
142 0C44 LSL R4
143 1C55 ROL R5
144 0C44 LSL R4
145 1C55 ROL R5
146 0C42 ADD R4,R2
147 1C53 ADC R5,R3
148 9240 0B47 STS OSPrioHighRdy,R4
(0338) if (OSPrioHighRdy != OSPrioCur) { /* No Ctx Sw if current task is highest rdy */
14A 9020 0B48 LDS R2,OSPrioCur
14C 2C34 MOV R3,R4
14D 1442 CP R4,R2
14E F409 BNE 0x0150
14F C03C RJMP 0x018C
(0339) OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
150 EB80 LDI R24,0xB0
151 E099 LDI R25,0x9
152 2DE4 MOV R30,R4
153 27FF CLR R31
154 0FEE LSL R30
155 1FFF ROL R31
156 0FE8 ADD R30,R24
157 1FF9 ADC R31,R25
158 8020 LDD R2,Z+0
159 8031 LDD R3,Z+1
15A 9230 0A33 STS OSTCBHighRdy+1,R3
15C 9220 0A32 STS OSTCBHighRdy,R2
(0340) #if OS_TASK_PROFILE_EN > 0
(0341) OSTCBHighRdy->OSTCBCtxSwCtr++; /* Inc. # of context switches to this task */
15E 01A1 MOVW R20,R2
15F 5F40 SUBI R20,0xF0
160 4F5F SBCI R21,0xFF
161 E081 LDI R24,1
162 E090 LDI R25,0
163 E0A0 LDI R26,0
164 E0B0 LDI R27,0
165 01FA MOVW R30,R20
166 8020 LDD R2,Z+0
167 8031 LDD R3,Z+1
168 8042 LDD R4,Z+2
169 8053 LDD R5,Z+3
16A 0E28 ADD R2,R24
16B 1E39 ADC R3,R25
16C 1E4A ADC R4,R26
16D 1E5B ADC R5,R27
16E 8220 STD Z+0,R2
16F 8231 STD Z+1,R3
170 8242 STD Z+2,R4
171 8253 STD Z+3,R5
(0342) #endif
(0343) OSCtxSwCtr++; /* Keep track of the number of ctx switches */
172 E081 LDI R24,1
173 E090 LDI R25,0
174 E0A0 LDI R26,0
175 E0B0 LDI R27,0
176 9040 0B96 LDS R4,OSCtxSwCtr+2
178 9050 0B97 LDS R5,OSCtxSwCtr+3
17A 9020 0B94 LDS R2,OSCtxSwCtr
17C 9030 0B95 LDS R3,OSCtxSwCtr+1
17E 0E28 ADD R2,R24
17F 1E39 ADC R3,R25
180 1E4A ADC R4,R26
181 1E5B ADC R5,R27
182 9230 0B95 STS OSCtxSwCtr+1,R3
184 9220 0B94 STS OSCtxSwCtr,R2
186 9250 0B97 STS OSCtxSwCtr+3,R5
188 9240 0B96 STS OSCtxSwCtr+2,R4
(0344) OSIntCtxSw(); /* Perform interrupt level ctx switch */
18A 940E 0C53 CALL _OSIntCtxSw
(0345) }
(0346) }
(0347) }
(0348) OS_EXIT_CRITICAL();
18C 2D0A MOV R16,R10
18D 940E 0BBA CALL _OS_CPU_SR_Restore
(0349) }
18F 940C 0F9D JMP pop_xgset300C
_OSSchedLock:
cpu_sr --> R10
191 92AA ST R10,-Y
(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 */
192 9180 0B3D LDS R24,OSRunning
194 3081 CPI R24,1
195 F469 BNE 0x01A3
(0377) OS_ENTER_CRITICAL();
196 940E 0BB7 CALL _OS_CPU_SR_Save
198 2EA0 MOV R10,R16
(0378) if (OSLockNesting < 255u) { /* Prevent OSLockNesting from wrapping back to 0 */
199 9180 0B49 LDS R24,OSLockNesting
19B 3F8F CPI R24,0xFF
19C F418 BCC 0x01A0
(0379) OSLockNesting++; /* Increment lock nesting level */
19D 5F8F SUBI R24,0xFF
19E 9380 0B49 STS OSLockNesting,R24
(0380) }
(0381) OS_EXIT_CRITICAL();
1A0 2D0A MOV R16,R10
1A1 940E 0BBA CALL _OS_CPU_SR_Restore
(0382) }
1A3 90A9 LD R10,Y+
1A4 9508 RET
_OSSchedUnlock:
cpu_sr --> R10
1A5 92AA ST R10,-Y
(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 */
1A6 9180 0B3D LDS R24,OSRunning
1A8 3081 CPI R24,1
1A9 F509 BNE 0x01CB
(0411) OS_ENTER_CRITICAL();
1AA 940E 0BB7 CALL _OS_CPU_SR_Save
1AC 2EA0 MOV R10,R16
(0412) if (OSLockNesting > 0) { /* Do not decrement if already 0 */
1AD E080 LDI R24,0
1AE 9020 0B49 LDS R2,OSLockNesting
1B0 1582 CP R24,R2
1B1 F4B0 BCC 0x01C8
(0413) OSLockNesting--; /* Decrement lock nesting level */
1B2 2D82 MOV R24,R2
1B3 5081 SUBI R24,1
1B4 9380 0B49 STS OSLockNesting,R24
(0414) if (OSLockNesting == 0) { /* See if scheduler is enabled and ... */
1B6 2388 TST R24
1B7 F461 BNE 0x01C4
(0415) if (OSIntNesting == 0) { /* ... not in an ISR */
1B8 9020 0B4B LDS R2,OSIntNesting
1BA 2022 TST R2
1BB F421 BNE 0x01C0
(0416) OS_EXIT_CRITICAL();
1BC 940E 0BBA CALL _OS_CPU_SR_Restore
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -