📄 os_q.lst
字号:
ANSI-C/cC++ Compiler for HC08 V-5.0.12 ICG, Oct 6 2000
1: /*
2: *********************************************************************************************************
3: * uC/OS-II
4: * The Real-Time Kernel
5: * MESSAGE QUEUE MANAGEMENT
6: *
7: * (c) Copyright 1992-1998, Jean J. Labrosse, Plantation, FL
8: * All Rights Reserved
9: *
10: * V2.00
11: *
12: * File : OS_Q.C
13: * By : Jean J. Labrosse
14: *********************************************************************************************************
15: */
16: #include "includes.h"
17:
18:
19: #if OS_Q_EN && (OS_MAX_QS >= 2)
20: /*
21: *********************************************************************************************************
22: * LOCAL DATA TYPES
23: *********************************************************************************************************
24: */
25:
26: typedef struct os_q { /* QUEUE CONTROL BLOCK */
27: struct os_q *OSQPtr; /* Link to next queue control block in list of free blocks */
28: void **OSQStart; /* Pointer to start of queue data */
29: void **OSQEnd; /* Pointer to end of queue data */
30: void **OSQIn; /* Pointer to where next message will be inserted in the Q */
31: void **OSQOut; /* Pointer to where next message will be extracted from the Q */
32: INT16U OSQSize; /* Size of queue (maximum number of entries) */
33: INT16U OSQEntries; /* Current number of entries in the queue */
34: } OS_Q;
35:
36: /*
37: *********************************************************************************************************
38: * LOCAL GLOBAL VARIABLES
39: *********************************************************************************************************
40: */
41:
42: static OS_Q *OSQFreeList; /* Pointer to list of free QUEUE control blocks */
43: static OS_Q OSQTbl[OS_MAX_QS]; /* Table of QUEUE control blocks */
44:
45: /*$PAGE*/
46: /*
47: *********************************************************************************************************
48: * ACCEPT MESSAGE FROM QUEUE
49: *
50: * Description: This function checks the queue to see if a message is available. Unlike OSQPend(),
51: * OSQAccept() does not suspend the calling task if a message is not available.
52: *
53: * Arguments : pevent is a pointer to the event control block
54: *
55: * Returns : != (void *)0 is the message in the queue if one is available. The message is removed
56: * from the so the next time OSQAccept() is called, the queue will contain
57: * one less entry.
58: * == (void *)0 if the queue is empty
59: * if you passed an invalid event type
60: *********************************************************************************************************
61: */
62:
63: void *OSQAccept (OS_EVENT *pevent)
64: {
65: void *msg;
66: OS_Q *pq;
67:
68:
69: OS_ENTER_CRITICAL();
70: if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
71: OS_EXIT_CRITICAL();
72: return ((void *)0);
73: }
74: pq = pevent->OSEventPtr; /* Point at queue control block */
75: if (pq->OSQEntries != 0) { /* See if any messages in the queue */
76: msg = *pq->OSQOut++; /* Yes, extract oldest message from the queue */
77: pq->OSQEntries--; /* Update the number of entries in the queue */
78: if (pq->OSQOut == pq->OSQEnd) { /* Wrap OUT pointer if we are at the end of the queue */
79: pq->OSQOut = pq->OSQStart;
80: }
81: } else {
82: msg = (void *)0; /* Queue is empty */
83: }
84: OS_EXIT_CRITICAL();
85: return (msg); /* Return message received (or NULL) */
86: }
87: /*$PAGE*/
88: /*
89: *********************************************************************************************************
90: * CREATE A MESSAGE QUEUE
91: *
92: * Description: This function creates a message queue if free event control blocks are available.
93: *
94: * Arguments : start is a pointer to the base address of the message queue storage area. The
95: * storage area MUST be declared as an array of pointers to 'void' as follows
96: *
97: * void *MessageStorage[size]
98: *
99: * size is the number of elements in the storage area
100: *
101: * Returns : != (void *)0 is a pointer to the event control clock (OS_EVENT) associated with the
102: * created queue
103: * == (void *)0 if no event control blocks were available
104: *********************************************************************************************************
105: */
106:
107: OS_EVENT *OSQCreate (void **start, INT16U size)
108: {
109: OS_EVENT *pevent;
110: OS_Q *pq;
111:
112:
113: OS_ENTER_CRITICAL();
114: pevent = OSEventFreeList; /* Get next free event control block */
115: if (OSEventFreeList != (OS_EVENT *)0) { /* See if pool of free ECB pool was empty */
116: OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;
117: }
118: OS_EXIT_CRITICAL();
119: if (pevent != (OS_EVENT *)0) { /* See if we have an event control block */
120: OS_ENTER_CRITICAL(); /* Get a free queue control block */
121: pq = OSQFreeList;
122: if (OSQFreeList != (OS_Q *)0) {
123: OSQFreeList = OSQFreeList->OSQPtr;
124: }
125: OS_EXIT_CRITICAL();
126: if (pq != (OS_Q *)0) { /* See if we were able to get a queue control block */
127: pq->OSQStart = start; /* Yes, initialize the queue */
128: pq->OSQEnd = &start[size];
129: pq->OSQIn = start;
130: pq->OSQOut = start;
131: pq->OSQSize = size;
132: pq->OSQEntries = 0;
133: pevent->OSEventType = OS_EVENT_TYPE_Q;
134: pevent->OSEventPtr = pq;
135: OSEventWaitListInit(pevent);
136: } else { /* No, since we couldn't get a queue control block */
137: OS_ENTER_CRITICAL(); /* Return event control block on error */
138: pevent->OSEventPtr = (void *)OSEventFreeList;
139: OSEventFreeList = pevent;
140: OS_EXIT_CRITICAL();
141: pevent = (OS_EVENT *)0;
142: }
143: }
144: return (pevent);
145: }
146: /*$PAGE*/
147: /*
148: *********************************************************************************************************
149: * FLUSH QUEUE
150: *
151: * Description : This function is used to flush the contents of the message queue.
152: *
153: * Arguments : none
154: *
155: * Returns : OS_NO_ERR upon success
156: * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue
157: *********************************************************************************************************
158: */
159:
160: INT8U OSQFlush (OS_EVENT *pevent)
161: {
162: OS_Q *pq;
163:
164:
165: OS_ENTER_CRITICAL();
166: if (pevent->OSEventType != OS_EVENT_TYPE_Q) { /* Validate event block type */
167: OS_EXIT_CRITICAL();
168: return (OS_ERR_EVENT_TYPE);
169: }
170: pq = pevent->OSEventPtr; /* Point to queue storage structure */
171: pq->OSQIn = pq->OSQStart;
172: pq->OSQOut = pq->OSQStart;
173: pq->OSQEntries = 0;
174: OS_EXIT_CRITICAL();
175: return (OS_NO_ERR);
176: }
177:
178: /*$PAGE*/
179: /*
180: *********************************************************************************************************
181: * QUEUE MODULE INITIALIZATION
182: *
183: * Description : This function is called by uC/OS-II to initialize the message queue module. Your
184: * application MUST NOT call this function.
185: *
186: * Arguments : none
187: *
188: * Returns : none
189: *********************************************************************************************************
190: */
191:
192: void OSQInit (void)
193: {
194: INT16U i;
195:
196:
197: for (i = 0; i < (OS_MAX_QS - 1); i++) { /* Init. list of free QUEUE control blocks */
198: OSQTbl[i].OSQPtr = &OSQTbl[i+1];
199: }
200: OSQTbl[OS_MAX_QS - 1].OSQPtr = (OS_Q *)0;
201: OSQFreeList = &OSQTbl[0];
202: }
203:
204: /*$PAGE*/
205: /*
206: *********************************************************************************************************
207: * PEND ON A QUEUE FOR A MESSAGE
208: *
209: * Description: This function waits for a message to be sent to a queue
210: *
211: * Arguments : pevent is a pointer to the event control block associated with the desired queue
212: *
213: * timeout is an optional timeout period (in clock ticks). If non-zero, your task will
214: * wait for a message to arrive at the queue up to the amount of time
215: * specified by this argument. If you specify 0, however, your task will wait
216: * forever at the specified queue or, until a message arrives.
217: *
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -