Question 1. I noticed that xEventGroupSync() performs a call to vTaskSuspendAll() prior to entering a block where the events are tested. I want to confirm if this stops the scheduling of the other CPU on the dual core ESP32. I realize that xTaskResumeAll() is called later on.

Question 2. I see that xEventGroupSetBits( xEventGroup, uxBitsToSet ) is called after the scheduler has been suspended. Does this mean that uxBitsToSet remain set in the event group after a timeout occurs?

All official versions of FreeRTOS (those written by us) are single core, so I’m afraid I don’t know the answer to that.

I’m confused by this statement. All API functions have their own entry point, so none are called after the scheduler has been suspended unless the application writer suspends the scheduler then calls the API function (which would be in breach of the API usage rules anyway). Can you link to the code you are referring to in the repo: https://github.com/FreeRTOS/FreeRTOS-Kernel

Looking at the ESP32 code, I see that vTaskSuspendAll() only affects the current core.

Question 2 was still about xEventGroupSync():

EventBits_t xEventGroupSync( EventGroupHandle_t xEventGroup, const EventBits_t uxBitsToSet, const EventBits_t uxBitsToWaitFor, TickType_t xTicksToWait )
EventBits_t uxOriginalBitValue, uxReturn;
EventGroup_t *pxEventBits = ( EventGroup_t * ) xEventGroup;
BaseType_t xAlreadyYielded;
BaseType_t xTimeoutOccurred = pdFALSE;
    configASSERT( ( uxBitsToWaitFor & eventEVENT_BITS_CONTROL_BYTES ) == 0 ); 
    configASSERT( uxBitsToWaitFor != 0 );
    #if ( ( INCLUDE_xTaskGetSchedulerState == 1 ) || ( configUSE_TIMERS == 1 ) )
            configASSERT( !( ( xTaskGetSchedulerState() == taskSCHEDULER_SUSPENDED ) && ( xTicksToWait != 0 ) ) );
            uxOriginalBitValue = pxEventBits->uxEventBits;
            ( void ) xEventGroupSetBits( xEventGroup, uxBitsToSet );
            if( ( ( uxOriginalBitValue | uxBitsToSet ) & uxBitsToWaitFor ) == uxBitsToWaitFor )

In that code I had wondered if the uxBitToSet were undone if the call timed out. I don’t see how that is possible (I assumed that it might have been).

Looking at the code I don’t see anywhere where they are cleared, and thinking about the synchronisation/rendezvous use case I don’t think it would make sense to clear them - so the answer is no, they are not cleared again.