freertos: Add newlib dynamic reentrancy support

SMP FreeRTOS adds support for dynamic reentrancy in the following commit:
34b8e24d7c

This commit does the following:

- Pulls in the upstream changes
- Move __getreent() to "freertos_tasks_c_additions.h"
- Add the required configNEWLIB_REENTRANT_IS_DYNAMIC to SMP FreeRTOS port
This commit is contained in:
Darian Leung 2022-06-01 23:16:11 +08:00
parent 2d08431433
commit d8eb55d83b
5 changed files with 45 additions and 50 deletions

View File

@ -3180,7 +3180,7 @@ TaskHandle_t xTaskGetCurrentTaskHandle( void ) PRIVILEGED_FUNCTION;
/*
* Return the handle of the task running on specified core.
*/
TaskHandle_t xTaskGetCurrentTaskHandleCPU( BaseType_t xCoreID ) PRIVILEGED_FUNCTION;
TaskHandle_t xTaskGetCurrentTaskHandleCPU( UBaseType_t xCoreID ) PRIVILEGED_FUNCTION;
/*
* Shortcut used by the queue implementation to prevent unnecessary call to

View File

@ -177,6 +177,7 @@ This file get's pulled into assembly sources. Therefore, some includes need to b
#endif // CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS
#define configSTACK_DEPTH_TYPE uint32_t
#define configUSE_NEWLIB_REENTRANT 1
#define configNEWLIB_REENTRANT_IS_DYNAMIC 1 // IDF Newlib supports dynamic reentrancy. We provide our own __getreent() function
#define configENABLE_BACKWARD_COMPATIBILITY 0
#define configASSERT(a) assert(a)
#define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H 1

View File

@ -2860,17 +2860,18 @@ void vTaskStartScheduler( void )
* starts to run. */
portDISABLE_INTERRUPTS();
#if ( configUSE_NEWLIB_REENTRANT == 1 )
#if ( ( configUSE_NEWLIB_REENTRANT == 1 ) && ( configNEWLIB_REENTRANT_IS_DYNAMIC == 0 ) )
{
/* Switch Newlib's _impure_ptr variable to point to the _reent
* structure specific to the task that will run first.
* See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html
* for additional information. */
#ifndef ESP_PLATFORM
* for additional information.
*
* Note: Updating the _impure_ptr is not required when Newlib is compiled with
* __DYNAMIC_REENT__ enabled. The port should provide __getreent() instead. */
_impure_ptr = &( pxCurrentTCB->xNewLib_reent );
#endif
}
#endif /* configUSE_NEWLIB_REENTRANT */
#endif /* ( configUSE_NEWLIB_REENTRANT == 1 ) && ( configNEWLIB_REENTRANT_IS_DYNAMIC == 0 ) */
xNextTaskUnblockTime = portMAX_DELAY;
xSchedulerRunning = pdTRUE;
@ -3953,17 +3954,18 @@ void vTaskSwitchContext( BaseType_t xCoreID )
}
#endif
#if ( configUSE_NEWLIB_REENTRANT == 1 )
#if ( ( configUSE_NEWLIB_REENTRANT == 1 ) && ( configNEWLIB_REENTRANT_IS_DYNAMIC == 0 ) )
{
/* Switch Newlib's _impure_ptr variable to point to the _reent
* structure specific to this task.
* See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html
* for additional information. */
#ifndef ESP_PLATFORM
* for additional information.
*
* Note: Updating the _impure_ptr is not required when Newlib is compiled with
* __DYNAMIC_REENT__ enabled. The the port should provide __getreent() instead. */
_impure_ptr = &( pxCurrentTCB->xNewLib_reent );
#endif
}
#endif /* configUSE_NEWLIB_REENTRANT */
#endif /* ( configUSE_NEWLIB_REENTRANT == 1 ) && ( configNEWLIB_REENTRANT_IS_DYNAMIC == 0 ) */
}
}
portRELEASE_ISR_LOCK();
@ -4918,7 +4920,6 @@ static void prvCheckTasksWaitingTermination( void )
static void prvDeleteTCB( TCB_t * pxTCB )
{
/* This call is required specifically for the TriCore port. It must be
* above the vPortFree() calls. The call is also used by ports/demos that
* want to allocate and clean RAM statically. */
@ -5008,7 +5009,7 @@ static void prvResetNextTaskUnblockTime( void )
return xReturn;
}
TaskHandle_t xTaskGetCurrentTaskHandleCPU( BaseType_t xCoreID )
TaskHandle_t xTaskGetCurrentTaskHandleCPU( UBaseType_t xCoreID )
{
TaskHandle_t xReturn = NULL;
@ -6440,24 +6441,3 @@ static void prvAddCurrentTaskToDelayedList( TickType_t xTicksToWait,
#endif
#endif /* if ( configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H == 1 ) */
/* ------------------------------------------------ IDF Compatibility --------------------------------------------------
*
* ------------------------------------------------------------------------------------------------------------------ */
#ifdef ESP_PLATFORM
#if ( configUSE_NEWLIB_REENTRANT == 1 )
//Return global reent struct if FreeRTOS isn't running,
struct _reent* __getreent(void) {
//No lock needed because if this changes, we won't be running anymore.
TCB_t *currTask=xTaskGetCurrentTaskHandle();
if (currTask==NULL) {
//No task running. Return global struct.
return _GLOBAL_REENT;
} else {
//We have a task; return its reentrant struct.
return &currTask->xNewLib_reent;
}
}
#endif
#endif //ESP_PLATFORM

View File

@ -2418,22 +2418,6 @@ void vTaskEndScheduler( void )
}
/*----------------------------------------------------------*/
#if ( configUSE_NEWLIB_REENTRANT == 1 )
//Return global reent struct if FreeRTOS isn't running,
struct _reent* __getreent(void) {
//No lock needed because if this changes, we won't be running anymore.
TCB_t *currTask=xTaskGetCurrentTaskHandle();
if (currTask==NULL) {
//No task running. Return global struct.
return _GLOBAL_REENT;
} else {
//We have a task; return its reentrant struct.
return &currTask->xNewLib_reent;
}
}
#endif
void vTaskSuspendAll( void )
{
/* A critical section is not required as the variable is of type

View File

@ -17,6 +17,36 @@
* `/additions` directory.
*/
/* ----------------------------------------------------- Newlib --------------------------------------------------------
*
* ------------------------------------------------------------------------------------------------------------------ */
#if ( configUSE_NEWLIB_REENTRANT == 1 )
/**
* @brief Get reentrancy structure of the current task
*
* - This funciton is required by newlib (when __DYNAMIC_REENT__ is enabled)
* - It will return a pointer to the current task's reent struct
* - If FreeRTOS is not running, it will return the global reent struct
*
* @return Pointer to a the (current taks's)/(globa) reent struct
*/
struct _reent *__getreent(void)
{
// No lock needed because if this changes, we won't be running anymore.
TCB_t *pxCurTask = xTaskGetCurrentTaskHandle();
struct _reent *ret;
if (pxCurTask == NULL) {
// No task running. Return global struct.
ret = _GLOBAL_REENT;
} else {
// We have a task; return its reentrant struct.
ret = &pxCurTask->xNewLib_reent;
}
return ret;
}
#endif // configUSE_NEWLIB_REENTRANT == 1
/* -------------------------------------------------- Task Snapshot ----------------------------------------------------
*
* ------------------------------------------------------------------------------------------------------------------ */