📄 os_sem.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: * SEMAPHORE MANAGEMENT
6: *
7: * (c) Copyright 1992-1998, Jean J. Labrosse, Plantation, FL
8: * All Rights Reserved
9: *
10: * V2.00
11: *
12: * File : OS_SEM.C
13: * By : Jean J. Labrosse
14: *********************************************************************************************************
15: */
16:
17:
18: #include "includes.h"
19:
20:
21: #if OS_SEM_EN
22: /*
23: *********************************************************************************************************
24: * ACCEPT SEMAPHORE
25: *
26: * Description: This function checks the semaphore to see if a resource is available or, if an event
27: * occurred. Unlike OSSemPend(), OSSemAccept() does not suspend the calling task if the
28: * resource is not available or the event did not occur.
29: *
30: * Arguments : pevent is a pointer to the event control block
31: *
32: * Returns : > 0 if the resource is available or the event did not occur the semaphore is
33: * decremented to obtain the resource.
34: * == 0 if the resource is not available or the event did not occur or,
35: * you didn't pass a pointer to a semaphore
36: *********************************************************************************************************
37: */
38:
39: INT16U OSSemAccept (OS_EVENT *pevent)
40: {
41: INT16U cnt;
42:
43:
44: OS_ENTER_CRITICAL();
45: if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */
46: OS_EXIT_CRITICAL();
47: return (0);
48: }
49: cnt = pevent->OSEventCnt;
50: if (cnt > 0) { /* See if resource is available */
51: pevent->OSEventCnt--; /* Yes, decrement semaphore and notify caller */
52: }
53: OS_EXIT_CRITICAL();
54: return (cnt); /* Return semaphore count */
55: }
56:
57: /*$PAGE*/
58: /*
59: *********************************************************************************************************
60: * CREATE A SEMAPHORE
61: *
62: * Description: This function creates a semaphore.
63: *
64: * Arguments : cnt is the initial value for the semaphore. If the value is 0, no resource is
65: * available (or no event has occurred). You initialize the semaphore to a
66: * non-zero value to specify how many resources are available (e.g. if you have
67: * 10 resources, you would initialize the semaphore to 10).
68: *
69: * Returns : != (void *)0 is a pointer to the event control clock (OS_EVENT) associated with the
70: * created semaphore
71: * == (void *)0 if no event control blocks were available
72: *********************************************************************************************************
73: */
74:
75: OS_EVENT *OSSemCreate (INT16U cnt)
76: {
77: OS_EVENT *pevent;
78:
79:
80: OS_ENTER_CRITICAL();
81: pevent = OSEventFreeList; /* Get next free event control block */
82: if (OSEventFreeList != (OS_EVENT *)0) { /* See if pool of free ECB pool was empty */
83: OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;
84: }
85: OS_EXIT_CRITICAL();
86: if (pevent != (OS_EVENT *)0) { /* Get an event control block */
87: pevent->OSEventType = OS_EVENT_TYPE_SEM;
88: pevent->OSEventCnt = cnt; /* Set semaphore value */
89: OSEventWaitListInit(pevent);
90: }
91: return (pevent);
92: }
93:
94: /*$PAGE*/
95: /*
96: *********************************************************************************************************
97: * PEND ON SEMAPHORE
98: *
99: * Description: This function waits for a semaphore.
100: *
101: * Arguments : pevent is a pointer to the event control block associated with the desired
102: * semaphore.
103: *
104: * timeout is an optional timeout period (in clock ticks). If non-zero, your task will
105: * wait for the resource up to the amount of time specified by this argument.
106: * If you specify 0, however, your task will wait forever at the specified
107: * semaphore or, until the resource becomes available (or the event occurs).
108: *
109: * err is a pointer to where an error message will be deposited. Possible error
110: * messages are:
111: *
112: * OS_NO_ERR The call was successful and your task owns the resource
113: * or, the event you are waiting for occurred.
114: * OS_TIMEOUT The semaphore was not received within the specified
115: * timeout.
116: * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore.
117: * OS_ERR_PEND_ISR If you called this function from an ISR and the result
118: * would lead to a suspension.
119: *
120: * Returns : none
121: *********************************************************************************************************
122: */
123:
124: void OSSemPend (OS_EVENT *pevent, INT16U timeout, INT8U *err)
125: {
126: OS_ENTER_CRITICAL();
127: if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */
128: OS_EXIT_CRITICAL();
129: *err = OS_ERR_EVENT_TYPE;
130: }
131: if (pevent->OSEventCnt > 0) { /* If sem. is positive, resource available ... */
132: pevent->OSEventCnt--; /* ... decrement semaphore only if positive. */
133: OS_EXIT_CRITICAL();
134: *err = OS_NO_ERR;
135: } else if (OSIntNesting > 0) { /* See if called from ISR ... */
136: OS_EXIT_CRITICAL(); /* ... can't PEND from an ISR */
137: *err = OS_ERR_PEND_ISR;
138: } else { /* Otherwise, must wait until event occurs */
139: OSTCBCur->OSTCBStat |= OS_STAT_SEM; /* Resource not available, pend on semaphore */
140: OSTCBCur->OSTCBDly = timeout; /* Store pend timeout in TCB */
141: OSEventTaskWait(pevent); /* Suspend task until event or timeout occurs */
142: OS_EXIT_CRITICAL();
143: OSSched(); /* Find next highest priority task ready */
144: OS_ENTER_CRITICAL();
145: if (OSTCBCur->OSTCBStat & OS_STAT_SEM) { /* Must have timed out if still waiting for event*/
146: OSEventTO(pevent);
147: OS_EXIT_CRITICAL();
148: *err = OS_TIMEOUT; /* Indicate that didn't get event within TO */
149: } else {
150: OSTCBCur->OSTCBEventPtr = (OS_EVENT *)0;
151: OS_EXIT_CRITICAL();
152: *err = OS_NO_ERR;
153: }
154: }
155: }
156: /*$PAGE*/
157: /*
158: *********************************************************************************************************
159: * POST TO A SEMAPHORE
160: *
161: * Description: This function signals a semaphore
162: *
163: * Arguments : pevent is a pointer to the event control block associated with the desired
164: * semaphore.
165: *
166: * Returns : OS_NO_ERR The call was successful and the semaphore was signaled.
167: * OS_SEM_OVF If the semaphore count exceeded its limit. In other words, you have
168: * signalled the semaphore more often than you waited on it with either
169: * OSSemAccept() or OSSemPend().
170: * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a semaphore
171: *********************************************************************************************************
172: */
173:
174: INT8U OSSemPost (OS_EVENT *pevent)
175: {
176: OS_ENTER_CRITICAL();
177: if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */
178: OS_EXIT_CRITICAL();
179: return (OS_ERR_EVENT_TYPE);
180: }
181: if (pevent->OSEventGrp) { /* See if any task waiting for semaphore */
182: OSEventTaskRdy(pevent, (void *)0, OS_STAT_SEM); /* Ready highest prio task waiting on event */
183: OS_EXIT_CRITICAL();
184: OSSched(); /* Find highest priority task ready to run */
185: return (OS_NO_ERR);
186: } else {
187: if (pevent->OSEventCnt < 65535) { /* Make sure semaphore will not overflow */
188: pevent->OSEventCnt++; /* Increment semaphore count to register event */
189: OS_EXIT_CRITICAL();
190: return (OS_NO_ERR);
191: } else { /* Semaphore value has reached its maximum */
192: OS_EXIT_CRITICAL();
193: return (OS_SEM_OVF);
194: }
195: }
196: }
197: /*
198: *********************************************************************************************************
199: * QUERY A SEMAPHORE
200: *
201: * Description: This function obtains information about a semaphore
202: *
203: * Arguments : pevent is a pointer to the event control block associated with the desired
204: * semaphore
205: *
206: * pdata is a pointer to a structure that will contain information about the
207: * semaphore.
208: *
209: * Returns : OS_NO_ERR The call was successful and the message was sent
210: * OS_ERR_EVENT_TYPE If you are attempting to obtain data from a non semaphore.
211: *********************************************************************************************************
212: */
213:
214: INT8U OSSemQuery (OS_EVENT *pevent, OS_SEM_DATA *pdata)
215: {
216: INT8U i;
217: INT8U *psrc;
218: INT8U *pdest;
219:
220:
221: OS_ENTER_CRITICAL();
222: if (pevent->OSEventType != OS_EVENT_TYPE_SEM) { /* Validate event block type */
223: OS_EXIT_CRITICAL();
224: return (OS_ERR_EVENT_TYPE);
225: }
226: pdata->OSEventGrp = pevent->OSEventGrp; /* Copy message mailbox wait list */
227: psrc = &pevent->OSEventTbl[0];
228: pdest = &pdata->OSEventTbl[0];
229: for (i = 0; i < OS_EVENT_TBL_SIZE; i++) {
230: *pdest++ = *psrc++;
231: }
232: pdata->OSCnt = pevent->OSEventCnt; /* Get semaphore count */
233: OS_EXIT_CRITICAL();
234: return (OS_NO_ERR);
235: }
236: #endif
237:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -