diff --git a/portable/ThirdParty/GCC/Posix/port.c b/portable/ThirdParty/GCC/Posix/port.c index 4f7d8b609..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 @@ -97,6 +102,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 +111,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 +139,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 +147,7 @@ static void prvMarkAsFreeRTOSThread( void ) { uint8_t * pucThreadData = NULL; - prvInitThreadKey(); + ( void ) pthread_once( &hThreadKeyOnce, prvInitThreadKey ); pucThreadData = malloc( 1 ); configASSERT( pucThreadData != NULL ); @@ -165,7 +163,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 +193,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 +270,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 +304,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; + hSigSetupThread = ( pthread_once_t ) PTHREAD_ONCE_INIT; + hThreadKeyOnce = ( pthread_once_t ) PTHREAD_ONCE_INIT; #endif /* __APPLE__*/ /* Restore original signal mask. */ @@ -392,7 +396,7 @@ void vPortDisableInterrupts( void ) { if( prvIsFreeRTOSThread() == pdTRUE ) { - pthread_sigmask(SIG_BLOCK, &xAllSignals, NULL); + pthread_sigmask( SIG_BLOCK, &xAllSignals, NULL ); } } /*-----------------------------------------------------------*/ @@ -540,7 +544,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 ); 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 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'; }