📄 os_q.lst
字号:
OS_CPU_SR cpu_sr;
#endif
182 1 BOOLEAN tasks_waiting;
183 1 OS_Q *pq;
184 1
185 1
186 1 if (OSIntNesting > 0) { /* See if called from ISR ... */
187 2 *err = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */
188 2 return ((OS_EVENT *)0);
189 2 }
190 1 #if OS_ARG_CHK_EN > 0
191 1 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
192 2 *err = OS_ERR_PEVENT_NULL;
193 2 return (pevent);
194 2 }
195 1 if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
196 2 *err = OS_ERR_EVENT_TYPE;
197 2 return (pevent);
198 2 }
199 1 #endif
200 1 OS_ENTER_CRITICAL();
201 1 if (pevent->OSEventGrp != 0x00) { /* See if any tasks waiting on queue */
202 2 tasks_waiting = TRUE; /* Yes */
203 2 } else {
204 2 tasks_waiting = FALSE; /* No */
205 2 }
206 1 switch (opt) {
207 2 case OS_DEL_NO_PEND: /* Delete queue only if no task waiting */
208 2 if (tasks_waiting == FALSE) {
209 3 pq = (OS_Q *)pevent->OSEventPtr; /* Return OS_Q to free list */
210 3 pq->OSQPtr = OSQFreeList;
211 3 OSQFreeList = pq;
212 3 pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
213 3 pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
214 3 OSEventFreeList = pevent; /* Get next free event control block */
215 3 OS_EXIT_CRITICAL();
216 3 *err = OS_NO_ERR;
217 3 return ((OS_EVENT *)0); /* Queue has been deleted */
218 3 } else {
219 3 OS_EXIT_CRITICAL();
220 3 *err = OS_ERR_TASK_WAITING;
221 3 return (pevent);
222 3 }
223 2
224 2 case OS_DEL_ALWAYS: /* Always delete the queue */
225 2 while (pevent->OSEventGrp != 0x00) { /* Ready ALL tasks waiting for queue */
226 3 OS_EventTaskRdy(pevent, (void *)0, OS_STAT_Q);
227 3 }
228 2 pq = (OS_Q *)pevent->OSEventPtr; /* Return OS_Q to free list */
229 2 pq->OSQPtr = OSQFreeList;
230 2 OSQFreeList = pq;
231 2 pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
232 2 pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
233 2 OSEventFreeList = pevent; /* Get next free event control block */
234 2 OS_EXIT_CRITICAL();
235 2 if (tasks_waiting == TRUE) { /* Reschedule only if task(s) were waiting */
236 3 OS_Sched(); /* Find highest priority task ready to run */
237 3 }
238 2 *err = OS_NO_ERR;
239 2 return ((OS_EVENT *)0); /* Queue has been deleted */
240 2
241 2 default:
C51 COMPILER V6.23a OS_Q 12/09/2004 16:50:26 PAGE 5
242 2 OS_EXIT_CRITICAL();
243 2 *err = OS_ERR_INVALID_OPT;
244 2 return (pevent);
245 2 }
246 1 }
247 #endif
248
249 /*$PAGE*/
250 /*
251 *********************************************************************************************************
252 * FLUSH QUEUE
253 *
254 * Description : This function is used to flush the contents of the message queue.
255 *
256 * Arguments : none
257 *
258 * Returns : OS_NO_ERR upon success
259 * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue
260 * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
261 *********************************************************************************************************
262 */
263
264 #if OS_Q_FLUSH_EN > 0
265 INT8U OSQFlush (OS_EVENT *pevent) KCREENTRANT
266 {
267 1 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
270 1 OS_Q *pq;
271 1
272 1
273 1 #if OS_ARG_CHK_EN > 0
274 1 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
275 2 return (OS_ERR_PEVENT_NULL);
276 2 }
277 1 if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
278 2 return (OS_ERR_EVENT_TYPE);
279 2 }
280 1 #endif
281 1 OS_ENTER_CRITICAL();
282 1 pq = (OS_Q *)pevent->OSEventPtr; /* Point to queue storage structure */
283 1 pq->OSQIn = pq->OSQStart;
284 1 pq->OSQOut = pq->OSQStart;
285 1 pq->OSQEntries = 0;
286 1 OS_EXIT_CRITICAL();
287 1 return (OS_NO_ERR);
288 1 }
289 #endif
290
291 /*$PAGE*/
292 /*
293 *********************************************************************************************************
294 * PEND ON A QUEUE FOR A MESSAGE
295 *
296 * Description: This function waits for a message to be sent to a queue
297 *
298 * Arguments : pevent is a pointer to the event control block associated with the desired queue
299 *
300 * timeout is an optional timeout period (in clock ticks). If non-zero, your task will
301 * wait for a message to arrive at the queue up to the amount of time
302 * specified by this argument. If you specify 0, however, your task will wait
303 * forever at the specified queue or, until a message arrives.
C51 COMPILER V6.23a OS_Q 12/09/2004 16:50:26 PAGE 6
304 *
305 * err is a pointer to where an error message will be deposited. Possible error
306 * messages are:
307 *
308 * OS_NO_ERR The call was successful and your task received a
309 * message.
310 * OS_TIMEOUT A message was not received within the specified timeout
311 * OS_ERR_EVENT_TYPE You didn't pass a pointer to a queue
312 * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer
313 * OS_ERR_PEND_ISR If you called this function from an ISR and the result
314 * would lead to a suspension.
315 *
316 * Returns : != (void *)0 is a pointer to the message received
317 * == (void *)0 if no message was received or,
318 * if 'pevent' is a NULL pointer or,
319 * if you didn't pass a pointer to a queue.
320 *********************************************************************************************************
321 */
322
323 void *OSQPend (OS_EVENT *pevent, INT16U timeout, INT8U *err) KCREENTRANT
324 {
325 1 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr;
#endif
328 1 void *msg;
329 1 OS_Q *pq;
330 1
331 1
332 1 if (OSIntNesting > 0) { /* See if called from ISR ... */
333 2 *err = OS_ERR_PEND_ISR; /* ... can't PEND from an ISR */
334 2 return ((void *)0);
335 2 }
336 1 #if OS_ARG_CHK_EN > 0
337 1 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
338 2 *err = OS_ERR_PEVENT_NULL;
339 2 return ((void *)0);
340 2 }
341 1 if (pevent->OSEventType != OS_EVENT_TYPE_Q) {/* Validate event block type */
342 2 *err = OS_ERR_EVENT_TYPE;
343 2 return ((void *)0);
344 2 }
345 1 #endif
346 1 OS_ENTER_CRITICAL();
347 1 pq = (OS_Q *)pevent->OSEventPtr; /* Point at queue control block */
348 1 if (pq->OSQEntries > 0) { /* See if any messages in the queue */
349 2 msg = *pq->OSQOut++; /* Yes, extract oldest message from the queue */
350 2 pq->OSQEntries--; /* Update the number of entries in the queue */
351 2 if (pq->OSQOut == pq->OSQEnd) { /* Wrap OUT pointer if we are at the end of the queue */
352 3 pq->OSQOut = pq->OSQStart;
353 3 }
354 2 OS_EXIT_CRITICAL();
355 2 *err = OS_NO_ERR;
356 2 return (msg); /* Return message received */
357 2 }
358 1 OSTCBCur->OSTCBStat |= OS_STAT_Q; /* Task will have to pend for a message to be posted */
359 1 OSTCBCur->OSTCBDly = timeout; /* Load timeout into TCB */
360 1 OS_EventTaskWait(pevent); /* Suspend task until event or timeout occurs */
361 1 OS_EXIT_CRITICAL();
362 1 OS_Sched(); /* Find next highest priority task ready to run */
363 1 OS_ENTER_CRITICAL();
364 1 msg = OSTCBCur->OSTCBMsg;
365 1 if (msg != (void *)0) { /* Did we get a message? */
C51 COMPILER V6.23a OS_Q 12/09/2004 16:50:26 PAGE 7
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -