📄 queue.lst
字号:
\ 000006 B012.... CALL #vPortFree
570 vPortFree( pxQueue );
\ 00000A 0C4A MOV.W R10, R12
\ 00000C B012.... CALL #vPortFree
571 }
\ 000010 3A41 POP.W R10
\ 000012 3041 RET
572 /*-----------------------------------------------------------*/
573
\ In segment CODE, align 2
574 static signed portBASE_TYPE prvUnlockQueue( xQueueHandle pxQueue )
\ prvUnlockQueue:
575 {
\ 000000 0A12 PUSH.W R10
\ 000002 0B12 PUSH.W R11
\ 000004 0A4C MOV.W R12, R10
576 signed portBASE_TYPE xYieldRequired = pdFALSE;
\ 000006 0B43 MOV.W #0x0, R11
577
578 /* THIS FUNCTION MUST BE CALLED WITH THE SCHEDULER SUSPENDED. */
579
580 /* The lock counts contains the number of extra data items placed or
581 removed from the queue while the queue was locked. When a queue is
582 locked items can be added or removed, but the event lists cannot be
583 updated. */
584 taskENTER_CRITICAL();
\ 000008 32C2 DINT
\ 00000A 0343 NOP
\ 00000C 9253.... ADD.W #0x1, &usCriticalNesting
585 {
586 --( pxQueue->xTxLock );
\ 000010 0F4A MOV.W R10, R15
\ 000012 BF532400 ADD.W #0xffff, 0x24(R15)
587
588 /* See if data was added to the queue while it was locked. */
589 if( pxQueue->xTxLock > queueUNLOCKED )
\ 000016 8A932400 CMP.W #0x0, 0x24(R10)
\ 00001A 0D38 JL ??prvUnlockQueue_0
590 {
591 pxQueue->xTxLock = queueUNLOCKED;
\ 00001C BA432400 MOV.W #0xffff, 0x24(R10)
592
593 /* Data was posted while the queue was locked. Are any tasks
594 blocked waiting for data to become available? */
595 if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
\ 000020 8A931200 CMP.W #0x0, 0x12(R10)
\ 000024 0824 JEQ ??prvUnlockQueue_0
596 {
597 /* Tasks that are removed from the event list will get added to
598 the pending ready list as the scheduler is still suspended. */
599 if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
\ 000026 0C4A MOV.W R10, R12
\ 000028 3C501200 ADD.W #0x12, R12
\ 00002C B012.... CALL #xTaskRemoveFromEventList
\ 000030 0C93 CMP.W #0x0, R12
\ 000032 0124 JEQ ??prvUnlockQueue_0
600 {
601 /* The task waiting has a higher priority so record that a
602 context switch is required. */
603 xYieldRequired = pdTRUE;
\ 000034 1B43 MOV.W #0x1, R11
604 }
605 }
606 }
607 }
608 taskEXIT_CRITICAL();
\ ??prvUnlockQueue_0:
\ 000036 8293.... CMP.W #0x0, &usCriticalNesting
\ 00003A 0624 JEQ ??prvUnlockQueue_1
\ 00003C B253.... ADD.W #0xffff, &usCriticalNesting
\ 000040 8293.... CMP.W #0x0, &usCriticalNesting
\ 000044 0120 JNE ??prvUnlockQueue_1
\ 000046 32D2 EINT
609
610 /* Do the same for the Rx lock. */
611 taskENTER_CRITICAL();
\ ??prvUnlockQueue_1:
\ 000048 32C2 DINT
\ 00004A 0343 NOP
\ 00004C 9253.... ADD.W #0x1, &usCriticalNesting
612 {
613 --( pxQueue->xRxLock );
\ 000050 0F4A MOV.W R10, R15
\ 000052 BF532200 ADD.W #0xffff, 0x22(R15)
614
615 if( pxQueue->xRxLock > queueUNLOCKED )
\ 000056 8A932200 CMP.W #0x0, 0x22(R10)
\ 00005A 0C38 JL ??prvUnlockQueue_2
616 {
617 pxQueue->xRxLock = queueUNLOCKED;
\ 00005C BA432200 MOV.W #0xffff, 0x22(R10)
618
619 if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) )
\ 000060 8A930800 CMP.W #0x0, 0x8(R10)
\ 000064 0724 JEQ ??prvUnlockQueue_2
620 {
621 if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
\ 000066 0C4A MOV.W R10, R12
\ 000068 3C52 ADD.W #0x8, R12
\ 00006A B012.... CALL #xTaskRemoveFromEventList
\ 00006E 0C93 CMP.W #0x0, R12
\ 000070 0124 JEQ ??prvUnlockQueue_2
622 {
623 xYieldRequired = pdTRUE;
\ 000072 1B43 MOV.W #0x1, R11
624 }
625 }
626 }
627 }
628 taskEXIT_CRITICAL();
\ ??prvUnlockQueue_2:
\ 000074 8293.... CMP.W #0x0, &usCriticalNesting
\ 000078 0624 JEQ ??prvUnlockQueue_3
\ 00007A B253.... ADD.W #0xffff, &usCriticalNesting
\ 00007E 8293.... CMP.W #0x0, &usCriticalNesting
\ 000082 0120 JNE ??prvUnlockQueue_3
\ 000084 32D2 EINT
629
630 return xYieldRequired;
\ ??prvUnlockQueue_3:
\ 000086 0C4B MOV.W R11, R12
\ 000088 3B41 POP.W R11
\ 00008A 3A41 POP.W R10
\ 00008C 3041 RET
631 }
632 /*-----------------------------------------------------------*/
633
\ In segment CODE, align 2
634 static signed portBASE_TYPE prvIsQueueEmpty( const xQueueHandle pxQueue )
\ prvIsQueueEmpty:
635 {
\ 000000 0F4C MOV.W R12, R15
636 signed portBASE_TYPE xReturn;
637
638 taskENTER_CRITICAL();
\ 000002 32C2 DINT
\ 000004 0343 NOP
\ 000006 9253.... ADD.W #0x1, &usCriticalNesting
639 xReturn = ( pxQueue->uxMessagesWaiting == ( unsigned portBASE_TYPE ) 0 );
\ 00000A 8F931C00 CMP.W #0x0, 0x1c(R15)
\ 00000E 0220 JNE ??prvIsQueueEmpty_0
\ 000010 5C43 MOV.B #0x1, R12
\ 000012 013C JMP ??prvIsQueueEmpty_1
\ ??prvIsQueueEmpty_0:
\ 000014 4C43 MOV.B #0x0, R12
\ ??prvIsQueueEmpty_1:
\ 000016 3CF0FF00 AND.W #0xff, R12
640 taskEXIT_CRITICAL();
\ 00001A 8293.... CMP.W #0x0, &usCriticalNesting
\ 00001E 0624 JEQ ??prvIsQueueEmpty_2
\ 000020 B253.... ADD.W #0xffff, &usCriticalNesting
\ 000024 8293.... CMP.W #0x0, &usCriticalNesting
\ 000028 0120 JNE ??prvIsQueueEmpty_2
\ 00002A 32D2 EINT
641
642 return xReturn;
\ ??prvIsQueueEmpty_2:
\ 00002C 3041 RET
643 }
644 /*-----------------------------------------------------------*/
645
\ In segment CODE, align 2
646 static signed portBASE_TYPE prvIsQueueFull( const xQueueHandle pxQueue )
\ prvIsQueueFull:
647 {
\ 000000 0F4C MOV.W R12, R15
648 signed portBASE_TYPE xReturn;
649
650 taskENTER_CRITICAL();
\ 000002 32C2 DINT
\ 000004 0343 NOP
\ 000006 9253.... ADD.W #0x1, &usCriticalNesting
651 xReturn = ( pxQueue->uxMessagesWaiting == pxQueue->uxLength );
\ 00000A 9F9F1E001C00 CMP.W 0x1e(R15), 0x1c(R15)
\ 000010 0220 JNE ??prvIsQueueFull_0
\ 000012 5C43 MOV.B #0x1, R12
\ 000014 013C JMP ??prvIsQueueFull_1
\ ??prvIsQueueFull_0:
\ 000016 4C43 MOV.B #0x0, R12
\ ??prvIsQueueFull_1:
\ 000018 3CF0FF00 AND.W #0xff, R12
652 taskEXIT_CRITICAL();
\ 00001C 8293.... CMP.W #0x0, &usCriticalNesting
\ 000020 0624 JEQ ??prvIsQueueFull_2
\ 000022 B253.... ADD.W #0xffff, &usCriticalNesting
\ 000026 8293.... CMP.W #0x0, &usCriticalNesting
\ 00002A 0120 JNE ??prvIsQueueFull_2
\ 00002C 32D2 EINT
653
654 return xReturn;
\ ??prvIsQueueFull_2:
\ 00002E 3041 RET
655 }
656 /*-----------------------------------------------------------*/
657
658 #if configUSE_CO_ROUTINES == 1
659 signed portBASE_TYPE xQueueCRSend( xQueueHandle pxQueue, const void *pvItemToQueue, portTickType xTicksToWait )
660 {
661 signed portBASE_TYPE xReturn;
662
663 /* If the queue is already full we may have to block. A critical section
664 is required to prevent an interrupt removing something from the queue
665 between the check to see if the queue is full and blocking on the queue. */
666 portDISABLE_INTERRUPTS();
667 {
668 if( prvIsQueueFull( pxQueue ) )
669 {
670 /* The queue is full - do we want to block or just leave without
671 posting? */
672 if( xTicksToWait > ( portTickType ) 0 )
673 {
674 /* As this is called from a coroutine we cannot block directly, but
675 return indicating that we need to block. */
676 vCoRoutineAddToDelayedList( xTicksToWait, &( pxQueue->xTasksWaitingToSend ) );
677 portENABLE_INTERRUPTS();
678 return errQUEUE_BLOCKED;
679 }
680 else
681 {
682 portENABLE_INTERRUPTS();
683 return errQUEUE_FULL;
684 }
685 }
686 }
687 portENABLE_INTERRUPTS();
688
689 portNOP();
690
691 portDISABLE_INTERRUPTS();
692 {
693 if( pxQueue->uxMessagesWaiting < pxQueue->uxLength )
694 {
695 /* There is room in the queue, copy the data into the queue. */
696 prvCopyQueueData( pxQueue, pvItemToQueue );
697 xReturn = pdPASS;
698
699 /* Were any co-routines waiting for data to become available? */
700 if( !listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) )
701 {
702 /* In this instance the co-routine could be placed directly
703 into the ready list as we are within a critical section.
704 Instead the same pending ready list mechansim is used as if
705 the event were caused from within an interrupt. */
706 if( xCoRoutineRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
707 {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -