📄 os_q.lst
字号:
C51 COMPILER V7.06 OS_Q 07/18/2003 11:06:02 PAGE 1
C51 COMPILER V7.06, COMPILATION OF MODULE OS_Q
OBJECT MODULE PLACED IN .\os_q.obj
COMPILER INVOKED BY: C:\KEIL\C51\BIN\C51.EXE ..\keilc51\os_q.c LARGE BROWSE DEBUG OBJECTEXTEND PRINT(.\os_q.lst) OBJECT(
-.\os_q.obj)
stmt level source
1 /*
2 *********************************************************************************************************
3 * uC/OS-II
4 * The Real-Time Kernel
5 * MESSAGE QUEUE MANAGEMENT
6 *
7 * (c) Copyright 1992-2002, Jean J. Labrosse, Weston, FL
8 * All Rights Reserved
9 *
10 * File : OS_Q.C
11 * By : Jean J. Labrosse
12 *********************************************************************************************************
13 */
14
15 #ifndef OS_MASTER_FILE
16 #include "includes.h"
17 #endif
18
19 #if (OS_Q_EN > 0) && (OS_MAX_QS > 0)
20 /*
21 *********************************************************************************************************
22 * ACCEPT MESSAGE FROM QUEUE
23 *
24 * Description: This function checks the queue to see if a message is available. Unlike OSQPend(),
25 * OSQAccept() does not suspend the calling task if a message is not available.
26 *
27 * Arguments : pevent is a pointer to the event control block
28 *
29 * err is a pointer to where an error message will be deposited. Possible error
30 * messages are:
31 *
32 * OS_NO_ERR The call was successful and your task received a
33 * message.
34 * OS_ERR_EVENT_TYPE You didn't pass a pointer to a queue
35 * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
36 * OS_Q_EMPTY The queue did not contain any messages
37 *
38 * Returns : != (void *)0 is the message in the queue if one is available. The message is removed
39 * from the so the next time OSQAccept() is called, the queue will contain
40 * one less entry.
41 * == (void *)0 if you received a NULL pointer message
42 * if the queue is empty or,
43 * if 'pevent' is a NULL pointer or,
44 * if you passed an invalid event type
45 *
46 * Note(s) : As of V2.60, you can now pass NULL pointers through queues. Because of this, the argument
47 * 'err' has been added to the API to tell you about the outcome of the call.
48 *********************************************************************************************************
49 */
50
51 #if OS_Q_ACCEPT_EN > 0
52 void *OSQAccept (OS_EVENT *pevent, INT8U *err) reentrant //using 0
53 {
54 1 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
C51 COMPILER V7.06 OS_Q 07/18/2003 11:06:02 PAGE 2
55 1 OS_CPU_SR cpu_sr;
56 1 #endif
57 1 void *msg;
58 1 OS_Q *pq;
59 1
60 1
61 1 #if OS_ARG_CHK_EN > 0
62 1 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
63 2 *err = OS_ERR_PEVENT_NULL;
64 2 return ((void *)0);
65 2 }
66 1 #endif
67 1 if (pevent->OSEventType != OS_EVENT_TYPE_Q) {/* Validate event block type */
68 2 *err = OS_ERR_EVENT_TYPE;
69 2 return ((void *)0);
70 2 }
71 1 OS_ENTER_CRITICAL();
72 1 pq = (OS_Q *)pevent->OSEventPtr; /* Point at queue control block */
73 1 if (pq->OSQEntries > 0) { /* See if any messages in the queue */
74 2 msg = *pq->OSQOut++; /* Yes, extract oldest message from the queue */
75 2 pq->OSQEntries--; /* Update the number of entries in the queue */
76 2 if (pq->OSQOut == pq->OSQEnd) { /* Wrap OUT pointer if we are at the end of the queue */
77 3 pq->OSQOut = pq->OSQStart;
78 3 }
79 2 *err = OS_NO_ERR;
80 2 } else {
81 2 *err = OS_Q_EMPTY;
82 2 msg = (void *)0; /* Queue is empty */
83 2 }
84 1 OS_EXIT_CRITICAL();
85 1 return (msg); /* Return message received (or NULL) */
86 1 }
87 #endif
88 /*$PAGE*/
89 /*
90 *********************************************************************************************************
91 * CREATE A MESSAGE QUEUE
92 *
93 * Description: This function creates a message queue if free event control blocks are available.
94 *
95 * Arguments : start is a pointer to the base address of the message queue storage area. The
96 * storage area MUST be declared as an array of pointers to 'void' as follows
97 *
98 * void *MessageStorage[size]
99 *
100 * size is the number of elements in the storage area
101 *
102 * Returns : != (OS_EVENT *)0 is a pointer to the event control clock (OS_EVENT) associated with the
103 * created queue
104 * == (OS_EVENT *)0 if no event control blocks were available or an error was detected
105 *********************************************************************************************************
106 */
107
108 OS_EVENT *OSQCreate (void **start, INT16U size) reentrant //using 0
109 {
110 1 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
111 1 OS_CPU_SR cpu_sr;
112 1 #endif
113 1 OS_EVENT *pevent;
114 1 OS_Q *pq;
115 1
116 1
C51 COMPILER V7.06 OS_Q 07/18/2003 11:06:02 PAGE 3
117 1 if (OSIntNesting > 0) { /* See if called from ISR ... */
118 2 return ((OS_EVENT *)0); /* ... can't CREATE from an ISR */
119 2 }
120 1 OS_ENTER_CRITICAL();
121 1 pevent = OSEventFreeList; /* Get next free event control block */
122 1 if (OSEventFreeList != (OS_EVENT *)0) { /* See if pool of free ECB pool was empty */
123 2 OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;
124 2 }
125 1 OS_EXIT_CRITICAL();
126 1 if (pevent != (OS_EVENT *)0) { /* See if we have an event control block */
127 2 OS_ENTER_CRITICAL();
128 2 pq = OSQFreeList; /* Get a free queue control block */
129 2 if (pq != (OS_Q *)0) { /* Were we able to get a queue control block ? */
130 3 OSQFreeList = OSQFreeList->OSQPtr; /* Yes, Adjust free list pointer to next free*/
131 3 OS_EXIT_CRITICAL();
132 3 pq->OSQStart = start; /* Initialize the queue */
133 3 pq->OSQEnd = &start[size];
134 3 pq->OSQIn = start;
135 3 pq->OSQOut = start;
136 3 pq->OSQSize = size;
137 3 pq->OSQEntries = 0;
138 3 pevent->OSEventType = OS_EVENT_TYPE_Q;
139 3 pevent->OSEventCnt = 0;
140 3 pevent->OSEventPtr = pq;
141 3 #if OS_EVENT_NAME_SIZE > 0
142 3 (void)strcpy(pevent->OSEventName, "?");
143 3 #endif
144 3 OS_EventWaitListInit(pevent); /* Initalize the wait list */
145 3 } else {
146 3 pevent->OSEventPtr = (void *)OSEventFreeList; /* No, Return event control block on error */
147 3 OSEventFreeList = pevent;
148 3 OS_EXIT_CRITICAL();
149 3 pevent = (OS_EVENT *)0;
150 3 }
151 2 }
152 1 return (pevent);
153 1 }
154 /*$PAGE*/
155 /*
156 *********************************************************************************************************
157 * DELETE A MESSAGE QUEUE
158 *
159 * Description: This function deletes a message queue and readies all tasks pending on the queue.
160 *
161 * Arguments : pevent is a pointer to the event control block associated with the desired
162 * queue.
163 *
164 * opt determines delete options as follows:
165 * opt == OS_DEL_NO_PEND Delete the queue ONLY if no task pending
166 * opt == OS_DEL_ALWAYS Deletes the queue even if tasks are waiting.
167 * In this case, all the tasks pending will be readied.
168 *
169 * err is a pointer to an error code that can contain one of the following values:
170 * OS_NO_ERR The call was successful and the queue was deleted
171 * OS_ERR_DEL_ISR If you tried to delete the queue from an ISR
172 * OS_ERR_INVALID_OPT An invalid option was specified
173 * OS_ERR_TASK_WAITING One or more tasks were waiting on the queue
174 * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue
175 * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
176 *
177 * Returns : pevent upon error
178 * (OS_EVENT *)0 if the queue was successfully deleted.
C51 COMPILER V7.06 OS_Q 07/18/2003 11:06:02 PAGE 4
179 *
180 * Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of
181 * the queue MUST check the return code of OSQPend().
182 * 2) OSQAccept() callers will not know that the intended queue has been deleted unless
183 * they check 'pevent' to see that it's a NULL pointer.
184 * 3) This call can potentially disable interrupts for a long time. The interrupt disable
185 * time is directly proportional to the number of tasks waiting on the queue.
186 * 4) Because ALL tasks pending on the queue will be readied, you MUST be careful in
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -