mirror of
https://github.com/FreeRTOS/FreeRTOS-Kernel.git
synced 2025-04-19 21:11:57 -04:00
Fix RP2040 assertion due to yield spin lock info being wrongly shared between multiple cores (#501)
Co-authored-by: graham sanderson <graham.sanderson@raspeberryi.com>
This commit is contained in:
parent
34b8e24d7c
commit
45dd83a8e3
29
portable/ThirdParty/GCC/RP2040/port.c
vendored
29
portable/ThirdParty/GCC/RP2040/port.c
vendored
|
@ -122,8 +122,8 @@ static void prvTaskExitError( void );
|
|||
static EventGroupHandle_t xEventGroup;
|
||||
static EventBits_t uxCrossCoreEventBits;
|
||||
static spin_lock_t * pxCrossCoreSpinLock;
|
||||
static spin_lock_t * pxYieldSpinLock;
|
||||
static uint32_t ulYieldSpinLockSaveValue;
|
||||
static spin_lock_t * pxYieldSpinLock[configNUM_CORES];
|
||||
static uint32_t ulYieldSpinLockSaveValue[configNUM_CORES];
|
||||
#endif /* configSUPPORT_PICO_SYNC_INTEROP */
|
||||
|
||||
/*
|
||||
|
@ -358,7 +358,7 @@ void vPortYield( void )
|
|||
#if ( configSUPPORT_PICO_SYNC_INTEROP == 1 )
|
||||
/* We are not in an ISR, and pxYieldSpinLock is always dealt with and
|
||||
* cleared interrupts are re-enabled, so should be NULL */
|
||||
configASSERT( pxYieldSpinLock == NULL );
|
||||
configASSERT( pxYieldSpinLock[portGET_CORE_ID()] == NULL );
|
||||
#endif /* configSUPPORT_PICO_SYNC_INTEROP */
|
||||
|
||||
/* Set a PendSV to request a context switch. */
|
||||
|
@ -373,11 +373,12 @@ void vPortYield( void )
|
|||
void vPortEnableInterrupts( void )
|
||||
{
|
||||
#if ( configSUPPORT_PICO_SYNC_INTEROP == 1 )
|
||||
if( pxYieldSpinLock )
|
||||
int xCoreID = portGET_CORE_ID();
|
||||
if( pxYieldSpinLock[xCoreID] )
|
||||
{
|
||||
spin_lock_t* const pxTmpLock = pxYieldSpinLock;
|
||||
pxYieldSpinLock = NULL;
|
||||
spin_unlock( pxTmpLock, ulYieldSpinLockSaveValue );
|
||||
spin_lock_t* const pxTmpLock = pxYieldSpinLock[xCoreID];
|
||||
pxYieldSpinLock[xCoreID] = NULL;
|
||||
spin_unlock( pxTmpLock, ulYieldSpinLockSaveValue[xCoreID] );
|
||||
}
|
||||
#endif
|
||||
__asm volatile ( " cpsie i " ::: "memory" );
|
||||
|
@ -773,14 +774,15 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void )
|
|||
}
|
||||
else
|
||||
{
|
||||
configASSERT( pxYieldSpinLock == NULL );
|
||||
configASSERT( pxYieldSpinLock[portGET_CORE_ID()] == NULL );
|
||||
|
||||
// we want to hold the lock until the event bits have been set; since interrupts are currently disabled
|
||||
// by the spinlock, we can defer until portENABLE_INTERRUPTS is called which is always called when
|
||||
// the scheduler is unlocked during this call
|
||||
configASSERT(pxLock->spin_lock);
|
||||
pxYieldSpinLock = pxLock->spin_lock;
|
||||
ulYieldSpinLockSaveValue = ulSave;
|
||||
int xCoreID = portGET_CORE_ID();
|
||||
pxYieldSpinLock[xCoreID] = pxLock->spin_lock;
|
||||
ulYieldSpinLockSaveValue[xCoreID] = ulSave;
|
||||
xEventGroupWaitBits( xEventGroup, prvGetEventGroupBit(pxLock->spin_lock),
|
||||
pdTRUE, pdFALSE, portMAX_DELAY);
|
||||
}
|
||||
|
@ -841,7 +843,7 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void )
|
|||
else
|
||||
{
|
||||
configASSERT( portIS_FREE_RTOS_CORE() );
|
||||
configASSERT( pxYieldSpinLock == NULL );
|
||||
configASSERT( pxYieldSpinLock[portGET_CORE_ID()] == NULL );
|
||||
|
||||
TickType_t uxTicksToWait = prvGetTicksToWaitBefore( uxUntil );
|
||||
if( uxTicksToWait )
|
||||
|
@ -850,8 +852,9 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void )
|
|||
* by the spinlock, we can defer until portENABLE_INTERRUPTS is called which is always called when
|
||||
* the scheduler is unlocked during this call */
|
||||
configASSERT(pxLock->spin_lock);
|
||||
pxYieldSpinLock = pxLock->spin_lock;
|
||||
ulYieldSpinLockSaveValue = ulSave;
|
||||
int xCoreID = portGET_CORE_ID();
|
||||
pxYieldSpinLock[xCoreID] = pxLock->spin_lock;
|
||||
ulYieldSpinLockSaveValue[xCoreID] = ulSave;
|
||||
xEventGroupWaitBits( xEventGroup,
|
||||
prvGetEventGroupBit(pxLock->spin_lock), pdTRUE,
|
||||
pdFALSE, uxTicksToWait );
|
||||
|
|
Loading…
Reference in a new issue