📄 os_mutex.ls1
字号:
180 ; * OS_ERR_CREATE_ISR if you attempted to create a MUTEX fr
om an ISR
181 ; * OS_PRIO_EXIST if a task at the priority inheritance
priority
182 ; * already exist.
183 ; * OS_ERR_PEVENT_NULL No more event control blocks availabl
e.
184 ; * OS_PRIO_INVALID if the priority you specify is higher
that the
185 ; * maximum allowed (i.e. > OS_LOWEST_PRI
O)
186 ; *
187 ; * Returns : != (void *)0 is a pointer to the event control clock (OS_EVENT) associate
d with the
188 ; * created mutex.
189 ; * == (void *)0 if an error is detected.
190 ; *
191 ; * Note(s) : 1) The LEAST significant 8 bits of '.OSEventCnt' are used to hold the prio
rity number
192 ; * of the task owning the mutex or 0xFF if no task owns the mutex.
193 ; * 2) The MOST significant 8 bits of '.OSEventCnt' are used to hold the prio
rity number
194 ; * to use to reduce priority inversion.
195 ; *****************************************************************************************
****************
196 ; */
197 ;
198 ; OS_EVENT *OSMutexCreate (INT8U prio, INT8U *err)
199 ; {
200 ;
201 ; OS_EVENT *pevent;
202 ;
203 ;
204 ; if (OSIntNesting > 0) { /* See if called from ISR ...
*/
205 ; *err = OS_ERR_CREATE_ISR; /* ... can't CREATE mutex from
an ISR */
206 ; return ((OS_EVENT *)0);
207 ; }
208 ; #if OS_ARG_CHK_EN > 0
209 ; if (prio >= OS_LOWEST_PRIO) { /* Validate PIP
*/
210 ; *err = OS_PRIO_INVALID;
211 ; return ((OS_EVENT *)0);
212 ; }
213 ; #endif
214 ; OS_ENTER_CRITICAL();
215 ; if (OSTCBPrioTbl[prio] != (OS_TCB *)0) { /* Mutex priority must not alr
eady exist */
216 ; OS_EXIT_CRITICAL(); /* Task already exist at prior
ity ... */
A51 MACRO ASSEMBLER OS_MUTEX 08/08/2005 11:36:49 PAGE 5
217 ; *err = OS_PRIO_EXIST; /* ... inheritance priority
*/
218 ; return ((OS_EVENT *)0);
219 ; }
220 ; OSTCBPrioTbl[prio] = (OS_TCB *)1; /* Reserve the table entry
*/
221 ; pevent = OSEventFreeList; /* Get next free event control
block */
222 ; if (pevent == (OS_EVENT *)0) { /* See if an ECB was available
*/
223 ; OSTCBPrioTbl[prio] = (OS_TCB *)0; /* No, Release the table entry
*/
224 ; OS_EXIT_CRITICAL();
225 ; *err = OS_ERR_PEVENT_NULL; /* No more event control block
s */
226 ; return (pevent);
227 ; }
228 ; OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr; /* Adjust the free l
ist */
229 ; OS_EXIT_CRITICAL();
230 ; pevent->OSEventType = OS_EVENT_TYPE_MUTEX;
231 ; pevent->OSEventCnt = (prio << 8) | OS_MUTEX_AVAILABLE;/* Resource is available
*/
232 ; pevent->OSEventPtr = (void *)0; /* No task owning the mutex
*/
233 ; OS_EventWaitListInit(pevent);
234 ; *err = OS_NO_ERR;
235 ; return (pevent);
236 ; }
237 ;
238 ; /*$PAGE*/
239 ; /*
240 ; *****************************************************************************************
****************
241 ; * DELETE A MUTEX
242 ; *
243 ; * Description: This function deletes a mutual exclusion semaphore and readies all tasks p
ending on the it.
244 ; *
245 ; * Arguments : pevent is a pointer to the event control block associated with the
desired mutex.
246 ; *
247 ; * opt determines delete options as follows:
248 ; * opt == OS_DEL_NO_PEND Delete mutex ONLY if no task pending
249 ; * opt == OS_DEL_ALWAYS Deletes the mutex even if tasks are
waiting.
250 ; * In this case, all the tasks pending
will be readied.
251 ; *
252 ; * err is a pointer to an error code that can contain one of the fo
llowing values:
253 ; * OS_NO_ERR The call was successful and the mute
x was deleted
254 ; * OS_ERR_DEL_ISR If you attempted to delete the MUTEX
from an ISR
255 ; * OS_ERR_INVALID_OPT An invalid option was specified
256 ; * OS_ERR_TASK_WAITING One or more tasks were waiting on th
e mutex
257 ; * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a mu
tex
258 ; * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
259 ; *
260 ; * Returns : pevent upon error
261 ; * (OS_EVENT *)0 if the mutex was successfully deleted.
262 ; *
263 ; * Note(s) : 1) This function must be used with care. Tasks that would normally expect
A51 MACRO ASSEMBLER OS_MUTEX 08/08/2005 11:36:49 PAGE 6
the presence of
264 ; * the mutex MUST check the return code of OSMutexPend().
265 ; * 2) This call can potentially disable interrupts for a long time. The inte
rrupt disable
266 ; * time is directly proportional to the number of tasks waiting on the mut
ex.
267 ; * 3) Because ALL tasks pending on the mutex will be readied, you MUST be car
eful because the
268 ; * resource(s) will no longer be guarded by the mutex.
269 ; *****************************************************************************************
****************
270 ; */
271 ;
272 ; #if OS_MUTEX_DEL_EN
273 ; OS_EVENT *OSMutexDel (OS_EVENT *pevent, INT8U opt, INT8U *err)
274 ; {
275 ;
276 ; BOOLEAN tasks_waiting;
277 ; INT8U pip;
278 ;
279 ;
280 ; if (OSIntNesting > 0) { /* See if called from ISR ...
*/
281 ; *err = OS_ERR_DEL_ISR; /* ... can't DELETE from an IS
R */
282 ; return (pevent);
283 ; }
284 ; #if OS_ARG_CHK_EN > 0
285 ; if (pevent == (OS_EVENT *)0) { /* Validate 'pevent'
*/
286 ; *err = OS_ERR_PEVENT_NULL;
287 ; return ((OS_EVENT *)0);
288 ; }
289 ; if (pevent->OSEventType != OS_EVENT_TYPE_MUTEX) { /* Validate event block type
*/
290 ; *err = OS_ERR_EVENT_TYPE;
291 ; return (pevent);
292 ; }
293 ; #endif
294 ; OS_ENTER_CRITICAL();
295 ; if (pevent->OSEventGrp != 0x00) { /* See if any tasks waiting on
mutex */
296 ; tasks_waiting = TRUE; /* Yes
*/
297 ; } else {
298 ; tasks_waiting = FALSE; /* No
*/
299 ; }
300 ; switch (opt) {
301 ; case OS_DEL_NO_PEND: /* Delete mutex only if no tas
k waiting */
302 ; if (tasks_waiting == FALSE) {
303 ; pip = (INT8U)(pevent->OSEventCnt >> 8);
304 ; OSTCBPrioTbl[pip] = (OS_TCB *)0; /* Free up the PIP
*/
305 ; pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
306 ; pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block
to free list */
307 ; OSEventFreeList = pevent;
308 ; OS_EXIT_CRITICAL();
309 ; *err = OS_NO_ERR;
310 ; return ((OS_EVENT *)0); /* Mutex has been deleted
*/
311 ; } else {
312 ; OS_EXIT_CRITICAL();
313 ; *err = OS_ERR_TASK_WAITING;
A51 MACRO ASSEMBLER OS_MUTEX 08/08/2005 11:36:49 PAGE 7
314 ; return (pevent);
315 ; }
316 ;
317 ; case OS_DEL_ALWAYS: /* Always delete the mutex
*/
318 ; while (pevent->OSEventGrp != 0x00) { /* Ready ALL tasks waiting for
mutex */
319 ; OS_EventTaskRdy(pevent, (void *)0, OS_STAT_MUTEX);
320 ; }
321 ; pip = (INT8U)(pevent->OSEventCnt >> 8);
322 ; OSTCBPrioTbl[pip] = (OS_TCB *)0; /* Free up the PIP
*/
323 ; pevent->OSEventType = OS_EVENT_TYPE_UNUSED;
324 ; pevent->OSEventPtr = OSEventFreeList; /* Return Event Control Block
to free list */
325 ; OSEventFreeList = pevent; /* Get next free event control
block */
326 ; OS_EXIT_CRITICAL();
327 ; if (tasks_waiting == TRUE) { /* Reschedule only if task(s)
were waiting */
328 ; OS_Sched(); /* Find highest priority task
ready to run */
329 ; }
330 ; *err = OS_NO_ERR;
331 ; return ((OS_EVENT *)0); /* Mutex has been deleted
*/
332 ;
333 ; default:
334 ; OS_EXIT_CRITICAL();
335 ; *err = OS_ERR_INVALID_OPT;
336 ; return (pevent);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -