📄 os_mutex.lst
字号:
104 *
105 * Description: This function creates a mutual exclusion semaphore.
106 *
107 * Arguments : prio is the priority to use when accessing the mutual exclusion semaphore. In
108 * other words, when the semaphore is acquired and a higher priority task
109 * attempts to obtain the semaphore then the priority of the task owning the
110 * semaphore is raised to this priority. It is assumed that you will specify
111 * a priority that is LOWER in value than ANY of the tasks competing for the
112 * mutex.
113 *
114 * err is a pointer to an error code which will be returned to your application:
115 * OS_NO_ERR if the call was successful.
116 * OS_ERR_CREATE_ISR if you attempted to create a MUTEX from an ISR
117 * OS_PRIO_EXIST if a task at the priority inheritance priority
118 * already exist.
119 * OS_ERR_PEVENT_NULL No more event control blocks available.
120 * OS_PRIO_INVALID if the priority you specify is higher that the
121 * maximum allowed (i.e. > OS_LOWEST_PRIO)
C51 COMPILER V8.08 OS_MUTEX 08/04/2008 21:49:52 PAGE 4
122 *
123 * Returns : != (void *)0 is a pointer to the event control clock (OS_EVENT) associated with the
124 * created mutex.
125 * == (void *)0 if an error is detected.
126 *
127 * Note(s) : 1) The LEAST significant 8 bits of '.OSEventCnt' are used to hold the priority number
128 * of the task owning the mutex or 0xFF if no task owns the mutex.
129 * 2) The MOST significant 8 bits of '.OSEventCnt' are used to hold the priority number
130 * to use to reduce priority inversion.
131 *********************************************************************************************************
132 */
133
134 OS_EVENT *OSMutexCreate (INT8U prio, INT8U *err)
135 {
136 OS_EVENT *pevent;
137 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
140
141
142
143 #if OS_ARG_CHK_EN > 0
144 if (err == (INT8U *)0) { /* Validate 'err' */
145 return ((OS_EVENT *)0);
146 }
147 if (prio >= OS_LOWEST_PRIO) { /* Validate PIP */
148 *err = OS_PRIO_INVALID;
149 return ((OS_EVENT *)0);
150 }
151 #endif
152 if (OSIntNesting > 0) { /* See if called from ISR ... */
153 *err = OS_ERR_CREATE_ISR; /* ... can't CREATE mutex from an ISR */
154 return ((OS_EVENT *)0);
155 }
156 OS_ENTER_CRITICAL();
157 if (OSTCBPrioTbl[prio] != (OS_TCB *)0) { /* Mutex priority must not already exist */
158 OS_EXIT_CRITICAL(); /* Task already exist at priority ... */
159 *err = OS_PRIO_EXIST; /* ... inheritance priority */
160 return ((OS_EVENT *)0);
161 }
162 OSTCBPrioTbl[prio] = (OS_TCB *)1; /* Reserve the table entry */
163 pevent = OSEventFreeList; /* Get next free event control block */
164 if (pevent == (OS_EVENT *)0) { /* See if an ECB was available */
165 OSTCBPrioTbl[prio] = (OS_TCB *)0; /* No, Release the table entry */
166 OS_EXIT_CRITICAL();
167 *err = OS_ERR_PEVENT_NULL; /* No more event control blocks */
168 return (pevent);
169 }
170 OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; /* Adjust the free list */
171 OS_EXIT_CRITICAL();
172 pevent->OSEventType = OS_EVENT_TYPE_MUTEX;
173 pevent->OSEventCnt = (INT16U)((INT16U)prio << 8) | OS_MUTEX_AVAILABLE; /* Resource is avail. */
174 pevent->OSEventPtr = (void *)0; /* No task owning the mutex */
175 #if OS_EVENT_NAME_SIZE > 1
176 pevent->OSEventName[0] = '?';
177 pevent->OSEventName[1] = OS_ASCII_NUL;
178 #endif
179 OS_EventWaitListInit(pevent);
180 *err = OS_NO_ERR;
181 return (pevent);
182 }
183
C51 COMPILER V8.08 OS_MUTEX 08/04/2008 21:49:52 PAGE 5
184 /*$PAGE*/
185 /*
186 *********************************************************************************************************
187 * DELETE A MUTEX
188 *
189 * Description: This function deletes a mutual exclusion semaphore and readies all tasks pending on the it.
190 *
191 * Arguments : pevent is a pointer to the event control block associated with the desired mutex.
192 *
193 * opt determines delete options as follows:
194 * opt == OS_DEL_NO_PEND Delete mutex ONLY if no task pending
195 * opt == OS_DEL_ALWAYS Deletes the mutex even if tasks are waiting.
196 * In this case, all the tasks pending will be readied.
197 *
198 * err is a pointer to an error code that can contain one of the following values:
199 * OS_NO_ERR The call was successful and the mutex was deleted
200 * OS_ERR_DEL_ISR If you attempted to delete the MUTEX from an ISR
201 * OS_ERR_INVALID_OPT An invalid option was specified
202 * OS_ERR_TASK_WAITING One or more tasks were waiting on the mutex
203 * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mutex
204 * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
205 *
206 * Returns : pevent upon error
207 * (OS_EVENT *)0 if the mutex was successfully deleted.
208 *
209 * Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of
210 * the mutex MUST check the return code of OSMutexPend().
211 * 2) This call can potentially disable interrupts for a long time. The interrupt disable
212 * time is directly proportional to the number of tasks waiting on the mutex.
213 * 3) Because ALL tasks pending on the mutex will be readied, you MUST be careful because the
214 * resource(s) will no longer be guarded by the mutex.
215 *********************************************************************************************************
216 */
217
218 #if OS_MUTEX_DEL_EN
219 OS_EVENT *OSMutexDel (OS_EVENT *pevent, INT8U opt, INT8U *err)
220 {
221 BOOLEAN tasks_waiting;
222 OS_EVENT *pevent_return;
223 INT8U pip;
224 #if OS_CRITICAL_METHOD == 3 /* Allocate storage for CPU status register */
OS_CPU_SR cpu_sr = 0;
#endif
227
228
229
230 #if OS_ARG_CHK_EN > 0
231 if (err == (INT8U *)0) { /* Validate 'err' */
232 return ((OS_EVENT *)0);
233 }
234 if (pevent == (OS_EVENT *)0) { /* Validate 'pevent' */
235 *err = OS_ERR_PEVENT_NULL;
236 return ((OS_EVENT *)0);
237 }
238 #endif
239 if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type */
240 *err = OS_ERR_EVENT_TYPE;
241 return (pevent);
242 }
243 if (OSIntNesting > 0) { /* See if called from ISR ... */
244 *err = OS_ERR_DEL_ISR; /* ... can't DELETE from an ISR */
245 return (pevent);
C51 COMPILER V8.08 OS_MUTEX 08/04/2008 21:49:52 PAGE 6
246 }
247 OS_ENTER_CRITICAL();
248 if (pevent->OSEventGrp != 0) { /* See if any tasks waiting on mutex */
249 tasks_waiting = TRUE; /* Yes */
250 } else {
251 tasks_waiting = FALSE; /* No */
252 }
253 switch (opt) {
254 case OS_DEL_NO_PEND: /* Delete mutex only if no task waiting */
255 if (tasks_waiting == FALSE) {
256 #if OS_EVENT_NAME_SIZE > 1
257 pevent->OSEventName[0] = '?'; /* Unknown name */
258 pevent->OSEventName[1] = OS_ASCII_NUL;
259 #endif
260 pip = (INT8U)(pevent->OSEventCnt >> 8);
261 OSTCBPrioTbl[pip] = (OS_TCB *)0; /* Free up the PIP */
262 pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
263 pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block to free list */
264 pevent->OSEventCnt = 0;
265 OSEventFreeList = pevent;
266 OS_EXIT_CRITICAL();
267 *err = OS_NO_ERR;
268 pevent_return = (OS_EVENT *)0; /* Mutex has been deleted */
269 } else {
270 OS_EXIT_CRITICAL();
271 *err = OS_ERR_TASK_WAITING;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -