📄 os_q.src
字号:
; * will no longer be guarded by the queue.
; * 5) If the storage for the message queue was allocated dynamically (i.e. using a malloc()
; * type call) then your application MUST release the memory storage by call the counterpart
; * call of the dynamic allocation scheme used. If the queue storage was created statically
; * then, the storage can be reused.
; *********************************************************************************************************
; */
;
; #if OS_Q_DEL_EN > 0
; OS_EVENT *OSQDel (OS_EVENT *pevent, INT8U opt, INT8U *err)LG_REENTRANT
; {
; #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 = (OS_Q *)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 = (OS_Q *)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;
; return ((OS_EVENT *)0); /* Queue has been deleted */
;
; default:
; OS_EXIT_CRITICAL();
; *err = OS_ERR_INVALID_OPT;
; return (pevent);
; }
; }
; #endif
;
; /*$PAGE*/
; /*
; *********************************************************************************************************
; * FLUSH QUEUE
; *
; * Description : This function is used to flush the contents of the message queue.
; *
; * Arguments : none
; *
; * Returns : OS_NO_ERR upon success
; * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue
; * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
; *********************************************************************************************************
; */
;
; #if OS_Q_FLUSH_EN > 0
; INT8U OSQFlush (OS_EVENT *pevent)LG_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
;
; /*$PAGE*/
; /*
; *********************************************************************************************************
; * PEND ON A QUEUE FOR A MESSAGE
; *
; * Description: This function waits for a message to be sent to a queue
; *
; * Arguments : pevent is a pointer to the event control block associated with the desired queue
; *
; * timeout is an optional timeout period (in clock ticks). If non-zero, your task will
; * wait for a message to arrive at the queue up to the amount of time
; * specified by this argument. If you specify 0, however, your task will wait
; * forever at the specified queue or, until a message arrives.
; *
; * err is a pointer to where an error message will be deposited. Possible error
; * messages are:
; *
; * OS_NO_ERR The call was successful and your task received a
; * message.
; * OS_TIMEOUT A message was not received within the specified timeout
; * OS_ERR_EVENT_TYPE You didn't pass a pointer to a queue
; * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
; * OS_ERR_PEND_ISR If you called this function from an ISR and the result
; * would lead to a suspension.
; *
; * Returns : != (void *)0 is a pointer to the message received
; * == (void *)0 if no message was received or,
; * if 'pevent' is a NULL pointer or,
; * if you didn't pass a pointer to a queue.
; *********************************************************************************************************
; */
;
; void *OSQPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)LG_REENTRANT
; {
; #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
; OS_CPU_SR cpu_sr;
; #endif
; void *msg;
; OS_Q *pq;
;
;
; if (OSIntNesting > 0) { /* See if called from ISR ... */
; *err = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */
; return ((void *)0);
; }
; #if OS_ARG_CHK_EN > 0
; if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
; *err = OS_ERR_PEVENT_NULL;
; return ((void *)0);
; }
; if (pevent->OSEventType != OS_EVENT_TYPE_Q) {/* Validate event block type */
; *err = OS_ERR_EVENT_TYPE;
; return ((void *)0);
; }
; #endif
; OS_ENTER_CRITICAL();
; pq = (OS_Q *)pevent->OSEventPtr; /* Point at queue control block */
; if (pq->OSQEntries > 0) { /* See if any messages in the queue */
; msg = *pq->OSQOut++; /* Yes, extract oldest message from the queue */
; pq->OSQEntries--; /* Update the number of entries in the queue */
; if (pq->OSQOut == pq->OSQEnd) { /* Wrap OUT pointer if we are at the end of the queue */
; pq->OSQOut = pq->OSQStart;
; }
; OS_EXIT_CRITICAL();
; *err = OS_NO_ERR;
; return (msg); /* Return message received */
; }
; OSTCBCur->OSTCBStat |= OS_STAT_Q; /* Task will have to pend for a message to be posted */
; OSTCBCur->OSTCBDly = timeout; /* Load timeout into TCB */
; OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */
; OS_EXIT_CRITICAL();
; OS_Sched(); /* Find next highest priority task ready to run */
; OS_ENTER_CRITICAL();
; msg = OSTCBCur->OSTCBMsg;
; if (msg != (void *)0) { /* Did we get a message? */
; OSTCBCur->OSTCBMsg = (void *)0; /* Extract message from TCB (Put there by QPost) */
; OSTCBCur->OSTCBStat = OS_STAT_RDY;
; OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0; /* No longer waiting for event */
; OS_EXIT_CRITICAL();
; *err = OS_NO_ERR;
; return (msg); /* Return message received */
; }
; OS_EventTO(pevent); /* Timed out */
; OS_EXIT_CRITICAL();
; *err = OS_TIMEOUT; /* Indicate a timeout occured */
; return ((void *)0); /* No message received */
; }
; /*$PAGE*/
; /*
; *********************************************************************************************************
; * POST MESSAGE TO A QUEUE
; *
; * Description: This function sends a message to a queue
; *
; * Arguments : pevent is a pointer to the event control block associated with the desired queue
; *
; * msg is a pointer to the message to send. You MUST NOT send a NULL pointer.
; *
; * Returns : OS_NO_ERR The call was successful and the message was sent
; * OS_Q_FULL If the queue cannot accept any more messages because it is full.
; * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue.
; * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
; * OS_ERR_POST_NULL_PTR If you are attempting to post a NULL pointer
; *********************************************************************************************************
; */
;
; #if OS_Q_POST_EN > 0
; INT8U OSQPost (OS_EVENT *pevent, void *msg)LG_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 (msg == (void *)0) { /* Make sure we are not posting a NULL pointer */
; return (OS_ERR_POST_NULL_PTR);
; }
; if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
; return (OS_ERR_EVENT_TYPE);
; }
; #endif
; OS_ENTER_CRITICAL();
; if (pevent->OSEventGrp != 0x00) { /* See if any task pending on queue */
; OS_EventTaskRdy(pevent, msg, OS_STAT_Q); /* Ready highest priority task waiting on event */
; OS_EXIT_CRITICAL();
; OS_Sched(); /* Find highest priority task ready to run */
; return (OS_NO_ERR);
; }
; pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue control block */
; if (pq->OSQEntries >= pq->OSQSize) { /* Make sure queue is not full */
; OS_EXIT_CRITICAL();
; return (OS_Q_FULL);
; }
; *pq->OSQIn++ = msg; /* Insert message into queue */
; pq->OSQEntries++; /* Update the nbr of entries in the queue */
; if (pq->OSQIn == pq->OSQEnd) { /* Wrap IN ptr if we are at end of queue */
; pq->OSQIn = pq->OSQStart;
; }
; OS_EXIT_CRITICAL();
; return (OS_NO_ERR);
; }
; #endif
; /*$PAGE*/
; /*
; *********************************************************************************************************
; * POST MESSAGE TO THE FRONT OF A QUEUE
; *
; * Description: This function sends a message to a queue but unlike OSQPost(), the message is posted at
; * the front instead of the end of the queue. Using OSQPostFront() allows you to send
; * 'priority' messages.
; *
; * Arguments : pevent is a pointer to the event control block associated with the desired queue
; *
; * msg is a pointer to the message to send. You MUST NOT send a NULL pointer.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -