📄 queue.lst
字号:
182 /* Create the list of pointers to queue items. The queue is one byte
183 longer than asked for to make wrap checking easier/faster. */
184 xQueueSizeInBytes = ( size_t ) ( uxQueueLength * uxItemSize ) + ( size_t ) 1;
185
186 pxNewQueue->pcHead = ( signed portCHAR * ) pvPortMalloc( xQueueSizeInBytes );
\ 00000014 271C MOV R7,R4
\ 00000016 6F43 MUL R7,R5
\ 00000018 781C ADD R0,R7,#+0x1
\ 0000001A ........ _BLF pvPortMalloc,pvPortMalloc??rT
\ 0000001E 3060 STR R0,[R6, #+0]
187 if( pxNewQueue->pcHead != NULL )
\ 00000020 0028 CMP R0,#+0
\ 00000022 1AD0 BEQ ??xQueueCreate_1
188 {
189 /* Initialise the queue members as described above where the
190 queue type is defined. */
191 pxNewQueue->pcTail = pxNewQueue->pcHead + ( uxQueueLength * uxItemSize );
\ 00000024 C019 ADD R0,R0,R7
\ 00000026 7060 STR R0,[R6, #+0x4]
192 pxNewQueue->uxMessagesWaiting = 0;
\ 00000028 0020 MOV R0,#+0
\ 0000002A 3065 STR R0,[R6, #+0x50]
193 pxNewQueue->pcWriteTo = pxNewQueue->pcHead;
\ 0000002C 3068 LDR R0,[R6, #+0]
\ 0000002E B060 STR R0,[R6, #+0x8]
194 pxNewQueue->pcReadFrom = pxNewQueue->pcHead + ( ( uxQueueLength - 1 ) * uxItemSize );
\ 00000030 0020 MOV R0,#+0
\ 00000032 C043 MVN R0,R0 ;; #-1
\ 00000034 2118 ADD R1,R4,R0
\ 00000036 6943 MUL R1,R5
\ 00000038 3268 LDR R2,[R6, #+0]
\ 0000003A 5118 ADD R1,R2,R1
\ 0000003C F160 STR R1,[R6, #+0xC]
195 pxNewQueue->uxLength = uxQueueLength;
\ 0000003E 7465 STR R4,[R6, #+0x54]
196 pxNewQueue->uxItemSize = uxItemSize;
\ 00000040 B565 STR R5,[R6, #+0x58]
197 pxNewQueue->xRxLock = queueUNLOCKED;
\ 00000042 F065 STR R0,[R6, #+0x5C]
198 pxNewQueue->xTxLock = queueUNLOCKED;
\ 00000044 3066 STR R0,[R6, #+0x60]
199
200 /* Likewise ensure the event queues start with the correct state. */
201 vListInitialise( &( pxNewQueue->xTasksWaitingToSend ) );
\ 00000046 301C MOV R0,R6
\ 00000048 1030 ADD R0,#+0x10
\ 0000004A ........ _BLF vListInitialise,vListInitialise??rT
202 vListInitialise( &( pxNewQueue->xTasksWaitingToReceive ) );
\ 0000004E 301C MOV R0,R6
\ 00000050 3030 ADD R0,#+0x30
\ 00000052 ........ _BLF vListInitialise,vListInitialise??rT
203
204 return pxNewQueue;
\ 00000056 301C MOV R0,R6
\ 00000058 03E0 B ??xQueueCreate_2
205 }
206 else
207 {
208 vPortFree( pxNewQueue );
\ ??xQueueCreate_1:
\ 0000005A 301C MOV R0,R6
\ 0000005C ........ _BLF vPortFree,vPortFree??rT
209 }
210 }
211 }
212
213 /* Will only reach here if we could not allocate enough memory or no memory
214 was required. */
215 return NULL;
\ ??xQueueCreate_0:
\ 00000060 0020 MOV R0,#+0
\ ??xQueueCreate_2:
\ 00000062 F0BC POP {R4-R7}
\ 00000064 02BC POP {R1}
\ 00000066 0847 BX R1 ;; return
216 }
217 /*-----------------------------------------------------------*/
218
\ In segment CODE, align 4, keep-with-next
219 signed portBASE_TYPE xQueueSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait )
220 {
\ xQueueSend:
\ 00000000 F4B5 PUSH {R2,R4-R7,LR}
\ 00000002 041C MOV R4,R0
\ 00000004 0E1C MOV R6,R1
221 signed portBASE_TYPE xReturn;
222
223 /* Make sure other tasks do not access the queue. */
224 vTaskSuspendAll();
\ 00000006 ........ _BLF vTaskSuspendAll,vTaskSuspendAll??rT
225
226 /* It is important that this is the only thread/ISR that modifies the
227 ready or delayed lists until xTaskResumeAll() is called. Places where
228 the ready/delayed lists are modified include:
229
230 + vTaskDelay() - Nothing can call vTaskDelay as the scheduler is
231 suspended, vTaskDelay() cannot be called from an ISR.
232 + vTaskPrioritySet() - Has a critical section around the access.
233 + vTaskSwitchContext() - This will not get executed while the scheduler
234 is suspended.
235 + prvCheckDelayedTasks() - This will not get executed while the
236 scheduler is suspended.
237 + xTaskCreate() - Has a critical section around the access.
238 + vTaskResume() - Has a critical section around the access.
239 + xTaskResumeAll() - Has a critical section around the access.
240 + xTaskRemoveFromEventList - Checks to see if the scheduler is
241 suspended. If so then the TCB being removed from the event is
242 removed from the event and added to the xPendingReadyList.
243 */
244
245 /* Make sure interrupts do not access the queue event list. */
246 prvLockQueue( pxQueue );
\ 0000000A ........ _BLF vPortEnterCritical,vPortEnterCritical??rT
\ 0000000E E06D LDR R0,[R4, #+0x5C]
\ 00000010 401C ADD R0,R0,#+0x1
\ 00000012 E065 STR R0,[R4, #+0x5C]
\ 00000014 206E LDR R0,[R4, #+0x60]
\ 00000016 401C ADD R0,R0,#+0x1
\ 00000018 2066 STR R0,[R4, #+0x60]
\ 0000001A ........ _BLF vPortExitCritical,vPortExitCritical??rT
247
248 /* It is important that interrupts to not access the event list of the
249 queue being modified here. Places where the event list is modified
250 include:
251
252 + xQueueSendFromISR(). This checks the lock on the queue to see if
253 it has access. If the queue is locked then the Tx lock count is
254 incremented to signify that a task waiting for data can be made ready
255 once the queue lock is removed. If the queue is not locked then
256 a task can be moved from the event list, but will not be removed
257 from the delayed list or placed in the ready list until the scheduler
258 is unlocked.
259
260 + xQueueReceiveFromISR(). As per xQueueSendFromISR().
261 */
262
263 /* If the queue is already full we may have to block. */
264 if( prvIsQueueFull( pxQueue ) )
\ 0000001E ........ _BLF vPortEnterCritical,vPortEnterCritical??rT
\ 00000022 0125 MOV R5,#+0x1
\ 00000024 206D LDR R0,[R4, #+0x50]
\ 00000026 616D LDR R1,[R4, #+0x54]
\ 00000028 8842 CMP R0,R1
\ 0000002A 01D1 BNE ??xQueueSend_0
\ 0000002C 0127 MOV R7,#+0x1
\ 0000002E 00E0 B ??xQueueSend_1
\ ??xQueueSend_0:
\ 00000030 0027 MOV R7,#+0
\ ??xQueueSend_1:
\ 00000032 ........ _BLF vPortExitCritical,vPortExitCritical??rT
\ 00000036 002F CMP R7,#+0
\ 00000038 1FD0 BEQ ??xQueueSend_2
265 {
266 /* The queue is full - do we want to block or just leave without
267 posting? */
268 if( xTicksToWait > ( portTickType ) 0 )
\ 0000003A 0098 LDR R0,[SP, #+0]
\ 0000003C 0028 CMP R0,#+0
\ 0000003E 1CD0 BEQ ??xQueueSend_2
269 {
270 /* We are going to place ourselves on the xTasksWaitingToSend event
271 list, and will get woken should the delay expire, or space become
272 available on the queue.
273
274 As detailed above we do not require mutual exclusion on the event
275 list as nothing else can modify it or the ready lists while we
276 have the scheduler suspended and queue locked.
277
278 It is possible that an ISR has removed data from the queue since we
279 checked if any was available. If this is the case then the data
280 will have been copied from the queue, and the queue variables
281 updated, but the event list will not yet have been checked to see if
282 anything is waiting as the queue is locked. */
283 vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToSend ), xTicksToWait );
\ 00000040 011C MOV R1,R0
\ 00000042 201C MOV R0,R4
\ 00000044 1030 ADD R0,#+0x10
\ 00000046 ........ _BLF vTaskPlaceOnEventList,vTaskPlaceOnEventList??rT
284
285 /* Force a context switch now as we are blocked. We can do
286 this from within a critical section as the task we are
287 switching to has its own context. When we return here (i.e. we
288 unblock) we will leave the critical section as normal.
289
290 It is possible that an ISR has caused an event on an unrelated and
291 unlocked queue. If this was the case then the event list for that
292 queue will have been updated but the ready lists left unchanged -
293 instead the readied task will have been added to the pending ready
294 list. */
295 taskENTER_CRITICAL();
\ 0000004A ........ _BLF vPortEnterCritical,vPortEnterCritical??rT
296 {
297 /* We can safely unlock the queue and scheduler here as
298 interrupts are disabled. We must not yield with anything
299 locked, but we can yield from within a critical section.
300
301 Tasks that have been placed on the pending ready list cannot
302 be tasks that are waiting for events on this queue. See
303 in comment xTaskRemoveFromEventList(). */
304 prvUnlockQueue( pxQueue );
\ 0000004E 201C MOV R0,R4
\ 00000050 ........ BL ??prvUnlockQueue
305
306 /* Resuming the scheduler may cause a yield. If so then there
307 is no point yielding again here. */
308 if( !xTaskResumeAll() )
\ 00000054 ........ _BLF xTaskResumeAll,xTaskResumeAll??rT
\ 00000058 0028 CMP R0,#+0
\ 0000005A 00D1 BNE ??xQueueSend_3
309 {
310 taskYIELD();
\ 0000005C 00DF SWI 0
311 }
312
313 /* Before leaving the critical section we have to ensure
314 exclusive access again. */
315 vTaskSuspendAll();
\ ??xQueueSend_3:
\ 0000005E ........ _BLF vTaskSuspendAll,vTaskSuspendAll??rT
316 prvLockQueue( pxQueue );
\ 00000062 ........ _BLF vPortEnterCritical,vPortEnterCritical??rT
\ 00000066 E06D LDR R0,[R4, #+0x5C]
\ 00000068 401C ADD R0,R0,#+0x1
\ 0000006A E065 STR R0,[R4, #+0x5C]
\ 0000006C 206E LDR R0,[R4, #+0x60]
\ 0000006E 401C ADD R0,R0,#+0x1
\ 00000070 2066 STR R0,[R4, #+0x60]
\ 00000072 ........ _BLF vPortExitCritical,vPortExitCritical??rT
317 }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -