📄 os_q.lst
字号:
116 * void *MessageStorage[size]
117 *
118 * size is the number of elements in the storage area
119 *
120 * Returns : != (OS_EVENT *)0 is a pointer to the event control clock (OS_EVENT) associated with the
121 * created queue
122 * == (OS_EVENT *)0 if no event control blocks were available or an error was detected
123 *********************************************************************************************************
124 */
125
\ In section .text, align 2, keep-with-next
126 OS_EVENT *OSQCreate (void **start,
127 INT16U size)
128 {
\ OSQCreate:
\ 00000000 2DE9F041 PUSH {R4-R8,LR}
\ 00000004 0400 MOVS R4,R0
\ 00000006 0D00 MOVS R5,R1
129 OS_EVENT *pevent;
130 OS_Q *pq;
131 #if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
132 OS_CPU_SR cpu_sr = 0u;
\ 00000008 5FF00008 MOVS R8,#+0
133 #endif
134
135
136
137 #ifdef OS_SAFETY_CRITICAL_IEC61508
138 if (OSSafetyCriticalStartFlag == OS_TRUE) {
139 OS_SAFETY_CRITICAL_EXCEPTION();
140 return ((OS_EVENT *)0);
141 }
142 #endif
143
144 if (OSIntNesting > 0u) { /* See if called from ISR ... */
\ 0000000C ........ LDR.W R0,??DataTable4
\ 00000010 0078 LDRB R0,[R0, #+0]
\ 00000012 0028 CMP R0,#+0
\ 00000014 01D0 BEQ.N ??OSQCreate_0
145 return ((OS_EVENT *)0); /* ... can't CREATE from an ISR */
\ 00000016 0020 MOVS R0,#+0
\ 00000018 4CE0 B.N ??OSQCreate_1
146 }
147 OS_ENTER_CRITICAL();
\ ??OSQCreate_0:
\ 0000001A ........ BL OS_CPU_SR_Save
\ 0000001E 8046 MOV R8,R0
148 pevent = OSEventFreeList; /* Get next free event control block */
\ 00000020 ........ LDR.W R0,??DataTable4_1
\ 00000024 0068 LDR R0,[R0, #+0]
\ 00000026 0600 MOVS R6,R0
149 if (OSEventFreeList != (OS_EVENT *)0) { /* See if pool of free ECB pool was empty */
\ 00000028 ........ LDR.W R0,??DataTable4_1
\ 0000002C 0068 LDR R0,[R0, #+0]
\ 0000002E 0028 CMP R0,#+0
\ 00000030 06D0 BEQ.N ??OSQCreate_2
150 OSEventFreeList = (OS_EVENT *)OSEventFreeList->OSEventPtr;
\ 00000032 ........ LDR.W R0,??DataTable4_1
\ 00000036 0068 LDR R0,[R0, #+0]
\ 00000038 4068 LDR R0,[R0, #+4]
\ 0000003A ........ LDR.W R1,??DataTable4_1
\ 0000003E 0860 STR R0,[R1, #+0]
151 }
152 OS_EXIT_CRITICAL();
\ ??OSQCreate_2:
\ 00000040 4046 MOV R0,R8
\ 00000042 ........ BL OS_CPU_SR_Restore
153 if (pevent != (OS_EVENT *)0) { /* See if we have an event control block */
\ 00000046 002E CMP R6,#+0
\ 00000048 33D0 BEQ.N ??OSQCreate_3
154 OS_ENTER_CRITICAL();
\ 0000004A ........ BL OS_CPU_SR_Save
\ 0000004E 8046 MOV R8,R0
155 pq = OSQFreeList; /* Get a free queue control block */
\ 00000050 ........ LDR.W R0,??DataTable4_2
\ 00000054 0068 LDR R0,[R0, #+0]
\ 00000056 0700 MOVS R7,R0
156 if (pq != (OS_Q *)0) { /* Were we able to get a queue control block ? */
\ 00000058 002F CMP R7,#+0
\ 0000005A 1ED0 BEQ.N ??OSQCreate_4
157 OSQFreeList = OSQFreeList->OSQPtr; /* Yes, Adjust free list pointer to next free*/
\ 0000005C ........ LDR.W R0,??DataTable4_2
\ 00000060 ........ LDR.W R1,??DataTable4_2
\ 00000064 0968 LDR R1,[R1, #+0]
\ 00000066 0968 LDR R1,[R1, #+0]
\ 00000068 0160 STR R1,[R0, #+0]
158 OS_EXIT_CRITICAL();
\ 0000006A 4046 MOV R0,R8
\ 0000006C ........ BL OS_CPU_SR_Restore
159 pq->OSQStart = start; /* Initialize the queue */
\ 00000070 7C60 STR R4,[R7, #+4]
160 pq->OSQEnd = &start[size];
\ 00000072 ADB2 UXTH R5,R5 ;; ZeroExt R5,R5,#+16,#+16
\ 00000074 14EB8500 ADDS R0,R4,R5, LSL #+2
\ 00000078 B860 STR R0,[R7, #+8]
161 pq->OSQIn = start;
\ 0000007A FC60 STR R4,[R7, #+12]
162 pq->OSQOut = start;
\ 0000007C 3C61 STR R4,[R7, #+16]
163 pq->OSQSize = size;
\ 0000007E BD82 STRH R5,[R7, #+20]
164 pq->OSQEntries = 0u;
\ 00000080 0020 MOVS R0,#+0
\ 00000082 F882 STRH R0,[R7, #+22]
165 pevent->OSEventType = OS_EVENT_TYPE_Q;
\ 00000084 0220 MOVS R0,#+2
\ 00000086 3070 STRB R0,[R6, #+0]
166 pevent->OSEventCnt = 0u;
\ 00000088 0020 MOVS R0,#+0
\ 0000008A 3081 STRH R0,[R6, #+8]
167 pevent->OSEventPtr = pq;
\ 0000008C 7760 STR R7,[R6, #+4]
168 #if OS_EVENT_NAME_EN > 0u
169 pevent->OSEventName = (INT8U *)(void *)"?";
\ 0000008E .... ADR.N R0,??DataTable3 ;; "\?"
\ 00000090 7061 STR R0,[R6, #+20]
170 #endif
171 OS_EventWaitListInit(pevent); /* Initalize the wait list */
\ 00000092 3000 MOVS R0,R6
\ 00000094 ........ BL OS_EventWaitListInit
\ 00000098 0BE0 B.N ??OSQCreate_3
172 } else {
173 pevent->OSEventPtr = (void *)OSEventFreeList; /* No, Return event control block on error */
\ ??OSQCreate_4:
\ 0000009A ........ LDR.W R0,??DataTable4_1
\ 0000009E 0068 LDR R0,[R0, #+0]
\ 000000A0 7060 STR R0,[R6, #+4]
174 OSEventFreeList = pevent;
\ 000000A2 ........ LDR.W R0,??DataTable4_1
\ 000000A6 0660 STR R6,[R0, #+0]
175 OS_EXIT_CRITICAL();
\ 000000A8 4046 MOV R0,R8
\ 000000AA ........ BL OS_CPU_SR_Restore
176 pevent = (OS_EVENT *)0;
\ 000000AE 0020 MOVS R0,#+0
\ 000000B0 0600 MOVS R6,R0
177 }
178 }
179 return (pevent);
\ ??OSQCreate_3:
\ 000000B2 3000 MOVS R0,R6
\ ??OSQCreate_1:
\ 000000B4 BDE8F081 POP {R4-R8,PC} ;; return
180 }
181 /*$PAGE*/
182 /*
183 *********************************************************************************************************
184 * DELETE A MESSAGE QUEUE
185 *
186 * Description: This function deletes a message queue and readies all tasks pending on the queue.
187 *
188 * Arguments : pevent is a pointer to the event control block associated with the desired
189 * queue.
190 *
191 * opt determines delete options as follows:
192 * opt == OS_DEL_NO_PEND Delete the queue ONLY if no task pending
193 * opt == OS_DEL_ALWAYS Deletes the queue even if tasks are waiting.
194 * In this case, all the tasks pending will be readied.
195 *
196 * perr is a pointer to an error code that can contain one of the following values:
197 * OS_ERR_NONE The call was successful and the queue was deleted
198 * OS_ERR_DEL_ISR If you tried to delete the queue from an ISR
199 * OS_ERR_INVALID_OPT An invalid option was specified
200 * OS_ERR_TASK_WAITING One or more tasks were waiting on the queue
201 * OS_ERR_EVENT_TYPE If you didn't pass a pointer to a queue
202 * OS_ERR_PEVENT_NULL If 'pevent' is a NULL pointer.
203 *
204 * Returns : pevent upon error
205 * (OS_EVENT *)0 if the queue was successfully deleted.
206 *
207 * Note(s) : 1) This function must be used with care. Tasks that would normally expect the presence of
208 * the queue MUST check the return code of OSQPend().
209 * 2) OSQAccept() callers will not know that the intended queue has been deleted unless
210 * they check 'pevent' to see that it's a NULL pointer.
211 * 3) 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 queue.
213 * 4) Because ALL tasks pending on the queue will be readied, you MUST be careful in
214 * applications where the queue is used for mutual exclusion because the resource(s)
215 * will no longer be guarded by the queue.
216 * 5) If the storage for the message queue was allocated dynamically (i.e. using a malloc()
217 * type call) then your application MUST release the memory storage by call the counterpart
218 * call of the dynamic allocation scheme used. If the queue storage was created statically
219 * then, the storage can be reused.
220 *********************************************************************************************************
221 */
222
223 #if OS_Q_DEL_EN > 0u
\ In section .text, align 2, keep-with-next
224 OS_EVENT *OSQDel (OS_EVENT *pevent,
225 INT8U opt,
226 INT8U *perr)
227 {
\ OSQDel:
\ 00000000 2DE9F047 PUSH {R4-R10,LR}
\ 00000004 0400 MOVS R4,R0
\ 00000006 0D00 MOVS R5,R1
\ 00000008 1600 MOVS R6,R2
228 BOOLEAN tasks_waiting;
229 OS_EVENT *pevent_return;
230 OS_Q *pq;
231 #if OS_CRITICAL_METHOD == 3u /* Allocate storage for CPU status register */
232 OS_CPU_SR cpu_sr = 0u;
\ 0000000A 5FF0000A MOVS R10,#+0
233 #endif
234
235
236
237 #ifdef OS_SAFETY_CRITICAL
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -