📄 os_q.lst
字号:
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
BOOLEAN tasks_waiting;
OS_Q *pq;
if (OSIntNesting > 0) { /* See if called from ISR ... */
*err = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */
return ((OS_EVENT *)0);
}
#if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
*err = OS_ERR_PEVENT_NULL;
return (pevent);
}
if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
*err = OS_ERR_EVENT_TYPE;
return (pevent);
}
#endif
OS_ENTER_CRITICAL();
if (pevent->OSEventGrp != 0x00) { /* See if any tasks waiting on queue */
tasks_waiting = TRUE; /* Yes */
} else {
tasks_waiting = FALSE; /* No */
}
switch (opt) {
case OS_DEL_NO_PEND: /* Delete queue only if no task waiting */
if (tasks_waiting == FALSE) {
pq = pevent->OSEventPtr; /* Return OS_Q to free list */
pq->OSQPtr = OSQFreeList;
OSQFreeList = pq;
pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
OSEventFreeList = pevent; /* Get next free event control block */
OS_EXIT_CRITICAL();
*err = OS_NO_ERR;
return ((OS_EVENT *)0); /* Queue has been deleted */
} else {
OS_EXIT_CRITICAL();
*err = OS_ERR_TASK_WAITING;
return (pevent);
}
case OS_DEL_ALWAYS: /* Always delete the queue */
while (pevent->OSEventGrp != 0x00) { /* Ready ALL tasks waiting for queue */
OS_EventTaskRdy(pevent, (void *)0, OS_STAT_Q);
}
pq = pevent->OSEventPtr; /* Return OS_Q to free list */
pq->OSQPtr = OSQFreeList;
OSQFreeList = pq;
pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
OSEventFreeList = pevent; /* Get next free event control block */
OS_EXIT_CRITICAL();
if (tasks_waiting == TRUE) { /* Reschedule only if task(s) were waiting */
OS_Sched(); /* Find highest priority task ready to run */
}
*err = OS_NO_ERR;
C51 COMPILER V7.06 OS_Q 03/05/2008 20:23:54 PAGE 5
return ((OS_EVENT *)0); /* Queue has been deleted */
default:
OS_EXIT_CRITICAL();
*err = OS_ERR_INVALID_OPT;
return (pevent);
}
}
#endif
250
251 /*$PAGE*/
252 /*
253 *********************************************************************************************************
254 * FLUSH QUEUE
255 *
256 * Description : This function is used to flush the contents of the message queue.
257 *
258 * Arguments : none
259 *
260 * Returns : OS_NO_ERR upon success
261 * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue
262 * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
263 *********************************************************************************************************
264 */
265
266 #if OS_Q_FLUSH_EN > 0
INT8U OSQFlush (OS_EVENT *pevent) reentrant
{
#if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
OS_Q *pq;
#if OS_ARG_CHK_EN > 0
if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
return (OS_ERR_PEVENT_NULL);
}
if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
return (OS_ERR_EVENT_TYPE);
}
#endif
OS_ENTER_CRITICAL();
pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue storage structure */
pq->OSQIn = pq->OSQStart;
pq->OSQOut = pq->OSQStart;
pq->OSQEntries = 0;
OS_EXIT_CRITICAL();
return (OS_NO_ERR);
}
#endif
292
293 /*$PAGE*/
294 /*
295 *********************************************************************************************************
296 * PEND ON A QUEUE FOR A MESSAGE
297 *
298 * Description: This function waits for a message to be sent to a queue
299 *
300 * Arguments : pevent is a pointer to the event control block associated with the desired queue
301 *
302 * timeout is an optional timeout period (in clock ticks). If non-zero, your task will
C51 COMPILER V7.06 OS_Q 03/05/2008 20:23:54 PAGE 6
303 * wait for a message to arrive at the queue up to the amount of time
304 * specified by this argument. If you specify 0, however, your task will wait
305 * forever at the specified queue or, until a message arrives.
306 *
307 * err is a pointer to where an error message will be deposited. Possible error
308 * messages are:
309 *
310 * OS_NO_ERR The call was successful and your task received a
311 * message.
312 * OS_TIMEOUT A message was not received within the specified timeout
313 * OS_ERR_EVENT_TYPE You didn't pass a pointer to a queue
314 * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
315 * OS_ERR_PEND_ISR If you called this function from an ISR and the result
316 * would lead to a suspension.
317 *
318 * Returns : != (void *)0 is a pointer to the message received
319 * == (void *)0 if no message was received or,
320 * if 'pevent' is a NULL pointer or,
321 * if you didn't pass a pointer to a queue.
322 *********************************************************************************************************
323 */
324
325 void *OSQPend (OS_EVENT *pevent, INT16U timeout, INT8U *err) reentrant
326 {
327 1 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
330 1 void *msg;
331 1 OS_Q *pq;
332 1
333 1
334 1 if (OSIntNesting > 0) { /* See if called from ISR ... */
335 2 *err = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */
336 2 return ((void *)0);
337 2 }
338 1 #if OS_ARG_CHK_EN > 0
339 1 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
340 2 *err = OS_ERR_PEVENT_NULL;
341 2 return ((void *)0);
342 2 }
343 1 if (pevent->OSEventType != OS_EVENT_TYPE_Q) {/* Validate event block type */
344 2 *err = OS_ERR_EVENT_TYPE;
345 2 return ((void *)0);
346 2 }
347 1 #endif
348 1 OS_ENTER_CRITICAL();
349 1 pq = (OS_Q *)pevent->OSEventPtr; /* Point at queue control block */
350 1 if (pq->OSQEntries != 0) { /* See if any messages in the queue */
351 2 msg = *pq->OSQOut++; /* Yes, extract oldest message from the queue */
352 2 pq->OSQEntries--; /* Update the number of entries in the queue */
353 2 if (pq->OSQOut == pq->OSQEnd) { /* Wrap OUT pointer if we are at the end of the queue */
354 3 pq->OSQOut = pq->OSQStart;
355 3 }
356 2 OS_EXIT_CRITICAL();
357 2 *err = OS_NO_ERR;
358 2 return (msg); /* Return message received */
359 2 }
360 1 OSTCBCur->OSTCBStat |= OS_STAT_Q; /* Task will have to pend for a message to be posted */
361 1 OSTCBCur->OSTCBDly = timeout; /* Load timeout into TCB */
362 1 OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */
363 1 OS_EXIT_CRITICAL();
364 1 OS_Sched(); /* Find next highest priority task ready to run */
C51 COMPILER V7.06 OS_Q 03/05/2008 20:23:54 PAGE 7
365 1 OS_ENTER_CRITICAL();
366 1 msg = OSTCBCur->OSTCBMsg;
367 1 if (msg != (void *)0) { /* Did we get a message? */
368 2 OSTCBCur->OSTCBMsg = (void *)0; /* Extract message from TCB (Put there by QPost) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -