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