📄 os_q.lst
字号:
223 * OS_NO_ERR The call was successful and your task received a message.
224 * OS_TIMEOUT A message was not received within the specified timeout
225 * OS_ERR_EVENT_TYPE You didn't pass a pointer to a queue
226 * OS_ERR_PEND_ISR If you called this function from an ISR and the result
227 * would lead to a suspension.
228 *
229 * Returns : != (void *)0 is a pointer to the message received
230 * == (void *)0 if no message was received or you didn't pass a pointer to a queue.
231 *********************************************************************************************************
232 */
233
234 void *OSQPend (OS_EVENT *pevent, INT16U timeout, INT8U *err) reentrant
235 {
236 1 void *msg;
237 1 OS_Q *pq;
238 1
239 1
240 1 OS_ENTER_CRITICAL();
241 1 if (pevent->OSEventType != OS_EVENT_TYPE_Q) {/* Validate event block type */
C51 COMPILER V7.07 OS_Q 05/31/2008 20:36:07 PAGE 5
242 2 OS_EXIT_CRITICAL();
243 2 *err = OS_ERR_EVENT_TYPE;
244 2 return ((void *)0);
245 2 }
246 1 pq = pevent->OSEventPtr; /* Point at queue control block */
247 1 if (pq->OSQEntries != 0) { /* See if any messages in the queue */
248 2 msg = *pq->OSQOut++; /* Yes, extract oldest message from the queue */
249 2 pq->OSQEntries--; /* Update the number of entries in the queue */
250 2 if (pq->OSQOut == pq->OSQEnd) { /* Wrap OUT pointer if we are at the end of the queue */
251 3 pq->OSQOut = pq->OSQStart;
252 3 }
253 2 OS_EXIT_CRITICAL();
254 2 *err = OS_NO_ERR;
255 2 } else if (OSIntNesting > 0) { /* See if called from ISR ... */
256 2 OS_EXIT_CRITICAL(); /* ... can't PEND from an ISR */
257 2 *err = OS_ERR_PEND_ISR;
258 2 } else {
259 2 OSTCBCur->OSTCBStat |= OS_STAT_Q; /* Task will have to pend for a message to be posted */
260 2 OSTCBCur->OSTCBDly = timeout; /* Load timeout into TCB */
261 2 OSEventTaskWait(pevent); /* Suspend task until event or timeout occurs */
262 2 OS_EXIT_CRITICAL();
263 2 OSSched(); /* Find next highest priority task ready to run */
264 2 OS_ENTER_CRITICAL();
265 2 if ((msg = OSTCBCur->OSTCBMsg) != (void *)0) {/* Did we get a message? */
266 3 OSTCBCur->OSTCBMsg = (void *)0; /* Extract message from TCB (Put there by QPost) */
267 3 OSTCBCur->OSTCBStat = OS_STAT_RDY;
268 3 OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* No longer waiting for event */
269 3 OS_EXIT_CRITICAL();
270 3 *err = OS_NO_ERR;
271 3 } else if (OSTCBCur->OSTCBStat & OS_STAT_Q) { /* Timed out if status indicates pending on Q */
272 3 OSEventTO(pevent);
273 3 OS_EXIT_CRITICAL();
274 3 msg = (void *)0; /* No message received */
275 3 *err = OS_TIMEOUT; /* Indicate a timeout occured */
276 3 } else {
277 3 msg = *pq->OSQOut++; /* Extract message from queue */
278 3 pq->OSQEntries--; /* Update the number of entries in the queue */
279 3 if (pq->OSQOut == pq->OSQEnd) { /* Wrap OUT pointer if we are at the end of Q */
280 4 pq->OSQOut = pq->OSQStart;
281 4 }
282 3 OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;
283 3 OS_EXIT_CRITICAL();
284 3 *err = OS_NO_ERR;
285 3 }
286 2 }
287 1 return (msg); /* Return message received (or NULL) */
288 1 }
289 /*$PAGE*/
290 /*
291 *********************************************************************************************************
292 * POST MESSAGE TO A QUEUE
293 *
294 * Description: This function sends a message to a queue
295 *
296 * Arguments : pevent is a pointer to the event control block associated with the desired queue
297 *
298 * msg is a pointer to the message to send. You MUST NOT send a NULL pointer.
299 *
300 * Returns : OS_NO_ERR The call was successful and the message was sent
301 * OS_Q_FULL If the queue cannot accept any more messages because it is full.
302 * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue.
303 *********************************************************************************************************
C51 COMPILER V7.07 OS_Q 05/31/2008 20:36:07 PAGE 6
304 */
305
306 INT8U OSQPost (OS_EVENT *pevent, void *msg) reentrant
307 {
308 1 OS_Q *pq;
309 1
310 1
311 1 OS_ENTER_CRITICAL();
312 1 if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
313 2 OS_EXIT_CRITICAL();
314 2 return (OS_ERR_EVENT_TYPE);
315 2 }
316 1 if (pevent->OSEventGrp) { /* See if any task pending on queue */
317 2 OSEventTaskRdy(pevent, msg, OS_STAT_Q); /* Ready highest priority task waiting on event */
318 2 OS_EXIT_CRITICAL();
319 2 OSSched(); /* Find highest priority task ready to run */
320 2 return (OS_NO_ERR);
321 2 } else {
322 2 pq = pevent->OSEventPtr; /* Point to queue control block */
323 2 if (pq->OSQEntries >= pq->OSQSize) { /* Make sure queue is not full */
324 3 OS_EXIT_CRITICAL();
325 3 return (OS_Q_FULL);
326 3 } else {
327 3 *pq->OSQIn++ = msg; /* Insert message into queue */
328 3 pq->OSQEntries++; /* Update the nbr of entries in the queue */
329 3 if (pq->OSQIn == pq->OSQEnd) { /* Wrap IN ptr if we are at end of queue */
330 4 pq->OSQIn = pq->OSQStart;
331 4 }
332 3 OS_EXIT_CRITICAL();
333 3 }
334 2 return (OS_NO_ERR);
335 2 }
336 1 }
337 /*$PAGE*/
338 /*
339 *********************************************************************************************************
340 * POST MESSAGE TO THE FRONT OF A QUEUE
341 *
342 * Description: This function sends a message to a queue but unlike OSQPost(), the message is posted at
343 * the front instead of the end of the queue. Using OSQPostFront() allows you to send
344 * 'priority' messages.
345 *
346 * Arguments : pevent is a pointer to the event control block associated with the desired queue
347 *
348 * msg is a pointer to the message to send. You MUST NOT send a NULL pointer.
349 *
350 * Returns : OS_NO_ERR The call was successful and the message was sent
351 * OS_Q_FULL If the queue cannot accept any more messages because it is full.
352 * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue.
353 *********************************************************************************************************
354 */
355
356 INT8U OSQPostFront (OS_EVENT *pevent, void *msg) reentrant
357 {
358 1 OS_Q *pq;
359 1
360 1
361 1 OS_ENTER_CRITICAL();
362 1 if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
363 2 OS_EXIT_CRITICAL();
364 2 return (OS_ERR_EVENT_TYPE);
365 2 }
C51 COMPILER V7.07 OS_Q 05/31/2008 20:36:07 PAGE 7
366 1 if (pevent->OSEventGrp) { /* See if any task pending on queue */
367 2 OSEventTaskRdy(pevent, msg, OS_STAT_Q); /* Ready highest priority task waiting on event */
368 2 OS_EXIT_CRITICAL();
369 2 OSSched(); /* Find highest priority task ready to run */
370 2 return (OS_NO_ERR);
371 2 } else {
372 2 pq = pevent->OSEventPtr; /* Point to queue control block */
373 2 if (pq->OSQEntries >= pq->OSQSize) { /* Make sure queue is not full */
374 3 OS_EXIT_CRITICAL();
375 3 return (OS_Q_FULL);
376 3 } else {
377 3 if (pq->OSQOut == pq->OSQStart) { /* Wrap OUT ptr if we are at the 1st queue entry */
378 4 pq->OSQOut = pq->OSQEnd;
379 4 }
380 3 pq->OSQOut--;
381 3 *pq->OSQOut = msg; /* Insert message into queue */
382 3 pq->OSQEntries++; /* Update the nbr of entries in the queue */
383 3 OS_EXIT_CRITICAL();
384 3 }
385 2 return (OS_NO_ERR);
386 2 }
387 1 }
388 /*$PAGE*/
389 /*
390 *********************************************************************************************************
391 * QUERY A MESSAGE QUEUE
392 *
393 * Description: This function obtains information about a message queue.
394 *
395 * Arguments : pevent is a pointer to the event control block associated with the desired mailbox
396 *
397 * pdata is a pointer to a structure that will contain information about the message
398 * queue.
399 *
400 * Returns : OS_NO_ERR The call was successful and the message was sent
401 * OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non queue.
402 *********************************************************************************************************
403 */
404
405 INT8U OSQQuery (OS_EVENT *pevent, OS_Q_DATA *ppdata) reentrant
406 {
407 1 OS_Q *pq;
408 1 INT8U i;
409 1 INT8U *psrc;
410 1 INT8U *pdest;
411 1
412 1
413 1 OS_ENTER_CRITICAL();
414 1 if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
415 2 OS_EXIT_CRITICAL();
416 2 return (OS_ERR_EVENT_TYPE);
417 2 }
418 1 ppdata->OSEventGrp = pevent->OSEventGrp; /* Copy message mailbox wait list */
419 1 psrc = &pevent->OSEventTbl[0];
420 1 pdest = &ppdata->OSEventTbl[0];
421 1 for (i = 0; i < OS_EVENT_TBL_SIZE; i++) {
422 2 *pdest++ = *psrc++;
423 2 }
424 1 pq = (OS_Q *)pevent->OSEventPtr;
425 1 if (pq->OSQEntries > 0) {
426 2 ppdata->OSMsg = pq->OSQOut; /* Get next message to return if available */
427 2 } else {
C51 COMPILER V7.07 OS_Q 05/31/2008 20:36:07 PAGE 8
428 2 ppdata->OSMsg = (void *)0;
429 2 }
430 1 ppdata->OSNMsgs = pq->OSQEntries;
431 1 ppdata->OSQSize = pq->OSQSize;
432 1 OS_EXIT_CRITICAL();
433 1 return (OS_NO_ERR);
434 1 }
435 #endif
MODULE INFORMATION: STATIC OVERLAYABLE
CODE SIZE = 3291 ----
CONSTANT SIZE = ---- ----
XDATA SIZE = 41 ----
PDATA SIZE = ---- ----
DATA SIZE = ---- ----
IDATA SIZE = ---- ----
BIT SIZE = ---- ----
END OF MODULE INFORMATION.
C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -