📄 queue.lst
字号:
\ 000028 1C53 ADD.W #0x1, R12
\ 00002A 094C MOV.W R12, R9
196
197 pxNewQueue->pcHead = ( signed portCHAR * ) pvPortMalloc( xQueueSizeInBytes );
\ 00002C 0C49 MOV.W R9, R12
\ 00002E B012.... CALL #pvPortMalloc
\ 000032 884C0000 MOV.W R12, 0(R8)
198 if( pxNewQueue->pcHead != NULL )
\ 000036 88930000 CMP.W #0x0, 0(R8)
\ 00003A 2824 JEQ ??xQueueCreate_1
199 {
200 /* Initialise the queue members as described above where the
201 queue type is defined. */
202 pxNewQueue->pcTail = pxNewQueue->pcHead + ( uxQueueLength * uxItemSize );
\ 00003C 2648 MOV.W @R8, R6
\ 00003E 0C4A MOV.W R10, R12
\ 000040 0E4B MOV.W R11, R14
\ 000042 B012.... CALL #?Mul16
\ 000046 065C ADD.W R12, R6
\ 000048 88460200 MOV.W R6, 0x2(R8)
203 pxNewQueue->uxMessagesWaiting = 0;
\ 00004C 88431C00 MOV.W #0x0, 0x1c(R8)
204 pxNewQueue->pcWriteTo = pxNewQueue->pcHead;
\ 000050 A8480400 MOV.W @R8, 0x4(R8)
205 pxNewQueue->pcReadFrom = pxNewQueue->pcHead + ( ( uxQueueLength - 1 ) * uxItemSize );
\ 000054 2648 MOV.W @R8, R6
\ 000056 0C4A MOV.W R10, R12
\ 000058 3C53 ADD.W #0xffff, R12
\ 00005A 0E4B MOV.W R11, R14
\ 00005C B012.... CALL #?Mul16
\ 000060 065C ADD.W R12, R6
\ 000062 88460600 MOV.W R6, 0x6(R8)
206 pxNewQueue->uxLength = uxQueueLength;
\ 000066 884A1E00 MOV.W R10, 0x1e(R8)
207 pxNewQueue->uxItemSize = uxItemSize;
\ 00006A 884B2000 MOV.W R11, 0x20(R8)
208 pxNewQueue->xRxLock = queueUNLOCKED;
\ 00006E B8432200 MOV.W #0xffff, 0x22(R8)
209 pxNewQueue->xTxLock = queueUNLOCKED;
\ 000072 B8432400 MOV.W #0xffff, 0x24(R8)
210
211 /* Likewise ensure the event queues start with the correct state. */
212 vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) );
\ 000076 0C48 MOV.W R8, R12
\ 000078 3C52 ADD.W #0x8, R12
\ 00007A B012.... CALL #vListInitialise
213 vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) );
\ 00007E 0C48 MOV.W R8, R12
\ 000080 3C501200 ADD.W #0x12, R12
\ 000084 B012.... CALL #vListInitialise
214
215 return pxNewQueue;
\ 000088 0C48 MOV.W R8, R12
\ 00008A 043C JMP ??xQueueCreate_2
216 }
217 else
218 {
219 vPortFree( pxNewQueue );
\ ??xQueueCreate_1:
\ 00008C 0C48 MOV.W R8, R12
\ 00008E B012.... CALL #vPortFree
220 }
221 }
222 }
223
224 /* Will only reach here if we could not allocate enough memory or no memory
225 was required. */
226 return NULL;
\ ??xQueueCreate_0:
\ 000092 0C43 MOV.W #0x0, R12
\ ??xQueueCreate_2:
\ 000094 3040.... BR #?Epilogue5
227 }
228 /*-----------------------------------------------------------*/
229
\ In segment CODE, align 2
230 signed portBASE_TYPE xQueueSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait )
\ xQueueSend:
231 {
\ 000000 0A12 PUSH.W R10
\ 000002 0B12 PUSH.W R11
\ 000004 0812 PUSH.W R8
\ 000006 0912 PUSH.W R9
\ 000008 094C MOV.W R12, R9
\ 00000A 0A4E MOV.W R14, R10
\ 00000C 1B410A00 MOV.W 0xa(SP), R11
232 signed portBASE_TYPE xReturn;
233
234 /* Make sure other tasks do not access the queue. */
235 vTaskSuspendAll();
\ 000010 B012.... CALL #vTaskSuspendAll
236
237 /* It is important that this is the only thread/ISR that modifies the
238 ready or delayed lists until xTaskResumeAll() is called. Places where
239 the ready/delayed lists are modified include:
240
241 + vTaskDelay() - Nothing can call vTaskDelay as the scheduler is
242 suspended, vTaskDelay() cannot be called from an ISR.
243 + vTaskPrioritySet() - Has a critical section around the access.
244 + vTaskSwitchContext() - This will not get executed while the scheduler
245 is suspended.
246 + prvCheckDelayedTasks() - This will not get executed while the
247 scheduler is suspended.
248 + xTaskCreate() - Has a critical section around the access.
249 + vTaskResume() - Has a critical section around the access.
250 + xTaskResumeAll() - Has a critical section around the access.
251 + xTaskRemoveFromEventList - Checks to see if the scheduler is
252 suspended. If so then the TCB being removed from the event is
253 removed from the event and added to the xPendingReadyList.
254 */
255
256 /* Make sure interrupts do not access the queue event list. */
257 prvLockQueue( pxQueue );
\ 000014 32C2 DINT
\ 000016 0343 NOP
\ 000018 9253.... ADD.W #0x1, &usCriticalNesting
\ 00001C 0F49 MOV.W R9, R15
\ 00001E 9F532200 ADD.W #0x1, 0x22(R15)
\ 000022 0F49 MOV.W R9, R15
\ 000024 9F532400 ADD.W #0x1, 0x24(R15)
\ 000028 8293.... CMP.W #0x0, &usCriticalNesting
\ 00002C 0624 JEQ ??xQueueSend_0
\ 00002E B253.... ADD.W #0xffff, &usCriticalNesting
\ 000032 8293.... CMP.W #0x0, &usCriticalNesting
\ 000036 0120 JNE ??xQueueSend_0
\ 000038 32D2 EINT
258
259 /* It is important that interrupts to not access the event list of the
260 queue being modified here. Places where the event list is modified
261 include:
262
263 + xQueueSendFromISR(). This checks the lock on the queue to see if
264 it has access. If the queue is locked then the Tx lock count is
265 incremented to signify that a task waiting for data can be made ready
266 once the queue lock is removed. If the queue is not locked then
267 a task can be moved from the event list, but will not be removed
268 from the delayed list or placed in the ready list until the scheduler
269 is unlocked.
270
271 + xQueueReceiveFromISR(). As per xQueueSendFromISR().
272 */
273
274 /* If the queue is already full we may have to block. */
275 if( prvIsQueueFull( pxQueue ) )
\ ??xQueueSend_0:
\ 00003A 0C49 MOV.W R9, R12
\ 00003C B012.... CALL #prvIsQueueFull
\ 000040 0C93 CMP.W #0x0, R12
\ 000042 3224 JEQ ??xQueueSend_1
276 {
277 /* The queue is full - do we want to block or just leave without
278 posting? */
279 if( xTicksToWait > ( portTickType ) 0 )
\ 000044 0B93 CMP.W #0x0, R11
\ 000046 3024 JEQ ??xQueueSend_1
280 {
281 /* We are going to place ourselves on the xTasksWaitingToSend event
282 list, and will get woken should the delay expire, or space become
283 available on the queue.
284
285 As detailed above we do not require mutual exclusion on the event
286 list as nothing else can modify it or the ready lists while we
287 have the scheduler suspended and queue locked.
288
289 It is possible that an ISR has removed data from the queue since we
290 checked if any was available. If this is the case then the data
291 will have been copied from the queue, and the queue variables
292 updated, but the event list will not yet have been checked to see if
293 anything is waiting as the queue is locked. */
294 vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );
\ 000048 0E4B MOV.W R11, R14
\ 00004A 0C49 MOV.W R9, R12
\ 00004C 3C52 ADD.W #0x8, R12
\ 00004E B012.... CALL #vTaskPlaceOnEventList
295
296 /* Force a context switch now as we are blocked. We can do
297 this from within a critical section as the task we are
298 switching to has its own context. When we return here (i.e. we
299 unblock) we will leave the critical section as normal.
300
301 It is possible that an ISR has caused an event on an unrelated and
302 unlocked queue. If this was the case then the event list for that
303 queue will have been updated but the ready lists left unchanged -
304 instead the readied task will have been added to the pending ready
305 list. */
306 taskENTER_CRITICAL();
\ 000052 32C2 DINT
\ 000054 0343 NOP
\ 000056 9253.... ADD.W #0x1, &usCriticalNesting
307 {
308 /* We can safely unlock the queue and scheduler here as
309 interrupts are disabled. We must not yield with anything
310 locked, but we can yield from within a critical section.
311
312 Tasks that have been placed on the pending ready list cannot
313 be tasks that are waiting for events on this queue. See
314 in comment xTaskRemoveFromEventList(). */
315 prvUnlockQueue( pxQueue );
\ 00005A 0C49 MOV.W R9, R12
\ 00005C B012.... CALL #prvUnlockQueue
316
317 /* Resuming the scheduler may cause a yield. If so then there
318 is no point yielding again here. */
319 if( !xTaskResumeAll() )
\ 000060 B012.... CALL #xTaskResumeAll
\ 000064 0C93 CMP.W #0x0, R12
\ 000066 0220 JNE ??xQueueSend_2
320 {
321 taskYIELD();
\ 000068 B012.... CALL #vPortYield
322 }
323
324 /* Before leaving the critical section we have to ensure
325 exclusive access again. */
326 vTaskSuspendAll();
\ ??xQueueSend_2:
\ 00006C B012.... CALL #vTaskSuspendAll
327 prvLockQueue( pxQueue );
\ 000070 32C2 DINT
\ 000072 0343 NOP
\ 000074 9253.... ADD.W #0x1, &usCriticalNesting
\ 000078 0F49 MOV.W R9, R15
\ 00007A 9F532200 ADD.W #0x1, 0x22(R15)
\ 00007E 0F49 MOV.W R9, R15
\ 000080 9F532400 ADD.W #0x1, 0x24(R15)
\ 000084 8293.... CMP.W #0x0, &usCriticalNesting
\ 000088 0624 JEQ ??xQueueSend_3
\ 00008A B253.... ADD.W #0xffff, &usCriticalNesting
\ 00008E 8293.... CMP.W #0x0, &usCriticalNesting
\ 000092 0120 JNE ??xQueueSend_3
\ 000094 32D2 EINT
328 }
329 taskEXIT_CRITICAL();
\ ??xQueueSend_3:
\ 000096 8293.... CMP.W #0x0, &usCriticalNesting
\ 00009A 0624 JEQ ??xQueueSend_1
\ 00009C B253.... ADD.W #0xffff, &usCriticalNesting
\ 0000A0 8293.... CMP.W #0x0, &usCriticalNesting
\ 0000A4 0120 JNE ??xQueueSend_1
\ 0000A6 32D2 EINT
330 }
331 }
332
333 /* When we are here it is possible that we unblocked as space became
334 available on the queue. It is also possible that an ISR posted to the
335 queue since we left the critical section, so it may be that again there
336 is no space. This would only happen if a task and ISR post onto the
337 same queue. */
338 taskENTER_CRITICAL();
\ ??xQueueSend_1:
\ 0000A8 32C2 DINT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -