From ae0a5913c8b95276e5a53122bfbf6d505a297ba7 Mon Sep 17 00:00:00 2001 From: Rahul Kar <118818625+kar-rahul-aws@users.noreply.github.com> Date: Thu, 6 Feb 2025 14:41:19 +0530 Subject: [PATCH 1/5] Call key creation before checking if a thread is FreeRTOS (#1238) --- portable/ThirdParty/GCC/Posix/port.c | 39 ++++++++++++++-------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/portable/ThirdParty/GCC/Posix/port.c b/portable/ThirdParty/GCC/Posix/port.c index 4f7d8b609..66095fb2c 100644 --- a/portable/ThirdParty/GCC/Posix/port.c +++ b/portable/ThirdParty/GCC/Posix/port.c @@ -97,6 +97,7 @@ static inline Thread_t * prvGetThreadFromTask( TaskHandle_t xTask ) /*-----------------------------------------------------------*/ static pthread_once_t hSigSetupThread = PTHREAD_ONCE_INIT; +static pthread_once_t hThreadKeyOnce = PTHREAD_ONCE_INIT; static sigset_t xAllSignals; static sigset_t xSchedulerOriginalSignalMask; static pthread_t hMainThread = ( pthread_t ) NULL; @@ -105,7 +106,6 @@ static BaseType_t xSchedulerEnd = pdFALSE; static pthread_t hTimerTickThread; static bool xTimerTickThreadShouldRun; static uint64_t prvStartTimeNs; -static pthread_mutex_t xThreadMutex = PTHREAD_MUTEX_INITIALIZER; static pthread_key_t xThreadKey = 0; /*-----------------------------------------------------------*/ @@ -134,14 +134,7 @@ static void prvThreadKeyDestructor( void * pvData ) static void prvInitThreadKey( void ) { - pthread_mutex_lock( &xThreadMutex ); - - if( xThreadKey == 0 ) - { - pthread_key_create( &xThreadKey, prvThreadKeyDestructor ); - } - - pthread_mutex_unlock( &xThreadMutex ); + pthread_key_create( &xThreadKey, prvThreadKeyDestructor ); } /*-----------------------------------------------------------*/ @@ -149,7 +142,7 @@ static void prvMarkAsFreeRTOSThread( void ) { uint8_t * pucThreadData = NULL; - prvInitThreadKey(); + ( void ) pthread_once( &hThreadKeyOnce, prvInitThreadKey ); pucThreadData = malloc( 1 ); configASSERT( pucThreadData != NULL ); @@ -165,7 +158,10 @@ static BaseType_t prvIsFreeRTOSThread( void ) uint8_t * pucThreadData = NULL; BaseType_t xRet = pdFALSE; + ( void ) pthread_once( &hThreadKeyOnce, prvInitThreadKey ); + pucThreadData = ( uint8_t * ) pthread_getspecific( xThreadKey ); + if( ( pucThreadData != NULL ) && ( *pucThreadData == 1 ) ) { xRet = pdTRUE; @@ -192,13 +188,13 @@ void prvFatalError( const char * pcCall, } /*-----------------------------------------------------------*/ -static void prvPortSetCurrentThreadName(char * pxThreadName) +static void prvPortSetCurrentThreadName( char * pxThreadName ) { -#ifdef __APPLE__ - pthread_setname_np(pxThreadName); -#else - pthread_setname_np(pthread_self(), pxThreadName); -#endif + #ifdef __APPLE__ + pthread_setname_np( pxThreadName ); + #else + pthread_setname_np( pthread_self(), pxThreadName ); + #endif } /*-----------------------------------------------------------*/ @@ -269,7 +265,7 @@ BaseType_t xPortStartScheduler( void ) sigset_t xSignals; hMainThread = pthread_self(); - prvPortSetCurrentThreadName("Scheduler"); + prvPortSetCurrentThreadName( "Scheduler" ); /* Start the timer that generates the tick ISR(SIGALRM). * Interrupts are disabled here already. */ @@ -303,9 +299,12 @@ BaseType_t xPortStartScheduler( void ) * memset the internal struct members for MacOS/Linux Compatibility */ #if __APPLE__ hSigSetupThread.__sig = _PTHREAD_ONCE_SIG_init; - memset( ( void * ) &hSigSetupThread.__opaque, 0, sizeof(hSigSetupThread.__opaque)); + hThreadKeyOnce.__sig = _PTHREAD_ONCE_SIG_init; + memset( ( void * ) &hSigSetupThread.__opaque, 0, sizeof( hSigSetupThread.__opaque ) ); + memset( ( void * ) &hThreadKeyOnce.__opaque, 0, sizeof( hThreadKeyOnce.__opaque ) ); #else /* Linux PTHREAD library*/ hSigSetupThread = PTHREAD_ONCE_INIT; + hThreadKeyOnce = PTHREAD_ONCE_INIT; #endif /* __APPLE__*/ /* Restore original signal mask. */ @@ -392,7 +391,7 @@ void vPortDisableInterrupts( void ) { if( prvIsFreeRTOSThread() == pdTRUE ) { - pthread_sigmask(SIG_BLOCK, &xAllSignals, NULL); + pthread_sigmask( SIG_BLOCK, &xAllSignals, NULL ); } } /*-----------------------------------------------------------*/ @@ -540,7 +539,7 @@ static void * prvWaitForStart( void * pvParams ) vPortEnableInterrupts(); /* Set thread name */ - prvPortSetCurrentThreadName(pcTaskGetName(xTaskGetCurrentTaskHandle())); + prvPortSetCurrentThreadName( pcTaskGetName( xTaskGetCurrentTaskHandle() ) ); /* Call the task's entry point. */ pxThread->pxCode( pxThread->pvParams ); From d10ee468114afb06ee6eca8f976c7b953aa5a2b8 Mon Sep 17 00:00:00 2001 From: Jakub Tymejczyk Date: Fri, 7 Feb 2025 02:21:34 +0100 Subject: [PATCH 2/5] Fix GCC/Posix port compilation on FreeBSD (#1239) (#1240) On FreeBSD pthread_once_t is a struct and cast is required. Otherwise there's compilation error: ../../mocks/freertos/port.c:261:23: error: expected expression hSigSetupThread = PTHREAD_ONCE_INIT; ^ PTHREAD_ONCE_INIT is defined as: { PTHREAD_NEEDS_INIT, NULL } on FreeBSD Co-authored-by: Jakub Tymejczyk --- portable/ThirdParty/GCC/Posix/port.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/portable/ThirdParty/GCC/Posix/port.c b/portable/ThirdParty/GCC/Posix/port.c index 66095fb2c..5dc7f45f8 100644 --- a/portable/ThirdParty/GCC/Posix/port.c +++ b/portable/ThirdParty/GCC/Posix/port.c @@ -303,8 +303,8 @@ BaseType_t xPortStartScheduler( void ) memset( ( void * ) &hSigSetupThread.__opaque, 0, sizeof( hSigSetupThread.__opaque ) ); memset( ( void * ) &hThreadKeyOnce.__opaque, 0, sizeof( hThreadKeyOnce.__opaque ) ); #else /* Linux PTHREAD library*/ - hSigSetupThread = PTHREAD_ONCE_INIT; - hThreadKeyOnce = PTHREAD_ONCE_INIT; + hSigSetupThread = ( pthread_once_t ) PTHREAD_ONCE_INIT; + hThreadKeyOnce = ( pthread_once_t ) PTHREAD_ONCE_INIT; #endif /* __APPLE__*/ /* Restore original signal mask. */ From a470b2d3755b5aaad71f4fdae0ca4a8361b4303a Mon Sep 17 00:00:00 2001 From: Graham Sanderson Date: Sun, 9 Feb 2025 23:32:36 -0600 Subject: [PATCH 3/5] RP2040: update FreeRTOS_Kernel_import.cmake to match the newer version in Community-Supported-Ports (#1243) - The newer version looks in Community-Supported-Ports too Co-authored-by: graham sanderson --- .../GCC/RP2040/FreeRTOS_Kernel_import.cmake | 90 ++++++++++++------- 1 file changed, 60 insertions(+), 30 deletions(-) diff --git a/portable/ThirdParty/GCC/RP2040/FreeRTOS_Kernel_import.cmake b/portable/ThirdParty/GCC/RP2040/FreeRTOS_Kernel_import.cmake index 109a54e19..854aab43f 100644 --- a/portable/ThirdParty/GCC/RP2040/FreeRTOS_Kernel_import.cmake +++ b/portable/ThirdParty/GCC/RP2040/FreeRTOS_Kernel_import.cmake @@ -10,38 +10,68 @@ if (DEFINED ENV{FREERTOS_KERNEL_PATH} AND (NOT FREERTOS_KERNEL_PATH)) message("Using FREERTOS_KERNEL_PATH from environment ('${FREERTOS_KERNEL_PATH}')") endif () -set(FREERTOS_KERNEL_RP2040_RELATIVE_PATH "portable/ThirdParty/GCC/RP2040") -# undo the above -set(FREERTOS_KERNEL_RP2040_BACK_PATH "../../../..") - -if (NOT FREERTOS_KERNEL_PATH) - # check if we are inside the FreeRTOS kernel tree (i.e. this file has been included directly) - get_filename_component(_ACTUAL_PATH ${CMAKE_CURRENT_LIST_DIR} REALPATH) - get_filename_component(_POSSIBLE_PATH ${CMAKE_CURRENT_LIST_DIR}/${FREERTOS_KERNEL_RP2040_BACK_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH} REALPATH) - if (_ACTUAL_PATH STREQUAL _POSSIBLE_PATH) - get_filename_component(FREERTOS_KERNEL_PATH ${CMAKE_CURRENT_LIST_DIR}/${FREERTOS_KERNEL_RP2040_BACK_PATH} REALPATH) +# first pass we look in old tree; second pass we look in new tree +foreach(SEARCH_PASS RANGE 0 1) + if (SEARCH_PASS) + # ports may be moving to submodule in the future + set(FREERTOS_KERNEL_RP2040_RELATIVE_PATH "portable/ThirdParty/Community-Supported-Ports/GCC") + set(FREERTOS_KERNEL_RP2040_BACK_PATH "../../../../..") + else() + set(FREERTOS_KERNEL_RP2040_RELATIVE_PATH "portable/ThirdParty/GCC") + set(FREERTOS_KERNEL_RP2040_BACK_PATH "../../../..") endif() - if (_ACTUAL_PATH STREQUAL _POSSIBLE_PATH) - get_filename_component(FREERTOS_KERNEL_PATH ${CMAKE_CURRENT_LIST_DIR}/${FREERTOS_KERNEL_RP2040_BACK_PATH} REALPATH) - message("Setting FREERTOS_KERNEL_PATH to ${FREERTOS_KERNEL_PATH} based on location of FreeRTOS-Kernel-import.cmake") - elseif (PICO_SDK_PATH AND EXISTS "${PICO_SDK_PATH}/../FreeRTOS-Kernel") - set(FREERTOS_KERNEL_PATH ${PICO_SDK_PATH}/../FreeRTOS-Kernel) - message("Defaulting FREERTOS_KERNEL_PATH as sibling of PICO_SDK_PATH: ${FREERTOS_KERNEL_PATH}") - endif() -endif () -if (NOT FREERTOS_KERNEL_PATH) - foreach(POSSIBLE_SUFFIX Source FreeRTOS-Kernel FreeRTOS/Source) - # check if FreeRTOS-Kernel exists under directory that included us - set(SEARCH_ROOT ${CMAKE_CURRENT_SOURCE_DIR}) - get_filename_component(_POSSIBLE_PATH ${SEARCH_ROOT}/${POSSIBLE_SUFFIX} REALPATH) - if (EXISTS ${_POSSIBLE_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/CMakeLists.txt) - get_filename_component(FREERTOS_KERNEL_PATH ${_POSSIBLE_PATH} REALPATH) - message("Setting FREERTOS_KERNEL_PATH to '${FREERTOS_KERNEL_PATH}' found relative to enclosing project") + if(PICO_PLATFORM STREQUAL "rp2040") + set(FREERTOS_KERNEL_RP2040_RELATIVE_PATH "${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/RP2040") + else() + if (PICO_PLATFORM STREQUAL "rp2350-riscv") + set(FREERTOS_KERNEL_RP2040_RELATIVE_PATH "${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/RP2350_RISC-V") + else() + set(FREERTOS_KERNEL_RP2040_RELATIVE_PATH "${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/RP2350_ARM_NTZ") + endif() + endif() + + if (NOT FREERTOS_KERNEL_PATH) + # check if we are inside the FreeRTOS kernel tree (i.e. this file has been included directly) + get_filename_component(_ACTUAL_PATH ${CMAKE_CURRENT_LIST_DIR} REALPATH) + get_filename_component(_POSSIBLE_PATH ${CMAKE_CURRENT_LIST_DIR}/${FREERTOS_KERNEL_RP2040_BACK_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH} REALPATH) + if (_ACTUAL_PATH STREQUAL _POSSIBLE_PATH) + get_filename_component(FREERTOS_KERNEL_PATH ${CMAKE_CURRENT_LIST_DIR}/${FREERTOS_KERNEL_RP2040_BACK_PATH} REALPATH) + endif() + if (_ACTUAL_PATH STREQUAL _POSSIBLE_PATH) + get_filename_component(FREERTOS_KERNEL_PATH ${CMAKE_CURRENT_LIST_DIR}/${FREERTOS_KERNEL_RP2040_BACK_PATH} REALPATH) + message("Setting FREERTOS_KERNEL_PATH to ${FREERTOS_KERNEL_PATH} based on location of FreeRTOS-Kernel-import.cmake") + break() + elseif (PICO_SDK_PATH AND EXISTS "${PICO_SDK_PATH}/../FreeRTOS-Kernel") + set(FREERTOS_KERNEL_PATH ${PICO_SDK_PATH}/../FreeRTOS-Kernel) + message("Defaulting FREERTOS_KERNEL_PATH as sibling of PICO_SDK_PATH: ${FREERTOS_KERNEL_PATH}") break() endif() - endforeach() -endif() + endif () + + if (NOT FREERTOS_KERNEL_PATH) + foreach(POSSIBLE_SUFFIX Source FreeRTOS-Kernel FreeRTOS/Source) + # check if FreeRTOS-Kernel exists under directory that included us + set(SEARCH_ROOT ${CMAKE_CURRENT_SOURCE_DIR}) + get_filename_component(_POSSIBLE_PATH ${SEARCH_ROOT}/${POSSIBLE_SUFFIX} REALPATH) + if (EXISTS ${_POSSIBLE_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/CMakeLists.txt) + get_filename_component(FREERTOS_KERNEL_PATH ${_POSSIBLE_PATH} REALPATH) + message("Setting FREERTOS_KERNEL_PATH to '${FREERTOS_KERNEL_PATH}' found relative to enclosing project") + break() + endif() + endforeach() + if (FREERTOS_KERNEL_PATH) + break() + endif() + endif() + + # user must have specified + if (FREERTOS_KERNEL_PATH) + if (EXISTS "${FREERTOS_KERNEL_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}") + break() + endif() + endif() +endforeach () if (NOT FREERTOS_KERNEL_PATH) message(FATAL_ERROR "FreeRTOS location was not specified. Please set FREERTOS_KERNEL_PATH.") @@ -54,8 +84,8 @@ if (NOT EXISTS ${FREERTOS_KERNEL_PATH}) message(FATAL_ERROR "Directory '${FREERTOS_KERNEL_PATH}' not found") endif() if (NOT EXISTS ${FREERTOS_KERNEL_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/CMakeLists.txt) - message(FATAL_ERROR "Directory '${FREERTOS_KERNEL_PATH}' does not contain an RP2040 port here: ${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}") + message(FATAL_ERROR "Directory '${FREERTOS_KERNEL_PATH}' does not contain a '${PICO_PLATFORM}' port here: ${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}") endif() set(FREERTOS_KERNEL_PATH ${FREERTOS_KERNEL_PATH} CACHE PATH "Path to the FreeRTOS_KERNEL" FORCE) -add_subdirectory(${FREERTOS_KERNEL_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH} FREERTOS_KERNEL) +add_subdirectory(${FREERTOS_KERNEL_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH} FREERTOS_KERNEL) \ No newline at end of file From fbaeba352ec22a088b7f88a67430f7c03409e81a Mon Sep 17 00:00:00 2001 From: Sudeep Mohanty <91244425+sudeep-mohanty@users.noreply.github.com> Date: Mon, 10 Feb 2025 09:17:36 +0100 Subject: [PATCH 4/5] fix(freertos): Correct taskRESERVED_TASK_NAME_LENGTH macro definition (#1241) This commit updates the definition of taskRESERVED_TASK_NAME_LENGTH in tasks.c to fix an unreachable preprocessor condition. Signed-off-by: Sudeep Mohanty Co-authored-by: Gaurav-Aggarwal-AWS <33462878+aggarg@users.noreply.github.com> --- tasks.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/tasks.c b/tasks.c index 518c9e87f..783f54810 100644 --- a/tasks.c +++ b/tasks.c @@ -156,16 +156,15 @@ #define configIDLE_TASK_NAME "IDLE" #endif +/* Reserve space for Core ID and null termination. */ #if ( configNUMBER_OF_CORES > 1 ) - /* Reserve space for Core ID and null termination. */ + /* Multi-core systems with up to 9 cores require 1 character for core ID and 1 for null termination. */ #if ( configMAX_TASK_NAME_LEN < 2U ) #error Minimum required task name length is 2. Please increase configMAX_TASK_NAME_LEN. #endif #define taskRESERVED_TASK_NAME_LENGTH 2U -#elif ( configNUMBER_OF_CORES > 9 ) - #warning Please increase taskRESERVED_TASK_NAME_LENGTH. 1 character is insufficient to store the core ID. -#else +#else /* if ( configNUMBER_OF_CORES > 1 ) */ /* Reserve space for null termination. */ #if ( configMAX_TASK_NAME_LEN < 1U ) #error Minimum required task name length is 1. Please increase configMAX_TASK_NAME_LEN. @@ -3597,7 +3596,12 @@ static BaseType_t prvCreateIdleTasks( void ) * only one idle task. */ #if ( configNUMBER_OF_CORES > 1 ) { - /* Append the idle task number to the end of the name. */ + /* Append the idle task number to the end of the name. + * + * Note: Idle task name index only supports single-character + * core IDs (0-9). If the core ID exceeds 9, the idle task + * name will contain an incorrect ASCII character. This is + * acceptable as the task name is used mainly for debugging. */ cIdleName[ xIdleTaskNameIndex ] = ( char ) ( xCoreID + '0' ); cIdleName[ xIdleTaskNameIndex + 1 ] = '\0'; } From 51a1598e4e0281de8b8d54467747af460478eadc Mon Sep 17 00:00:00 2001 From: Bhoomika R S Date: Wed, 12 Feb 2025 14:57:03 +0530 Subject: [PATCH 5/5] Add instruction to suppress SIGUSR1 in Posix with LLDB debugger (#1245) While using the macOS default LLDB debugger, a call to vTaskEndScheduler results in an unhandled SIGUSR1 (aka SIGRESUME) when restoring the scheduler thread's signals with pthread_sigmask. This crashes the program. Added instructions in portable/ThirdParty/GCC/Posix/port.c to suppress SIGUSR1 to prevent LLDB debugger interference when exiting xPortStartScheduler Thanks to: @johnboiles for pointing it out in #1224 --- portable/ThirdParty/GCC/Posix/port.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/portable/ThirdParty/GCC/Posix/port.c b/portable/ThirdParty/GCC/Posix/port.c index 5dc7f45f8..ff386ac9f 100644 --- a/portable/ThirdParty/GCC/Posix/port.c +++ b/portable/ThirdParty/GCC/Posix/port.c @@ -48,6 +48,11 @@ * stdio (printf() and friends) should be called from a single task * only or serialized with a FreeRTOS primitive such as a binary * semaphore or mutex. +* +* Note: When using LLDB (the default debugger on macOS) with this port, +* suppress SIGUSR1 to prevent debugger interference. This can be +* done by adding the following line to ~/.lldbinit: +* `process handle SIGUSR1 -n true -p true -s false` *----------------------------------------------------------*/ #ifdef __linux__ #define _GNU_SOURCE