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 EventGroupHandle_t xEventGroup;
|
||||||
static EventBits_t uxCrossCoreEventBits;
|
static EventBits_t uxCrossCoreEventBits;
|
||||||
static spin_lock_t * pxCrossCoreSpinLock;
|
static spin_lock_t * pxCrossCoreSpinLock;
|
||||||
static spin_lock_t * pxYieldSpinLock;
|
static spin_lock_t * pxYieldSpinLock[configNUM_CORES];
|
||||||
static uint32_t ulYieldSpinLockSaveValue;
|
static uint32_t ulYieldSpinLockSaveValue[configNUM_CORES];
|
||||||
#endif /* configSUPPORT_PICO_SYNC_INTEROP */
|
#endif /* configSUPPORT_PICO_SYNC_INTEROP */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -358,7 +358,7 @@ void vPortYield( void )
|
||||||
#if ( configSUPPORT_PICO_SYNC_INTEROP == 1 )
|
#if ( configSUPPORT_PICO_SYNC_INTEROP == 1 )
|
||||||
/* We are not in an ISR, and pxYieldSpinLock is always dealt with and
|
/* We are not in an ISR, and pxYieldSpinLock is always dealt with and
|
||||||
* cleared interrupts are re-enabled, so should be NULL */
|
* cleared interrupts are re-enabled, so should be NULL */
|
||||||
configASSERT( pxYieldSpinLock == NULL );
|
configASSERT( pxYieldSpinLock[portGET_CORE_ID()] == NULL );
|
||||||
#endif /* configSUPPORT_PICO_SYNC_INTEROP */
|
#endif /* configSUPPORT_PICO_SYNC_INTEROP */
|
||||||
|
|
||||||
/* Set a PendSV to request a context switch. */
|
/* Set a PendSV to request a context switch. */
|
||||||
|
@ -373,11 +373,12 @@ void vPortYield( void )
|
||||||
void vPortEnableInterrupts( void )
|
void vPortEnableInterrupts( void )
|
||||||
{
|
{
|
||||||
#if ( configSUPPORT_PICO_SYNC_INTEROP == 1 )
|
#if ( configSUPPORT_PICO_SYNC_INTEROP == 1 )
|
||||||
if( pxYieldSpinLock )
|
int xCoreID = portGET_CORE_ID();
|
||||||
|
if( pxYieldSpinLock[xCoreID] )
|
||||||
{
|
{
|
||||||
spin_lock_t* const pxTmpLock = pxYieldSpinLock;
|
spin_lock_t* const pxTmpLock = pxYieldSpinLock[xCoreID];
|
||||||
pxYieldSpinLock = NULL;
|
pxYieldSpinLock[xCoreID] = NULL;
|
||||||
spin_unlock( pxTmpLock, ulYieldSpinLockSaveValue );
|
spin_unlock( pxTmpLock, ulYieldSpinLockSaveValue[xCoreID] );
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
__asm volatile ( " cpsie i " ::: "memory" );
|
__asm volatile ( " cpsie i " ::: "memory" );
|
||||||
|
@ -773,14 +774,15 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void )
|
||||||
}
|
}
|
||||||
else
|
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
|
// 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
|
// by the spinlock, we can defer until portENABLE_INTERRUPTS is called which is always called when
|
||||||
// the scheduler is unlocked during this call
|
// the scheduler is unlocked during this call
|
||||||
configASSERT(pxLock->spin_lock);
|
configASSERT(pxLock->spin_lock);
|
||||||
pxYieldSpinLock = pxLock->spin_lock;
|
int xCoreID = portGET_CORE_ID();
|
||||||
ulYieldSpinLockSaveValue = ulSave;
|
pxYieldSpinLock[xCoreID] = pxLock->spin_lock;
|
||||||
|
ulYieldSpinLockSaveValue[xCoreID] = ulSave;
|
||||||
xEventGroupWaitBits( xEventGroup, prvGetEventGroupBit(pxLock->spin_lock),
|
xEventGroupWaitBits( xEventGroup, prvGetEventGroupBit(pxLock->spin_lock),
|
||||||
pdTRUE, pdFALSE, portMAX_DELAY);
|
pdTRUE, pdFALSE, portMAX_DELAY);
|
||||||
}
|
}
|
||||||
|
@ -841,7 +843,7 @@ __attribute__( ( weak ) ) void vPortSetupTimerInterrupt( void )
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
configASSERT( portIS_FREE_RTOS_CORE() );
|
configASSERT( portIS_FREE_RTOS_CORE() );
|
||||||
configASSERT( pxYieldSpinLock == NULL );
|
configASSERT( pxYieldSpinLock[portGET_CORE_ID()] == NULL );
|
||||||
|
|
||||||
TickType_t uxTicksToWait = prvGetTicksToWaitBefore( uxUntil );
|
TickType_t uxTicksToWait = prvGetTicksToWaitBefore( uxUntil );
|
||||||
if( uxTicksToWait )
|
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
|
* by the spinlock, we can defer until portENABLE_INTERRUPTS is called which is always called when
|
||||||
* the scheduler is unlocked during this call */
|
* the scheduler is unlocked during this call */
|
||||||
configASSERT(pxLock->spin_lock);
|
configASSERT(pxLock->spin_lock);
|
||||||
pxYieldSpinLock = pxLock->spin_lock;
|
int xCoreID = portGET_CORE_ID();
|
||||||
ulYieldSpinLockSaveValue = ulSave;
|
pxYieldSpinLock[xCoreID] = pxLock->spin_lock;
|
||||||
|
ulYieldSpinLockSaveValue[xCoreID] = ulSave;
|
||||||
xEventGroupWaitBits( xEventGroup,
|
xEventGroupWaitBits( xEventGroup,
|
||||||
prvGetEventGroupBit(pxLock->spin_lock), pdTRUE,
|
prvGetEventGroupBit(pxLock->spin_lock), pdTRUE,
|
||||||
pdFALSE, uxTicksToWait );
|
pdFALSE, uxTicksToWait );
|
||||||
|
|
Loading…
Reference in a new issue