RP2040 fixes (#424)

* RP2040: malloc needs to be thread safe for FreeRTOS whether both cores are used or not

* RP2040: CMake file had broken left over test code

* RP2040: portIS_FREE_RTOS_CORE() returned an incorrect value prior to scheduler init when the application was compiled without multicore support

* RP2040: Bad initialization code was causing IRQs to get disabled before main() was called when using non static allocation
This commit is contained in:
Graham Sanderson 2021-12-21 13:08:41 -06:00 committed by GitHub
parent 4c4089b154
commit debbd254b6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 16 additions and 15 deletions

View File

@ -33,8 +33,7 @@ endif ()
if (NOT FREERTOS_KERNEL_PATH) if (NOT FREERTOS_KERNEL_PATH)
foreach(POSSIBLE_SUFFIX Source FreeRTOS-Kernel FreeRTOS/Source) foreach(POSSIBLE_SUFFIX Source FreeRTOS-Kernel FreeRTOS/Source)
# check if FreeRTOS-Kernel exists under directory that included us # check if FreeRTOS-Kernel exists under directory that included us
set(SEARCH_ROOT ${CMAKE_CURRENT_SOURCE_DIR}}) set(SEARCH_ROOT ${CMAKE_CURRENT_SOURCE_DIR})
set(SEARCH_ROOT ../../../..)
get_filename_component(_POSSIBLE_PATH ${SEARCH_ROOT}/${POSSIBLE_SUFFIX} REALPATH) get_filename_component(_POSSIBLE_PATH ${SEARCH_ROOT}/${POSSIBLE_SUFFIX} REALPATH)
if (EXISTS ${_POSSIBLE_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/CMakeLists.txt) if (EXISTS ${_POSSIBLE_PATH}/${FREERTOS_KERNEL_RP2040_RELATIVE_PATH}/CMakeLists.txt)
get_filename_component(FREERTOS_KERNEL_PATH ${_POSSIBLE_PATH} REALPATH) get_filename_component(FREERTOS_KERNEL_PATH ${_POSSIBLE_PATH} REALPATH)

View File

@ -32,7 +32,10 @@
#ifndef __ASSEMBLER__ #ifndef __ASSEMBLER__
#include "FreeRTOSConfig.h" #include "FreeRTOSConfig.h"
#include "rp2040_config.h" #include "rp2040_config.h"
#ifndef PICO_USE_MALLOC_MUTEX
// malloc needs to be made thread safe
#define PICO_USE_MALLOC_MUTEX 1
#endif /* PICO_USE_MALLOC_MUTEX */
#if ( configSUPPORT_PICO_SYNC_INTEROP == 1 ) #if ( configSUPPORT_PICO_SYNC_INTEROP == 1 )
// increase the amount of time it may reasonably take to wake us up // increase the amount of time it may reasonably take to wake us up
#ifndef PICO_TIME_SLEEP_OVERHEAD_ADJUST_US #ifndef PICO_TIME_SLEEP_OVERHEAD_ADJUST_US

View File

@ -110,8 +110,9 @@ static void prvTaskExitError( void );
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
/* Each task maintains its own interrupt status in the critical nesting /* Each task maintains its own interrupt status in the critical nesting
* variable. */ * variable. This is initialized to 0 to allow vPortEnter/ExitCritical
static UBaseType_t uxCriticalNesting = {0xaaaaaaaa}; * to be called before the scheduler is started */
static UBaseType_t uxCriticalNesting;
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
@ -158,13 +159,9 @@ static UBaseType_t uxCriticalNesting = {0xaaaaaaaa};
/*-----------------------------------------------------------*/ /*-----------------------------------------------------------*/
#if ( LIB_PICO_MULTICORE == 1 )
#define INVALID_LAUNCH_CORE_NUM 0xffu #define INVALID_LAUNCH_CORE_NUM 0xffu
static uint8_t ucLaunchCoreNum = INVALID_LAUNCH_CORE_NUM; static uint8_t ucLaunchCoreNum = INVALID_LAUNCH_CORE_NUM;
#define portIS_FREE_RTOS_CORE() ( ucLaunchCoreNum == get_core_num() ) #define portIS_FREE_RTOS_CORE() ( ucLaunchCoreNum == get_core_num() )
#else
#define portIS_FREE_RTOS_CORE() pdTRUE
#endif /* LIB_PICO_MULTICORE */
/* /*
* See header file for description. * See header file for description.
@ -266,8 +263,8 @@ BaseType_t xPortStartScheduler( void )
/* Initialise the critical nesting count ready for the first task. */ /* Initialise the critical nesting count ready for the first task. */
uxCriticalNesting = 0; uxCriticalNesting = 0;
#if (LIB_PICO_MULTICORE == 1)
ucLaunchCoreNum = get_core_num(); ucLaunchCoreNum = get_core_num();
#if (LIB_PICO_MULTICORE == 1)
#if ( configSUPPORT_PICO_SYNC_INTEROP == 1) #if ( configSUPPORT_PICO_SYNC_INTEROP == 1)
multicore_fifo_clear_irq(); multicore_fifo_clear_irq();
multicore_fifo_drain(); multicore_fifo_drain();
@ -728,7 +725,6 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void )
void vPortLockInternalSpinUnlockWithWait( struct lock_core * pxLock, uint32_t ulSave ) void vPortLockInternalSpinUnlockWithWait( struct lock_core * pxLock, uint32_t ulSave )
{ {
configASSERT( !portCHECK_IF_IN_ISR() ); configASSERT( !portCHECK_IF_IN_ISR() );
// note no need to check LIB_PICO_MULTICORE, as this is always returns true if that is not defined
if( !portIS_FREE_RTOS_CORE() ) if( !portIS_FREE_RTOS_CORE() )
{ {
spin_unlock(pxLock->spin_lock, ulSave ); spin_unlock(pxLock->spin_lock, ulSave );
@ -806,7 +802,6 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void )
} }
else else
{ {
configASSERT( portIS_FREE_RTOS_CORE() );
configASSERT( pxYieldSpinLock == NULL ); configASSERT( pxYieldSpinLock == NULL );
TickType_t uxTicksToWait = prvGetTicksToWaitBefore( uxUntil ); TickType_t uxTicksToWait = prvGetTicksToWaitBefore( uxUntil );
@ -858,6 +853,10 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void )
#if ( configSUPPORT_STATIC_ALLOCATION == 1 ) #if ( configSUPPORT_STATIC_ALLOCATION == 1 )
xEventGroup = xEventGroupCreateStatic(&xStaticEventGroup); xEventGroup = xEventGroupCreateStatic(&xStaticEventGroup);
#else #else
/* Note that it is slightly dubious calling this here before the scheduler is initialized,
* however the only thing it touches is the allocator which then calls vPortEnterCritical
* and vPortExitCritical, and allocating here saves us checking the one time initialized variable in
* some rather critical code paths */
xEventGroup = xEventGroupCreate(); xEventGroup = xEventGroupCreate();
#endif /* configSUPPORT_STATIC_ALLOCATION */ #endif /* configSUPPORT_STATIC_ALLOCATION */
} }