📄 os_core.lst
字号:
187 *********************************************************************************************************
188 * INITIALIZE EVENT CONTROL BLOCK'S WAIT LIST
189 *
190 * Description: This function is called by other uC/OS-II services to initialize the event wait list.
191 *
192 * Arguments : pevent is a pointer to the event control block allocated to the event.
193 *
194 * Returns : none
195 *
196 * Note : This function is INTERNAL to uC/OS-II and your application should not call it.
197 *********************************************************************************************************
198 */
199 #if (OS_Q_EN && (OS_MAX_QS >= 2)) || OS_MBOX_EN || OS_Sem_EN
200 void OSEventWaitListInit (OS_EVENT *pevent)reentrant
201 {
202 1 INT8U i;
203 1
204 1
205 1 pevent->OSEventGrp = 0x00; /* No task waiting on event */
206 1 for (i = 0; i < OS_EVENT_TBL_SIZE; i++) {
207 2 pevent->OSEventTbl[i] = 0x00;
208 2 }
209 1 }
210 #endif
211 /*$PAGE*/
212 /*
213 *********************************************************************************************************
214 * INITIALIZATION
215 *
216 * Description: This function is used to initialize the internals of uC/OS-II and MUST be called prior to
217 * creating any uC/OS-II object and, prior to calling OSStart().
218 *
219 * Arguments : none
220 *
221 * Returns : none
222 *********************************************************************************************************
223 */
224
225 void OSInit (void)
226 {
227 1 INT16U i;
228 1
229 1
230 1 OSTime = 0L; /* Clear the 32-bit system clock */
231 1 OSIntNesting = 0; /* Clear the interrupt nesting counter */
232 1 OSLockNesting = 0; /* Clear the scheduling lock counter */
233 1
234 1 OSTaskCtr = 0; /* Clear the number of tasks */
235 1
236 1 OSRunning = FALSE; /* Indicate that multitasking not started */
237 1 OSIdleCtr = 0L; /* Clear the 32-bit idle counter */
238 1 OSCtxSwCtr = 0; /* Clear the context switch counter */
239 1 OSRdyGrp = 0; /* Clear the ready list */
240 1 for (i = 0; i < OS_RDY_TBL_SIZE; i++) {
C51 COMPILER V7.20 OS_CORE 12/29/2004 11:50:53 PAGE 5
241 2 OSRdyTbl[i] = 0;
242 2 }
243 1
244 1 OSPrioCur = 0;
245 1 OSPrioHighRdy = 0;
246 1 OSTCBHighRdy = (OS_TCB *)0; /* TCB Initialization */
247 1 OSTCBCur = (OS_TCB *)0;
248 1 OSTCBList = (OS_TCB *)0;
249 1 for (i = 0; i < (OS_LOWEST_PRIO + 1); i++) { /* Clear the priority table */
250 2 OSTCBPrioTbl[i] = (OS_TCB *)0;
251 2 }
252 1 for (i = 0; i < (OS_MAX_TASKS + OS_N_SYS_TASKS - 1); i++) { /* Init. list of free TCBs */
253 2 OSTCBTbl[i].OSTCBNext = &OSTCBTbl[i + 1];
254 2 }
255 1 OSTCBTbl[OS_MAX_TASKS + OS_N_SYS_TASKS - 1].OSTCBNext = (OS_TCB *)0; /* Last OS_TCB */
256 1 OSTCBFreeList = &OSTCBTbl[0];
257 1
258 1
259 1 for (i = 0; i < (OS_MAX_EVENTS - 1); i++) { /* Init. list of free EVENT control blocks */
260 2 OSEventTbl[i].OSEventPtr = (OS_EVENT *)&OSEventTbl[i + 1];
261 2 }
262 1 OSEventTbl[OS_MAX_EVENTS - 1].OSEventPtr = (OS_EVENT *)0;
263 1 OSEventFreeList = &OSEventTbl[0];
264 1
265 1 #if OS_STK_GROWTH == 1
266 1
267 1 OSTaskCreate(OSTaskIdle, (void *)0, &OSTaskIdleStk[OS_TASK_IDLE_STK_SIZE - 1], OS_IDLE_PRIO);
268 1
269 1 #else
OSTaskCreate(OSTaskIdle, (void *)0, &OSTaskIdleStk[0], OS_IDLE_PRIO);
#endif
273 1
274 1 }
275 /*$PAGE*/
276 /*
277 *********************************************************************************************************
278 * ENTER ISR
279 *
280 * Description: This function is used to notify uC/OS-II that you are about to service an interrupt
281 * service routine (ISR). This allows uC/OS-II to keep track of interrupt nesting and thus
282 * only perform rescheduling at the last nested ISR.
283 *
284 * Arguments : none
285 *
286 * Returns : none
287 *
288 * Notes : 1) Your ISR can directly increment OSIntNesting without calling this function because
289 * OSIntNesting has been declared 'global'. You MUST, however, be sure that the increment
290 * is performed 'indivisibly' by your processor to ensure proper access to this critical
291 * resource.
292 * 2) You MUST still call OSIntExit() even though you increment OSIntNesting directly.
293 * 3) You MUST invoke OSIntEnter() and OSIntExit() in pair. In other words, for every call
294 * to OSIntEnter() at the beginning of the ISR you MUST have a call to OSIntExit() at the
295 * end of the ISR.
296 *********************************************************************************************************
297 */
298
299 void OSIntEnter (void)
300 {
301 1 OS_ENTER_CRITICAL();
302 1 OSIntNesting++; /* Increment ISR nesting level */
C51 COMPILER V7.20 OS_CORE 12/29/2004 11:50:53 PAGE 6
303 1 OS_EXIT_CRITICAL();
304 1 }
305 /*$PAGE*/
306 /*
307 *********************************************************************************************************
308 * EXIT ISR
309 *
310 * Description: This function is used to notify uC/OS-II that you have completed serviving an ISR. When
311 * the last nested ISR has completed, uC/OS-II will call the scheduler to determine whether
312 * a new, high-priority task, is ready to run.
313 *
314 * Arguments : none
315 *
316 * Returns : none
317 *
318 * Notes : 1) You MUST invoke OSIntEnter() and OSIntExit() in pair. In other words, for every call
319 * to OSIntEnter() at the beginning of the ISR you MUST have a call to OSIntExit() at the
320 * end of the ISR.
321 * 2) Rescheduling is prevented when the scheduler is locked (see OSSchedLock())
322 *********************************************************************************************************
323 */
324
325 void OSIntExit (void)
326 {
327 1 OS_ENTER_CRITICAL();
328 1 if ((--OSIntNesting | OSLockNesting) == 0) { /* Reschedule only if all ISRs completed & not locked */
329 2 OSIntExitY = OSUnMapTbl[OSRdyGrp];
330 2 OSPrioHighRdy = (INT8U)((OSIntExitY << 3) + OSUnMapTbl[OSRdyTbl[OSIntExitY]]);
331 2 if (OSPrioHighRdy != OSPrioCur) { /* No context switch if current task is highest ready */
332 3 OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
333 3 OSCtxSwCtr++; /* Keep track of the number of context switches */
334 3 OSIntCtxSw(); /* Perform interrupt level context switch */
335 3 }
336 2 }
337 1 OS_EXIT_CRITICAL();
338 1 }
339 /*$PAGE*/
340 /*
341 *********************************************************************************************************
342 * SCHEDULER
343 *
344 * Description: This function is called by other uC/OS-II services to determine whether a new, high
345 * priority task has been made ready to run. This function is invoked by TASK level code
346 * and is not used to reschedule tasks from ISRs (see OSIntExit() for ISR rescheduling).
347 *
348 * Arguments : none
349 *
350 * Returns : none
351 *
352 * Notes : 1) This function is INTERNAL to uC/OS-II and your application should not call it.
353 * 2) Rescheduling is prevented when the scheduler is locked (see OSSchedLock())
354 *********************************************************************************************************
355 */
356
357 void OSSched (void)reentrant
358 {
359 1 INT8U y;
360 1
361 1
362 1 OS_ENTER_CRITICAL();
363 1 if ((OSLockNesting | OSIntNesting) == 0) { /* Task scheduling must be enabled and not ISR level */
364 2 y = OSUnMapTbl[OSRdyGrp]; /* Get pointer to highest priority task ready to run */
C51 COMPILER V7.20 OS_CORE 12/29/2004 11:50:53 PAGE 7
365 2 OSPrioHighRdy = (INT8U)((y << 3) + OSUnMapTbl[OSRdyTbl[y]]);
366 2 if (OSPrioHighRdy != OSPrioCur) { /* No context switch if current task is highest ready */
367 3 OSTCBHighRdy = OSTCBPrioTbl[OSPrioHighRdy];
368 3 OSCtxSwCtr++; /* Increment context switch counter */
369 3 OSCtxSw(); /* Perform a context switch */
370 3 }
371 2 }
372 1 OS_EXIT_CRITICAL();
373 1 }
374 /*$PAGE*/
375 /*
376 *********************************************************************************************************
377 * PREVENT SCHEDULING
378 *
379 * Description: This function is used to prevent rescheduling to take place. This allows your application
380 * to prevent context switches until you are ready to permit context switching.
381 *
382 * Arguments : none
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -