| 1833 | /*-----------------------------------------------------------*/ |
| 1834 | |
| 1835 | BaseType_t xQueueReceiveFromISR( QueueHandle_t xQueue, |
| 1836 | void * const pvBuffer, |
| 1837 | BaseType_t * const pxHigherPriorityTaskWoken ) |
| 1838 | { |
| 1839 | BaseType_t xReturn; |
| 1840 | UBaseType_t uxSavedInterruptStatus; |
| 1841 | Queue_t * const pxQueue = xQueue; |
| 1842 | |
| 1843 | configASSERT( pxQueue ); |
| 1844 | configASSERT( !( ( pvBuffer == NULL ) && ( pxQueue->uxItemSize != ( UBaseType_t ) 0U ) ) ); |
| 1845 | |
| 1846 | /* RTOS ports that support interrupt nesting have the concept of a maximum |
| 1847 | * system call (or maximum API call) interrupt priority. Interrupts that are |
| 1848 | * above the maximum system call priority are kept permanently enabled, even |
| 1849 | * when the RTOS kernel is in a critical section, but cannot make any calls to |
| 1850 | * FreeRTOS API functions. If configASSERT() is defined in FreeRTOSConfig.h |
| 1851 | * then portASSERT_IF_INTERRUPT_PRIORITY_INVALID() will result in an assertion |
| 1852 | * failure if a FreeRTOS API function is called from an interrupt that has been |
| 1853 | * assigned a priority above the configured maximum system call priority. |
| 1854 | * Only FreeRTOS functions that end in FromISR can be called from interrupts |
| 1855 | * that have been assigned a priority at or (logically) below the maximum |
| 1856 | * system call interrupt priority. FreeRTOS maintains a separate interrupt |
| 1857 | * safe API to ensure interrupt entry is as fast and as simple as possible. |
| 1858 | * More information (albeit Cortex-M specific) is provided on the following |
| 1859 | * link: https://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html */ |
| 1860 | portASSERT_IF_INTERRUPT_PRIORITY_INVALID(); |
| 1861 | |
| 1862 | uxSavedInterruptStatus = portSET_INTERRUPT_MASK_FROM_ISR(); |
| 1863 | { |
| 1864 | const UBaseType_t uxMessagesWaiting = pxQueue->uxMessagesWaiting; |
| 1865 | |
| 1866 | /* Cannot block in an ISR, so check there is data available. */ |
| 1867 | if( uxMessagesWaiting > ( UBaseType_t ) 0 ) |
| 1868 | { |
| 1869 | const int8_t cRxLock = pxQueue->cRxLock; |
| 1870 | |
| 1871 | traceQUEUE_RECEIVE_FROM_ISR( pxQueue ); |
| 1872 | |
| 1873 | prvCopyDataFromQueue( pxQueue, pvBuffer ); |
| 1874 | pxQueue->uxMessagesWaiting = uxMessagesWaiting - ( UBaseType_t ) 1; |
| 1875 | |
| 1876 | /* If the queue is locked the event list will not be modified. |
| 1877 | * Instead update the lock count so the task that unlocks the queue |
| 1878 | * will know that an ISR has removed data while the queue was |
| 1879 | * locked. */ |
| 1880 | if( cRxLock == queueUNLOCKED ) |
| 1881 | { |
| 1882 | if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE ) |
| 1883 | { |
| 1884 | if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE ) |
| 1885 | { |
| 1886 | /* The task waiting has a higher priority than us so |
| 1887 | * force a context switch. */ |
| 1888 | if( pxHigherPriorityTaskWoken != NULL ) |
| 1889 | { |
| 1890 | *pxHigherPriorityTaskWoken = pdTRUE; |
| 1891 | } |
| 1892 | else |
no test coverage detected