diff --git a/components/freertos/event_groups.c b/components/freertos/event_groups.c index 2a63b0fa4f..8234ef6e55 100644 --- a/components/freertos/event_groups.c +++ b/components/freertos/event_groups.c @@ -217,6 +217,9 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, { EventBits_t uxOriginalBitValue, uxReturn; EventGroup_t * pxEventBits = xEventGroup; +#ifndef ESP_PLATFORM + BaseType_t xAlreadyYielded; +#endif // ESP_PLATFORM BaseType_t xTimeoutOccurred = pdFALSE; configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); @@ -227,7 +230,11 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, } #endif +#ifdef ESP_PLATFORM // IDF-3755 taskENTER_CRITICAL(); +#else + vTaskSuspendAll(); +#endif // ESP_PLATFORM { uxOriginalBitValue = pxEventBits->uxEventBits; @@ -270,11 +277,26 @@ EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, } } } +#ifdef ESP_PLATFORM // IDF-3755 taskEXIT_CRITICAL(); +#else + xAlreadyYielded = xTaskResumeAll(); +#endif // ESP_PLATFORM if( xTicksToWait != ( TickType_t ) 0 ) { +#ifdef ESP_PLATFORM portYIELD_WITHIN_API(); +#else + if( xAlreadyYielded == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } +#endif // ESP_PLATFORM /* The task blocked to wait for its required bits to be set - at this * point either the required bits were set or the block time expired. If @@ -333,7 +355,11 @@ EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, { EventGroup_t * pxEventBits = xEventGroup; EventBits_t uxReturn, uxControlBits = 0; +#ifdef ESP_PLATFORM BaseType_t xWaitConditionMet; +#else + BaseType_t xWaitConditionMet, xAlreadyYielded; +#endif // ESP_PLATFORM BaseType_t xTimeoutOccurred = pdFALSE; /* Check the user is not attempting to wait on the bits used by the kernel @@ -347,7 +373,11 @@ EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, } #endif +#ifdef ESP_PLATFORM // IDF-3755 taskENTER_CRITICAL(); +#else + vTaskSuspendAll(); +#endif // ESP_PLATFORM { const EventBits_t uxCurrentEventBits = pxEventBits->uxEventBits; @@ -415,11 +445,26 @@ EventBits_t xEventGroupWaitBits( EventGroupHandle_t xEventGroup, traceEVENT_GROUP_WAIT_BITS_BLOCK( xEventGroup, uxBitsToWaitFor ); } } +#ifdef ESP_PLATFORM // IDF-3755 taskEXIT_CRITICAL(); +#else + xAlreadyYielded = xTaskResumeAll(); +#endif // ESP_PLATFORM if( xTicksToWait != ( TickType_t ) 0 ) { +#ifdef ESP_PLATFORM portYIELD_WITHIN_API(); +#else + if( xAlreadyYielded == pdFALSE ) + { + portYIELD_WITHIN_API(); + } + else + { + mtCOVERAGE_TEST_MARKER(); + } +#endif // ESP_PLATFORM /* The task blocked to wait for its required bits to be set - at this * point either the required bits were set or the block time expired. If @@ -551,7 +596,11 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, pxList = &( pxEventBits->xTasksWaitingForBits ); pxListEnd = listGET_END_MARKER( pxList ); /*lint !e826 !e740 !e9087 The mini list structure is used as the list end to save RAM. This is checked and valid. */ +#ifdef ESP_PLATFORM // IDF-3755 taskENTER_CRITICAL(); +#else + vTaskSuspendAll(); +#endif // ESP_PLATFORM { traceEVENT_GROUP_SET_BITS( xEventGroup, uxBitsToSet ); @@ -623,7 +672,11 @@ EventBits_t xEventGroupSetBits( EventGroupHandle_t xEventGroup, * bit was set in the control word. */ pxEventBits->uxEventBits &= ~uxBitsToClear; } +#ifdef ESP_PLATFORM // IDF-3755 taskEXIT_CRITICAL(); +#else + ( void ) xTaskResumeAll(); +#endif // ESP_PLATFORM return pxEventBits->uxEventBits; } @@ -636,6 +689,7 @@ void vEventGroupDelete( EventGroupHandle_t xEventGroup ) traceEVENT_GROUP_DELETE( xEventGroup ); + // IDF-3755 taskENTER_CRITICAL(); { while( listCURRENT_LIST_LENGTH( pxTasksWaitingForBits ) > ( UBaseType_t ) 0 ) diff --git a/components/freertos/include/freertos/portable.h b/components/freertos/include/freertos/portable.h index 58b24b829c..36f83ff516 100644 --- a/components/freertos/include/freertos/portable.h +++ b/components/freertos/include/freertos/portable.h @@ -210,6 +210,21 @@ BaseType_t xPortStartScheduler( void ) PRIVILEGED_FUNCTION; */ void vPortEndScheduler( void ) PRIVILEGED_FUNCTION; +/* + * The structures and methods of manipulating the MPU are contained within the + * port layer. + * + * Fills the xMPUSettings structure with the memory region information + * contained in xRegions. + */ +#if ( portUSING_MPU_WRAPPERS == 1 ) + struct xMEMORY_REGION; + void vPortStoreTaskMPUSettings( xMPU_SETTINGS * xMPUSettings, + const struct xMEMORY_REGION * const xRegions, + StackType_t * pxBottomOfStack, + uint32_t ulStackDepth ) PRIVILEGED_FUNCTION; +#endif + /* *INDENT-OFF* */ #ifdef __cplusplus } diff --git a/components/freertos/include/freertos/semphr.h b/components/freertos/include/freertos/semphr.h index 08d52556e5..d693eddd4f 100644 --- a/components/freertos/include/freertos/semphr.h +++ b/components/freertos/include/freertos/semphr.h @@ -312,6 +312,16 @@ typedef QueueHandle_t SemaphoreHandle_t; #define xSemaphoreTake( xSemaphore, xBlockTime ) xQueueSemaphoreTake( ( xSemaphore ), ( xBlockTime ) ) /** + * @cond + * semphr. h + * @code{c} + * xSemaphoreTakeRecursive( + * SemaphoreHandle_t xMutex, + * TickType_t xBlockTime + * ); + * @endcode + * @endcond + * * Macro to recursively obtain, or 'take', a mutex type semaphore. * The mutex must have previously been created using a call to * xSemaphoreCreateRecursiveMutex(); @@ -400,6 +410,7 @@ typedef QueueHandle_t SemaphoreHandle_t; */ #define xSemaphoreTakeRecursive( xMutex, xBlockTime ) xQueueTakeMutexRecursive( ( xMutex ), ( xBlockTime ) ) +#ifdef ESP_PLATFORM // IDF-3814 /** @cond */ /* * xSemaphoreAltTake() is an alternative version of xSemaphoreTake(). @@ -415,7 +426,7 @@ typedef QueueHandle_t SemaphoreHandle_t; */ #define xSemaphoreAltTake( xSemaphore, xBlockTime ) xQueueAltGenericReceive( ( QueueHandle_t ) ( xSemaphore ), NULL, ( xBlockTime ), pdFALSE ) /** @endcond */ - +#endif // ESP_PLATFORM /** * Macro to release a semaphore. The semaphore must have previously been * created with a call to xSemaphoreCreateBinary(), xSemaphoreCreateMutex() or @@ -568,6 +579,7 @@ typedef QueueHandle_t SemaphoreHandle_t; */ #define xSemaphoreGiveRecursive( xMutex ) xQueueGiveMutexRecursive( ( xMutex ) ) +#ifdef ESP_PLATFORM // IDF-3814 /** @cond */ /* * xSemaphoreAltGive() is an alternative version of xSemaphoreGive(). @@ -584,6 +596,7 @@ typedef QueueHandle_t SemaphoreHandle_t; #define xSemaphoreAltGive( xSemaphore ) xQueueAltGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK ) /** @endcond */ +#endif // ESP_PLATFORM /** * Macro to release a semaphore. The semaphore must have previously been diff --git a/components/freertos/include/freertos/stdint.readme b/components/freertos/include/freertos/stdint.readme index 4414c29ed2..20a8d663ef 100644 --- a/components/freertos/include/freertos/stdint.readme +++ b/components/freertos/include/freertos/stdint.readme @@ -1,3 +1,28 @@ +/* + * FreeRTOS Kernel V10.4.3 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ #ifndef FREERTOS_STDINT #define FREERTOS_STDINT @@ -10,7 +35,7 @@ * To use this file: * * 1) Copy this file into the directory that contains your FreeRTOSConfig.h - * header file, as that directory will already be in the compilers include + * header file, as that directory will already be in the compiler's include * path. * * 2) Rename the copied file stdint.h. diff --git a/components/freertos/include/freertos/task.h b/components/freertos/include/freertos/task.h index 5c7ce9ada0..3be59a9eea 100644 --- a/components/freertos/include/freertos/task.h +++ b/components/freertos/include/freertos/task.h @@ -613,7 +613,16 @@ typedef enum } #endif /* configSUPPORT_STATIC_ALLOCATION */ -/* +/** + * @cond + * task. h + * @code{c} + * BaseType_t xTaskCreateRestricted( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask ); + * @endcode + * @endcond + * + * Only available when configSUPPORT_DYNAMIC_ALLOCATION is set to 1. + * * xTaskCreateRestricted() should only be used in systems that include an MPU * implementation. * @@ -686,12 +695,19 @@ typedef enum TaskHandle_t * pxCreatedTask ); #endif -/* - * xTaskCreateRestrictedStatic() should only be used in systems that include an - * MPU implementation. +/** + * @cond + * task. h + * @code{c} + * BaseType_t xTaskCreateRestrictedStatic( TaskParameters_t *pxTaskDefinition, TaskHandle_t *pxCreatedTask ); + * @endcode + * @endcond * * Only available when configSUPPORT_STATIC_ALLOCATION is set to 1. * + * xTaskCreateRestrictedStatic() should only be used in systems that include an + * MPU implementation. + * * Internally, within the FreeRTOS implementation, tasks use two blocks of * memory. The first block is used to hold the task's data structures. The * second block is used by the task as its stack. If a task is created using @@ -770,7 +786,7 @@ typedef enum */ #if ( ( portUSING_MPU_WRAPPERS == 1 ) && ( configSUPPORT_STATIC_ALLOCATION == 1 ) ) BaseType_t xTaskCreateRestrictedStatic( const TaskParameters_t * const pxTaskDefinition, - TaskHandle_t * pxCreatedTask ); + TaskHandle_t * pxCreatedTask ) PRIVILEGED_FUNCTION; #endif /** @@ -828,8 +844,12 @@ void vTaskAllocateMPURegions( TaskHandle_t xTask, const MemoryRegion_t * const pxRegions ) PRIVILEGED_FUNCTION; /** - * Remove a task from the RTOS real time kernel's management. The task being - * deleted will be removed from all ready, blocked, suspended and event lists. + * @cond + * task. h + * @code{c} + * void vTaskDelete( TaskHandle_t xTask ); + * @endcode + * @endcond * * INCLUDE_vTaskDelete must be defined as 1 for this function to be available. * See the configuration section for more information. @@ -1245,7 +1265,12 @@ void vTaskPrioritySet( TaskHandle_t xTask, UBaseType_t uxNewPriority ) PRIVILEGED_FUNCTION; /** - * Suspend a task. + * @cond + * task. h + * @code{c} + * void vTaskSuspend( TaskHandle_t xTaskToSuspend ); + * @endcode + * @endcond * * INCLUDE_vTaskSuspend must be defined as 1 for this function to be available. * See the configuration section for more information. @@ -1352,11 +1377,18 @@ void vTaskSuspend( TaskHandle_t xTaskToSuspend ) PRIVILEGED_FUNCTION; void vTaskResume( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; /** - * An implementation of vTaskResume() that can be called from within an ISR. + * @cond + * task. h + * @code{c} + * void xTaskResumeFromISR( TaskHandle_t xTaskToResume ); + * @endcode + * @endcond * * INCLUDE_xTaskResumeFromISR must be defined as 1 for this function to be * available. See the configuration section for more information. * + * An implementation of vTaskResume() that can be called from within an ISR. + * * A task that has been suspended by one or more calls to vTaskSuspend () * will be made available for running again by a single call to * xTaskResumeFromISR (). @@ -1384,14 +1416,20 @@ BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; *----------------------------------------------------------*/ /** @cond */ /** - * Starts the real time kernel tick processing. + * @cond + * task. h + * @code{c} + * void vTaskStartScheduler( void ); + * @endcode + * @endcond * + * Starts the real time kernel tick processing. After calling the kernel + * has control over which tasks are executed and when. + * NOTE: In ESP-IDF the scheduler is started automatically during * application startup, vTaskStartScheduler() should not be called from * ESP-IDF applications. * - * After calling the kernel has control over which tasks are executed and when. - * * See the demo application file main.c for an example of creating * tasks and starting the kernel. * @@ -1417,7 +1455,12 @@ BaseType_t xTaskResumeFromISR( TaskHandle_t xTaskToResume ) PRIVILEGED_FUNCTION; void vTaskStartScheduler( void ) PRIVILEGED_FUNCTION; /** - * Stops the real time kernel tick. + * @cond + * task. h + * @code{c} + * void vTaskEndScheduler( void ); + * @endcode + * @endcond * * NOTE: At the time of writing only the x86 real mode port, which runs on a PC * in place of DOS, implements this function. @@ -1476,9 +1519,15 @@ void vTaskEndScheduler( void ) PRIVILEGED_FUNCTION; /** @endcond */ /** - * Suspends the scheduler without disabling interrupts. + * @cond + * task. h + * @code{c} + * void vTaskSuspendAll( void ); + * @endcode + * @endcond * - * Context switches will not occur while the scheduler is suspended. + * Suspends the scheduler without disabling interrupts. Context switches will + * not occur while the scheduler is suspended. * * After calling vTaskSuspendAll () the calling task will continue to execute * without risk of being swapped out until a call to xTaskResumeAll () has been @@ -1591,7 +1640,12 @@ BaseType_t xTaskResumeAll( void ) PRIVILEGED_FUNCTION; *----------------------------------------------------------*/ /** - * Get tick count + * @cond + * task. h + * @code{c} + * TickType_t xTaskGetTickCount( void ); + * @endcode + * @endcond * * @return The count of ticks since vTaskStartScheduler was called. * @@ -1603,7 +1657,12 @@ BaseType_t xTaskResumeAll( void ) PRIVILEGED_FUNCTION; TickType_t xTaskGetTickCount( void ) PRIVILEGED_FUNCTION; /** - * Get tick count from ISR + * @cond + * task. h + * @code{c} + * TickType_t xTaskGetTickCountFromISR( void ); + * @endcode + * @endcond * * @return The count of ticks since vTaskStartScheduler was called. * @@ -1620,7 +1679,12 @@ TickType_t xTaskGetTickCount( void ) PRIVILEGED_FUNCTION; TickType_t xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION; /** - * Get current number of tasks + * @cond + * task. h + * @code{c} + * uint16_t uxTaskGetNumberOfTasks( void ); + * @endcode + * @endcond * * @return The number of tasks that the real time kernel is currently managing. * This includes all ready, blocked and suspended tasks. A task that @@ -1635,7 +1699,12 @@ TickType_t xTaskGetTickCountFromISR( void ) PRIVILEGED_FUNCTION; UBaseType_t uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION; /** - * Get task name + * @cond + * task. h + * @code{c} + * char *pcTaskGetName( TaskHandle_t xTaskToQuery ); + * @endcode + * @endcond * * @return The text (human readable) name of the task referenced by the handle * xTaskToQuery. A task can query its own name by either passing in its own @@ -1646,10 +1715,17 @@ UBaseType_t uxTaskGetNumberOfTasks( void ) PRIVILEGED_FUNCTION; * @endcond * \ingroup TaskUtils */ -char *pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ +char * pcTaskGetName( TaskHandle_t xTaskToQuery ) PRIVILEGED_FUNCTION; /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ /** - * @note This function takes a relatively long time to complete and should be + * @cond + * task. h + * @code{c} + * TaskHandle_t xTaskGetHandle( const char *pcNameToQuery ); + * @endcode + * @endcond + * + * NOTE: This function takes a relatively long time to complete and should be * used sparingly. * * @return The handle of the task that has the human readable name pcNameToQuery. diff --git a/components/freertos/queue.c b/components/freertos/queue.c index 486dd2d07e..1e2f795da5 100644 --- a/components/freertos/queue.c +++ b/components/freertos/queue.c @@ -975,7 +975,11 @@ BaseType_t xQueueGenericSend( QueueHandle_t xQueue, /* Interrupts and other tasks can send to and receive from the queue * now the critical section has been exited. */ +#ifdef ESP_PLATFORM // IDF-3755 taskENTER_CRITICAL(); +#else + vTaskSuspendAll(); +#endif // ESP_PLATFORM prvLockQueue( pxQueue ); /* Update the timeout state to see if it has expired yet. */ @@ -998,22 +1002,36 @@ BaseType_t xQueueGenericSend( QueueHandle_t xQueue, * task is already in the ready list before it yields - in which * case the yield will not cause a context switch unless there * is also a higher priority task in the pending ready list. */ +#ifdef ESP_PLATFORM // IDF-3755 taskEXIT_CRITICAL(); - portYIELD_WITHIN_API(); +#else + if( xTaskResumeAll() == pdFALSE ) +#endif // ESP_PLATFORM + { + portYIELD_WITHIN_API(); + } } else { /* Try again. */ prvUnlockQueue( pxQueue ); +#ifdef ESP_PLATFORM // IDF-3755 taskEXIT_CRITICAL(); +#else + ( void ) xTaskResumeAll(); +#endif // ESP_PLATFORM } } else { /* The timeout has expired. */ prvUnlockQueue( pxQueue ); +#ifdef ESP_PLATFORM // IDF-3755 taskEXIT_CRITICAL(); +#else + ( void ) xTaskResumeAll(); +#endif // ESP_PLATFORM traceQUEUE_SEND_FAILED( pxQueue ); return errQUEUE_FULL; @@ -1440,7 +1458,11 @@ BaseType_t xQueueReceive( QueueHandle_t xQueue, /* Interrupts and other tasks can send to and receive from the queue * now the critical section has been exited. */ +#ifdef ESP_PLATFORM // IDF-3755 taskENTER_CRITICAL(); +#else + vTaskSuspendAll(); +#endif // ESP_PLATFORM prvLockQueue( pxQueue ); /* Update the timeout state to see if it has expired yet. */ @@ -1453,15 +1475,31 @@ BaseType_t xQueueReceive( QueueHandle_t xQueue, traceBLOCKING_ON_QUEUE_RECEIVE( pxQueue ); vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); prvUnlockQueue( pxQueue ); +#ifdef ESP_PLATFORM // IDF-3755 taskEXIT_CRITICAL(); - portYIELD_WITHIN_API(); +#else + if( xTaskResumeAll() == pdFALSE ) +#endif // ESP_PLATFORM + { + portYIELD_WITHIN_API(); + } +#ifndef ESP_PLATFORM + else + { + mtCOVERAGE_TEST_MARKER(); + } +#endif // ESP_PLATFORM } else { /* The queue contains data again. Loop back to try and read the * data. */ prvUnlockQueue( pxQueue ); +#ifdef ESP_PLATFORM // IDF-3755 taskEXIT_CRITICAL(); +#else + ( void ) xTaskResumeAll(); +#endif // ESP_PLATFORM } } else @@ -1469,7 +1507,11 @@ BaseType_t xQueueReceive( QueueHandle_t xQueue, /* Timed out. If there is no data in the queue exit, otherwise loop * back and attempt to read the data. */ prvUnlockQueue( pxQueue ); +#ifdef ESP_PLATFORM // IDF-3755 taskEXIT_CRITICAL(); +#else + ( void ) xTaskResumeAll(); +#endif // ESP_PLATFORM if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) { @@ -1605,7 +1647,11 @@ BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue, /* Interrupts and other tasks can give to and take from the semaphore * now the critical section has been exited. */ +#ifdef ESP_PLATFORM // IDF-3755 taskENTER_CRITICAL(); +#else + vTaskSuspendAll(); +#endif // ESP_PLATFORM prvLockQueue( pxQueue ); /* Update the timeout state to see if it has expired yet. */ @@ -1627,7 +1673,7 @@ BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue, { xInheritanceOccurred = xTaskPriorityInherit( pxQueue->u.xSemaphore.xMutexHolder ); } - taskEXIT_CRITICAL(); + taskEXIT_CRITICAL(); } else { @@ -1638,22 +1684,42 @@ BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue, vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); prvUnlockQueue( pxQueue ); +#ifdef ESP_PLATFORM // IDF-3755 taskEXIT_CRITICAL(); - portYIELD_WITHIN_API(); +#else + if( xTaskResumeAll() == pdFALSE ) +#endif // ESP_PLATFORM + { + portYIELD_WITHIN_API(); + } +#ifndef ESP_PLATFORM + else + { + mtCOVERAGE_TEST_MARKER(); + } +#endif // ESP_PLATFORM } else { /* There was no timeout and the semaphore count was not 0, so * attempt to take the semaphore again. */ prvUnlockQueue( pxQueue ); +#ifdef ESP_PLATFORM // IDF-3755 taskEXIT_CRITICAL(); +#else + ( void ) xTaskResumeAll(); +#endif // ESP_PLATFORM } } else { /* Timed out. */ prvUnlockQueue( pxQueue ); +#ifdef ESP_PLATFORM // IDF-3755 taskEXIT_CRITICAL(); +#else + ( void ) xTaskResumeAll(); +#endif // ESP_PLATFORM /* If the semaphore count is 0 exit now as the timeout has * expired. Otherwise return to attempt to take the semaphore that is @@ -1772,7 +1838,7 @@ BaseType_t xQueuePeek( QueueHandle_t xQueue, { /* The queue was empty and no block time is specified (or * the block time has expired) so leave now. */ - taskEXIT_CRITICAL(); + taskEXIT_CRITICAL(); traceQUEUE_PEEK_FAILED( pxQueue ); return errQUEUE_EMPTY; } @@ -1796,7 +1862,11 @@ BaseType_t xQueuePeek( QueueHandle_t xQueue, /* Interrupts and other tasks can send to and receive from the queue * now the critical section has been exited. */ +#ifdef ESP_PLATFORM // IDF-3755 taskENTER_CRITICAL(); +#else + vTaskSuspendAll(); +#endif // ESP_PLATFORM prvLockQueue( pxQueue ); /* Update the timeout state to see if it has expired yet. */ @@ -1809,15 +1879,31 @@ BaseType_t xQueuePeek( QueueHandle_t xQueue, traceBLOCKING_ON_QUEUE_PEEK( pxQueue ); vTaskPlaceOnEventList( &( pxQueue->xTasksWaitingToReceive ), xTicksToWait ); prvUnlockQueue( pxQueue ); +#ifdef ESP_PLATFORM // IDF-3755 taskEXIT_CRITICAL(); - portYIELD_WITHIN_API(); +#else + if( xTaskResumeAll() == pdFALSE ) +#endif // ESP_PLATFORM + { + portYIELD_WITHIN_API(); + } +#ifndef ESP_PLATFORM + else + { + mtCOVERAGE_TEST_MARKER(); + } +#endif // ESP_PLATFORM } else { /* There is data in the queue now, so don't enter the blocked * state, instead return to try and obtain the data. */ prvUnlockQueue( pxQueue ); +#ifdef ESP_PLATFORM // IDF-3755 taskEXIT_CRITICAL(); +#else + ( void ) xTaskResumeAll(); +#endif // ESP_PLATFORM } } else @@ -1825,7 +1911,11 @@ BaseType_t xQueuePeek( QueueHandle_t xQueue, /* The timeout has expired. If there is still no data in the queue * exit, otherwise go back and try to read the data again. */ prvUnlockQueue( pxQueue ); +#ifdef ESP_PLATFORM // IDF-3755 taskEXIT_CRITICAL(); +#else + ( void ) xTaskResumeAll(); +#endif // ESP_PLATFORM if( prvIsQueueEmpty( pxQueue ) != pdFALSE ) { diff --git a/components/freertos/stream_buffer.c b/components/freertos/stream_buffer.c index 00ea670238..e989643033 100644 --- a/components/freertos/stream_buffer.c +++ b/components/freertos/stream_buffer.c @@ -64,7 +64,9 @@ * or #defined the notification macros away, then provide default implementations * that uses task notifications. */ /*lint -save -e9026 Function like macros allowed and needed here so they can be overridden. */ + #ifndef sbRECEIVE_COMPLETED +#ifdef ESP_PLATFORM // IDF-3775 #define sbRECEIVE_COMPLETED( pxStreamBuffer ) \ taskENTER_CRITICAL(); \ { \ @@ -77,6 +79,20 @@ } \ } \ taskEXIT_CRITICAL(); +#else + #define sbRECEIVE_COMPLETED( pxStreamBuffer ) \ + vTaskSuspendAll(); \ + { \ + if( ( pxStreamBuffer )->xTaskWaitingToSend != NULL ) \ + { \ + ( void ) xTaskNotify( ( pxStreamBuffer )->xTaskWaitingToSend, \ + ( uint32_t ) 0, \ + eNoAction ); \ + ( pxStreamBuffer )->xTaskWaitingToSend = NULL; \ + } \ + } \ + ( void ) xTaskResumeAll(); +#endif // ESP_PLATFORM #endif /* sbRECEIVE_COMPLETED */ #ifndef sbRECEIVE_COMPLETED_FROM_ISR @@ -104,6 +120,7 @@ * or #defined the notification macro away, them provide a default implementation * that uses task notifications. */ #ifndef sbSEND_COMPLETED +#ifdef ESP_PLATFORM // IDF-3755 #define sbSEND_COMPLETED( pxStreamBuffer ) \ taskENTER_CRITICAL(); \ { \ @@ -116,6 +133,20 @@ } \ } \ taskEXIT_CRITICAL(); +#else + #define sbSEND_COMPLETED( pxStreamBuffer ) \ + vTaskSuspendAll(); \ + { \ + if( ( pxStreamBuffer )->xTaskWaitingToReceive != NULL ) \ + { \ + ( void ) xTaskNotify( ( pxStreamBuffer )->xTaskWaitingToReceive, \ + ( uint32_t ) 0, \ + eNoAction ); \ + ( pxStreamBuffer )->xTaskWaitingToReceive = NULL; \ + } \ + } \ + ( void ) xTaskResumeAll(); +#endif // ESP_PLATFORM #endif /* sbSEND_COMPLETED */ #ifndef sbSEND_COMPLETE_FROM_ISR @@ -163,7 +194,9 @@ typedef struct StreamBufferDef_t /*lint !e9058 Style convention #if ( configUSE_TRACE_FACILITY == 1 ) UBaseType_t uxStreamBufferNumber; /* Used for tracing purposes. */ #endif +#ifdef ESP_PLATFORM portMUX_TYPE xStreamBufferMux; //Mutex required due to SMP +#endif // ESP_PLATFORM } StreamBuffer_t; /* @@ -539,6 +572,10 @@ size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, size_t xRequiredSpace = xDataLengthBytes; TimeOut_t xTimeOut; + /* The maximum amount of space a stream buffer will ever report is its length + * minus 1. */ + const size_t xMaxReportedSpace = pxStreamBuffer->xLength - ( size_t ) 1; + configASSERT( pvTxData ); configASSERT( pxStreamBuffer ); @@ -552,10 +589,33 @@ size_t xStreamBufferSend( StreamBufferHandle_t xStreamBuffer, /* Overflow? */ configASSERT( xRequiredSpace > xDataLengthBytes ); + + /* If this is a message buffer then it must be possible to write the + * whole message. */ + if( xRequiredSpace > xMaxReportedSpace ) + { + /* The message would not fit even if the entire buffer was empty, + * so don't wait for space. */ + xTicksToWait = ( TickType_t ) 0; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } } else { - mtCOVERAGE_TEST_MARKER(); + /* If this is a stream buffer then it is acceptable to write only part + * of the message to the buffer. Cap the length to the total length of + * the buffer. */ + if( xRequiredSpace > xMaxReportedSpace ) + { + xRequiredSpace = xMaxReportedSpace; + } + else + { + mtCOVERAGE_TEST_MARKER(); + } } if( xTicksToWait != ( TickType_t ) 0 ) @@ -1266,7 +1326,9 @@ static void prvInitialiseNewStreamBuffer( StreamBuffer_t * const pxStreamBuffer, pxStreamBuffer->xLength = xBufferSizeBytes; pxStreamBuffer->xTriggerLevelBytes = xTriggerLevelBytes; pxStreamBuffer->ucFlags = ucFlags; +#ifdef ESP_PLATFORM vPortCPUInitializeMutex( &pxStreamBuffer->xStreamBufferMux ); +#endif // ESP_PLATFORM } #if ( configUSE_TRACE_FACILITY == 1 ) diff --git a/components/freertos/tasks.c b/components/freertos/tasks.c index e91616233e..388aebc850 100644 --- a/components/freertos/tasks.c +++ b/components/freertos/tasks.c @@ -576,7 +576,7 @@ static void prvAddCurrentTaskToDelayedList( const portBASE_TYPE xCoreID, * Set xNextTaskUnblockTime to the time at which the next Blocked state task * will exit the Blocked state. */ -static void prvResetNextTaskUnblockTime( void ); +static void prvResetNextTaskUnblockTime( void ) PRIVILEGED_FUNCTION; #if ( ( configUSE_TRACE_FACILITY == 1 ) && ( configUSE_STATS_FORMATTING_FUNCTIONS > 0 ) ) @@ -671,15 +671,15 @@ void taskYIELD_OTHER_CORE( BaseType_t xCoreID, UBaseType_t uxPriority ) configASSERT( portVALID_STACK_MEM(pxStackBuffer) ); configASSERT( (xCoreID>=0 && xCoreID ( TickType_t ) 0U ) { configASSERT( uxSchedulerSuspended[xPortGetCoreID()] == 0 ); +#ifdef ESP_PLATFORM // IDF-3755 taskENTER_CRITICAL(); +#else + vTaskSuspendAll(); +#endif // ESP_PLATFORM { traceTASK_DELAY(); @@ -1572,7 +1577,11 @@ static void prvAddNewTaskToReadyList( TCB_t * pxNewTCB, * executing task. */ prvAddCurrentTaskToDelayedList( xPortGetCoreID(), xTicksToDelay ); } +#ifdef ESP_PLATFORM // IDF-3755 taskEXIT_CRITICAL(); +#else + xAlreadyYielded = xTaskResumeAll(); +#endif // ESP_PLATFORM } else { @@ -2760,7 +2769,11 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char /* Task names will be truncated to configMAX_TASK_NAME_LEN - 1 bytes. */ configASSERT( strlen( pcNameToQuery ) < configMAX_TASK_NAME_LEN ); +#ifdef ESP_PLATFORM // IDF-3755 taskENTER_CRITICAL(); +#else + vTaskSuspendAll(); +#endif // ESP_PLATFORM { /* Search the ready lists. */ do @@ -2806,7 +2819,11 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char } #endif } +#ifdef ESP_PLATFORM // IDF-3755 taskEXIT_CRITICAL(); +#else + ( void ) xTaskResumeAll(); +#endif // ESP_PLATFORM return pxTCB; } @@ -2822,7 +2839,11 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char { UBaseType_t uxTask = 0, uxQueue = configMAX_PRIORITIES; +#ifdef ESP_PLATFORM // IDF-3755 taskENTER_CRITICAL(); +#else + vTaskSuspendAll(); +#endif // ESP_PLATFORM { /* Is there a space in the array for each task in the system? */ if( uxArraySize >= uxCurrentNumberOfTasks ) @@ -2881,7 +2902,11 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char mtCOVERAGE_TEST_MARKER(); } } +#ifdef ESP_PLATFORM // IDF-3755 taskEXIT_CRITICAL(); +#else + ( void ) xTaskResumeAll(); +#endif // ESP_PLATFORM return uxTask; } @@ -2931,7 +2956,11 @@ char * pcTaskGetName( TaskHandle_t xTaskToQuery ) /*lint !e971 Unqualified char BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) { +#ifdef ESP_PLATFORM BaseType_t xYieldRequired = pdFALSE; +#else + BaseType_t xYieldOccurred; +#endif // ESP_PLATFORM /* Must not be called with the scheduler suspended as the implementation * relies on xPendedTicks being wound down to 0 in xTaskResumeAll(). */ @@ -2939,11 +2968,20 @@ BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) /* Use xPendedTicks to mimic xTicksToCatchUp number of ticks occuring when * the scheduler is suspended so the ticks are executed in xTaskResumeAll(). */ +#ifdef ESP_PLATFORM // IDF-3755 taskENTER_CRITICAL(); +#else + vTaskSuspendAll(); +#endif // ESP_PLATFORM xPendedTicks += xTicksToCatchUp; +#ifdef ESP_PLATFORM // IDF-3755 taskEXIT_CRITICAL(); - return xYieldRequired; +#else + xYieldOccurred = xTaskResumeAll(); + + return xYieldOccurred; +#endif // ESP_PLATFORM } /*----------------------------------------------------------*/ @@ -2956,7 +2994,11 @@ BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) configASSERT( pxTCB ); +#ifdef ESP_PLATFORM // IDF-3755 taskENTER_CRITICAL(); +#else + vTaskSuspendAll(); +#endif // ESP_PLATFORM { /* A task can only be prematurely removed from the Blocked state if * it is actually in the Blocked state. */ @@ -3019,7 +3061,11 @@ BaseType_t xTaskCatchUpTicks( TickType_t xTicksToCatchUp ) xReturn = pdFAIL; } } +#ifdef ESP_PLATFORM // IDF-3755 taskEXIT_CRITICAL(); +#else + ( void ) xTaskResumeAll(); +#endif // ESP_PLATFORM return xReturn; } @@ -3933,7 +3979,11 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters ) if( xExpectedIdleTime >= configEXPECTED_IDLE_TIME_BEFORE_SLEEP ) { +#ifdef ESP_PLATFORM // IDF-3755 taskENTER_CRITICAL(); +#else + vTaskSuspendAll(); +#endif // ESP_PLATFORM { /* Now the scheduler is suspended, the expected idle * time can be sampled again, and this time its value can @@ -3957,7 +4007,11 @@ static portTASK_FUNCTION( prvIdleTask, pvParameters ) mtCOVERAGE_TEST_MARKER(); } } +#ifdef ESP_PLATFORM // IDF-3755 taskEXIT_CRITICAL(); +#else + ( void ) xTaskResumeAll(); +#endif // ESP_PLATFORM } else { @@ -4258,14 +4312,22 @@ static void prvCheckTasksWaitingTermination( void ) * it should be reported as being in the Blocked state. */ if( eState == eSuspended ) { - taskENTER_CRITICAL(); +#ifdef ESP_PLATFORM // IDF-3755 + taskENTER_CRITICAL(); +#else + vTaskSuspendAll(); +#endif // ESP_PLATFORM { if( listLIST_ITEM_CONTAINER( &( pxTCB->xEventListItem ) ) != NULL ) { pxTaskStatus->eCurrentState = eBlocked; } } - taskEXIT_CRITICAL(); +#ifdef ESP_PLATFORM // IDF-3755 + taskEXIT_CRITICAL(); +#else + ( void ) xTaskResumeAll(); +#endif // ESP_PLATFORM } } #endif /* INCLUDE_vTaskSuspend */ diff --git a/components/freertos/timers.c b/components/freertos/timers.c index 2a97723496..e5e313b64f 100644 --- a/components/freertos/timers.c +++ b/components/freertos/timers.c @@ -608,7 +608,11 @@ PRIVILEGED_DATA portMUX_TYPE xTimerMux = portMUX_INITIALIZER_UNLOCKED; TickType_t xTimeNow; BaseType_t xTimerListsWereSwitched; +#ifdef ESP_PLATFORM taskENTER_CRITICAL(); +#else + vTaskSuspendAll(); +#endif // ESP_PLATFORM { /* Obtain the time now to make an assessment as to whether the timer * has expired or not. If obtaining the time causes the lists to switch @@ -622,7 +626,11 @@ PRIVILEGED_DATA portMUX_TYPE xTimerMux = portMUX_INITIALIZER_UNLOCKED; /* The tick count has not overflowed, has the timer expired? */ if( ( xListWasEmpty == pdFALSE ) && ( xNextExpireTime <= xTimeNow ) ) { +#ifdef ESP_PLATFORM taskEXIT_CRITICAL(); +#else + ( void ) xTaskResumeAll(); +#endif // ESP_PLATFORM prvProcessExpiredTimer( xNextExpireTime, xTimeNow ); } else @@ -642,19 +650,33 @@ PRIVILEGED_DATA portMUX_TYPE xTimerMux = portMUX_INITIALIZER_UNLOCKED; vQueueWaitForMessageRestricted( xTimerQueue, ( xNextExpireTime - xTimeNow ), xListWasEmpty ); +#ifdef ESP_PLATFORM // IDF-3755 taskEXIT_CRITICAL(); - - /* Yield to wait for either a command to arrive, or the - * block time to expire. If a command arrived between the - * critical section being exited and this yield then the yield - * will not cause the task to block. */ - portYIELD_WITHIN_API(); - +#else + if( xTaskResumeAll() == pdFALSE ) +#endif // ESP_PLATFORM + { + /* Yield to wait for either a command to arrive, or the + * block time to expire. If a command arrived between the + * critical section being exited and this yield then the yield + * will not cause the task to block. */ + portYIELD_WITHIN_API(); + } +#ifndef ESP_PLATFORM // IDF-3755 + else + { + mtCOVERAGE_TEST_MARKER(); + } +#endif // ESP_PLATFORM } } else { +#ifdef ESP_PLATFORM // IDF-3755 taskEXIT_CRITICAL(); +#else + ( void ) xTaskResumeAll(); +#endif // ESP_PLATFORM } } } @@ -986,8 +1008,8 @@ PRIVILEGED_DATA portMUX_TYPE xTimerMux = portMUX_INITIALIZER_UNLOCKED; { /* The timer queue is allocated statically in case * configSUPPORT_DYNAMIC_ALLOCATION is 0. */ - static StaticQueue_t xStaticTimerQueue; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */ - static uint8_t ucStaticTimerQueueStorage[ ( size_t ) configTIMER_QUEUE_LENGTH * sizeof( DaemonTaskMessage_t ) ]; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */ + PRIVILEGED_DATA static StaticQueue_t xStaticTimerQueue; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */ + PRIVILEGED_DATA static uint8_t ucStaticTimerQueueStorage[ ( size_t ) configTIMER_QUEUE_LENGTH * sizeof( DaemonTaskMessage_t ) ]; /*lint !e956 Ok to declare in this manner to prevent additional conditional compilation guards in other locations. */ xTimerQueue = xQueueCreateStatic( ( UBaseType_t ) configTIMER_QUEUE_LENGTH, ( UBaseType_t ) sizeof( DaemonTaskMessage_t ), &( ucStaticTimerQueueStorage[ 0 ] ), &xStaticTimerQueue ); }