📄 os-task-sem.lst
字号:
(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:
020F 90200209 LDS R2,_OSRunning
0211 2022 TST R2
0212 F499 BNE 0x0226
(0179) OSPrioHighRdy = 0;
0213 2422 CLR R2
0214 922001FF STS R2,_OSPrioHighRdy
(0180) OSPrioCur = 0;
0216 92200200 STS R2,_OSPrioCur
(0181) OSTCBHighRdy = OSpTCBList[OSPrioHighRdy]; /* Point to highest priority task ready to run */
0218 E083 LDI R24,3
0219 E092 LDI R25,2
021A 2DE2 MOV R30,R2
021B D3EC RCALL 0x0608
021C D3FE RCALL 0x061B
021D D457 RCALL 0x0675
(0182) OSTCBCur = OSTCBHighRdy;
(0183) #if OS_STRICT
(0184) if(0==OSTCBCur)
021E 2022 TST R2
021F F421 BNE 0x0224
0220 2033 TST R3
0221 F411 BNE 0x0224
(0185) OSError(0);
0222 2700 CLR R16
0223 D26D RCALL _OSError
(0186) #endif
(0187) OSStartHighRdy(); /* Execute target specific code to start task */
0224 DE0B RCALL _OSStartHighRdy
(0188) }
0225 C002 RJMP 0x0228
(0189) #if OS_STRICT
(0190) else OSError(0);
0226 2700 CLR R16
0227 D269 RCALL _OSError
(0191) #endif
(0192) }
0228 9508 RET
_OSTimeDly:
ticks --> R20
0229 D363 RCALL push_gset1
022A D401 RCALL 0x062C
(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! */
022B F069 BEQ 0x0239
(0213) OS_ENTER_CRITICAL();
022C 930A ST R16,-Y
022D B70F IN R16,P3F
022E 94F8 BCLR 7
022F 930F PUSH R16
0230 9109 LD R16,Y+
0231 D3DC RCALL 0x060E
(0214) OSTCBCur->OSTCBDly = ticks; /* Load ticks in TCB */
0232 8342 STD R20,2+Z
0233 8353 STD R21,3+Z
(0215) OS_EXIT_CRITICAL();
0234 930A ST R16,-Y
0235 910F POP R16
0236 BF0F OUT P3F,R16
0237 9109 LD R16,Y+
(0216) OSSched(); /* Find next task to run! */
0238 DFAF RCALL _OSSched
(0217) }
(0218) }
0239 D356 RCALL pop_gset1
023A 9508 RET
_OSGetPrioRdy:
ret --> R20
ptcb --> R10
i --> R22
023B D36B RCALL push_gset3
(0219) /*return tcb's prio which OSTCBDly==0*/
(0220) INT8U OSGetPrioRdy(void)
(0221) {
(0222) INT8U i,ret=0xff;
023C EF4F LDI R20,0xFF
(0223) OS_TCB *ptcb;
(0224) for(i=0;i<OS_TASK_COUNT;i++)
023D 2766 CLR R22
023E C034 RJMP 0x0273
(0225) {
(0226) ptcb=OSpTCBList[i];
023F E083 LDI R24,3
0240 E092 LDI R25,2
0241 2FE6 MOV R30,R22
0242 D3C5 RCALL 0x0608
0243 80A0 LDD R10,0+Z
0244 80B1 LDD R11,1+Z
(0227) //OS_ENTER_CRITICAL();
(0228) if(ptcb)
0245 20AA TST R10
0246 F419 BNE 0x024A
0247 20BB TST R11
0248 F409 BNE 0x024A
0249 C028 RJMP 0x0272
(0229) {
(0230) if(0==ptcb->OSTCBDly)
024A 2DEA MOV R30,R10
024B 2DFB MOV R31,R11
024C 8022 LDD R2,2+Z
024D 8033 LDD R3,3+Z
024E 2022 TST R2
024F F009 BEQ 0x0251
0250 C021 RJMP 0x0272
0251 2033 TST R3
0252 F009 BEQ 0x0254
0253 C01E RJMP 0x0272
(0231) {
(0232) if(OS_STAT_RDY==ptcb->OSTCBStat)
0254 2DEA MOV R30,R10
0255 2DFB MOV R31,R11
0256 8184 LDD R24,4+Z
0257 3081 CPI R24,1
0258 F451 BNE 0x0263
(0233) {
(0234) #if OS_STRICT
(0235) if(i!=ptcb->OSTCBPrio)
0259 8025 LDD R2,5+Z
025A 1562 CP R22,R2
025B F011 BEQ 0x025E
(0236) OSError(0);
025C 2700 CLR R16
025D D233 RCALL _OSError
(0237) #endif
(0238) ret=ptcb->OSTCBPrio;
025E D401 RCALL 0x0660
(0239) #if OS_STRICT
(0240) if(ret>OS_LOWEST_PRIO)
025F F4B0 BCC 0x0276
(0241) OSError(0);
0260 2700 CLR R16
0261 D22F RCALL _OSError
(0242) #endif
(0243) break;//for
0262 C013 RJMP 0x0276
(0244) }//end OS_STAT_RDY==ptcb->OSTCBStat
(0245) #if OS_SEM_EN
(0246) else{
(0247) if(ptcb->OSTCBStat & OS_STAT_SEM)
0263 2DEA MOV R30,R10
0264 2DFB MOV R31,R11
0265 8024 LDD R2,4+Z
0266 FE21 SBRS R2,1
0267 C00A RJMP 0x0272
(0248) {
(0249) #if OS_STRICT
(0250) if(i!=ptcb->OSTCBPrio)
0268 8025 LDD R2,5+Z
0269 1562 CP R22,R2
026A F011 BEQ 0x026D
(0251) OSError(0);
026B 2700 CLR R16
026C D224 RCALL _OSError
(0252) #endif
(0253) ret=ptcb->OSTCBPrio;
026D D3F2 RCALL 0x0660
(0254) #if OS_STRICT
(0255) if(ret>OS_LOWEST_PRIO)
026E F438 BCC 0x0276
(0256) OSError(0);
026F 2700 CLR R16
0270 D220 RCALL _OSError
(0257) #endif
(0258) break;//for
0271 C004 RJMP 0x0276
0272 9563 INC R22
0273 3063 CPI R22,3
0274 F408 BCC 0x0276
0275 CFC9 RJMP 0x023F
(0259) }
(0260) }//end (ptcb->OSTCBStat & OS_STAT_SEM)
(0261) #endif//OS_SEM_EN
(0262) }//end (0==ptcb->OSTCBDly)
(0263) }
(0264) //OS_EXIT_CRITICAL();
(0265) }
(0266) return ret;
0276 2F04 MOV R16,R20
0277 D337 RCALL pop_gset3
0278 9508 RET
(0267) }
(0268)
(0269) /*
(0270) *********************************************************************************************************
(0271) * PROCESS SYSTEM TICK
(0272) *
(0273) * Description: This function is used to signal to uC/OS-II the occurrence of a 'system tick' (also known
(0274) * as a 'clock tick'). This function should be called by the ticker ISR but, can also be
(0275) * called by a high priority task.
(0276) *
(0277) * Arguments : none
(0278) *
(0279) * Returns : none
(0280) *********************************************************************************************************
(0281) */
(0282)
(0283) void OSTimeTick (void)
(0284) {
(0285) INT8U i,ret;
(0286) OS_TCB *ptcb;
(0287) //skip last task,last task must be idle task
(0288) for(i=0;i<OS_TASK_COUNT-1;i++)
_OSTimeTick:
ret --> Y+1
ptcb --> R16
i --> R18
0279 2722 CLR R18
027A C01E RJMP 0x0299
(0289) {
(0290) ptcb=OSpTCBList[i];
027B E083 LDI R24,3
027C E092 LDI R25,2
027D 2FE2 MOV R30,R18
027E D389 RCALL 0x0608
027F 8100 LDD R16,0+Z
0280 8111 LDD R17,1+Z
(0291) // OS_ENTER_CRITICAL();
(0292) //check ptcb != 0
(0293) if(ptcb){ /* Go through all TCBs in TCB list */
0281 3000 CPI R16,0
0282 0701 CPC R16,R17
0283 F0A1 BEQ 0x0298
(0294) if (ptcb->OSTCBDly != 0) { /* Delayed or waiting for event with TO */
0284 2FE0 MOV R30,R16
0285 2FF1 MOV R31,R17
0286 8022 LDD R2,2+Z
0287 8033 LDD R3,3+Z
0288 2022 TST R2
0289 F411 BNE 0x028C
028A 2033 TST R3
028B F061 BEQ 0x0298
(0295) if (--ptcb->OSTCBDly == 0) { /* Decrement nbr of ticks to end of delay */
028C 2F80 MOV R24,R16
028D 2F91 MOV R25,R17
028E 9602 ADIW R24,2
028F D3A1 RCALL 0x0631
0290 9701 SBIW R24,1
0291 2E48 MOV R4,R24
0292 2E59 MOV R5,R25
0293 8240 STD R4,0+Z
0294 8251 STD R5,1+Z
0295 3080 CPI R24,0
0296 0789 CPC R24,R25
0297 F401 BNE 0x0298
0298 9523 INC R18
0299 3022 CPI R18,2
029A F300 BCS 0x027B
(0296) // if (!(ptcb->OSTCBStat & OS_STAT_SUSPEND)) { /* Is task suspended? */
(0297) // OSRdyGrp |= ptcb->OSTCBBitY; /* No, Make task Rdy to Run (timed out)*/
(0298) // OSRdyTbl[ptcb->OSTCBY] |= ptcb->OSTCBBitX;
(0299) // } else { /* Yes, Leave 1 tick to prevent ... */
(0300) // ptcb->OSTCBDly = 1; /* ... loosing the task when the ... */
(0301) // } /* ... suspension is removed. */
(0302) }//end (--ptcb->OSTCBDly==0)
(0303) }//end OSTCBDly!=0
(0304) }//end if(ptcb)
(0305) // OS_EXIT_CRITICAL();
(0306) }//end for
(0307) }
029B 9508 RET
(0308)
(0309) /*
(0310) *********************************************************************************************************
(0311) * EXIT ISR
(0312) *
(0313) * Description: This function is used to notify uC/OS-II that you have completed serviving an ISR. When
(0314) * the last nested ISR has completed, uC/OS-II will call the scheduler to determine whether
(0315) * a new, high-priority task, is ready to run.
(0316) *
(0317) * Arguments : none
(0318) *
(0319) * Returns : none
(0320) *
(0321) * Notes : 1) You MUST invoke OSIntEnter() and OSIntExit() in pair. In other words, for every call
(0322) * to OSIntEnter() at the beginning of the ISR you MUST have a call to OSIntExit() at the
(0323) * end of the ISR.
(0324) * 2) Rescheduling is prevented when the scheduler is locked (see OSSchedLock())
(0325) *********************************************************************************************************
(0326) */
(0327)
(0328) void OSIntExit(void)
(0329) {
(0330) OS_ENTER_CRITICAL();
_OSIntExit:
029C 930A ST R16,-Y
029D B70F IN R16,P3F
029E 94F8 BCLR 7
029F 930F PUSH R16
02A0 9109 LD R16,Y+
(0331) if ((--OSIntNesting | OSLockNesting) == 0) { /* Reschedule only if all ISRs completed & not locked */
02A1 91800202 LDS R24,_OSIntNesting
02A3 5081 SUBI R24,1
02A4 2E28 MOV R2,R24
02A5 92200202 STS R2,_OSIntNesting
02A7 90400201 LDS R4,_OSLockNesting
02A9 2824 OR R2,R4
02AA F009 BEQ 0x02AC
02AB C022 RJMP 0x02CE
(0332) OSPrioHighRdy=OSGetPrioRdy();
02AC DF8E RCALL _OSGetPrioRdy
02AD 930001FF STS R16,_OSPrioHighRdy
(0333) if(OSPrioHighRdy>OS_LOWEST_PRIO)
02AF E082 LDI R24,2
02B0 1780 CP R24,R16
02B1 F418 BCC 0x02B5
(0334) {
(0335) #if OS_STRICT
(0336) OSError(0);
02B2 2700 CLR R16
02B3 D1DD RCALL _OSError
(0337) #endif
(0338) }else if (OSPrioHighRdy != OSPrioCur) { /* No context switch if current task is highest ready */
02B4 C019 RJMP 0x02CE
02B5 D3A4 RCALL 0x065A
02B6 F0B9 BEQ 0x02CE
(0339) OSTCBHighRdy = OSpTCBList[OSPrioHighRdy];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -