Every priority level in FreeRTOS has its own ready and delayed list.

PRIVILEGED_DATA static List_t pxReadyTasksLists[ configMAX_PRIORITIES ]; /**< Prioritised ready tasks. */
PRIVILEGED_DATA static List_t xDelayedTaskList1;                         /**< Delayed tasks. */
PRIVILEGED_DATA static List_t xDelayedTaskList2;                         /**< Delayed tasks (two lists are used - one for delays that have overflowed the current tick count. */
PRIVILEGED_DATA static List_t * volatile pxDelayedTaskList;              /**< Points to the delayed task list currently being used. */
PRIVILEGED_DATA static List_t * volatile pxOverflowDelayedTaskList;      /**< Points to the delayed task list currently being used to hold tasks that have overflowed the current tick count. */
PRIVILEGED_DATA static List_t xPendingReadyList;                         /**< Tasks that have been readied while the scheduler was suspended.  They will be moved to the ready list when the scheduler is resumed. */
 

The idle task

It is created automatically when the scheduler is started, other configurations like calling the idleHook is done by checking a macro inside the idle task. this function is called every iteration in a while loop.

Binary Semaphores

Binary semaphores are implemented as a queue that has a length of 1 item of size 0 bytes. I don’t know yet but it is allowed in the implementation.

/* Allocate enough space to hold the maximum number of items that
 * can be in the queue at any time.  It is valid for uxItemSize to be
 * zero in the case the queue is used as a semaphore. */
xQueueSizeInBytes = ( size_t ) ( ( size_t ) uxQueueLength * ( size_t ) uxItemSize );
 
/* MISRA Ref 11.5.1 [Malloc memory assignment] */
/* More details at: https://github.com/FreeRTOS/FreeRTOS-Kernel/blob/main/MISRA.md#rule-115 */
/* coverity[misra_c_2012_rule_11_5_violation] */
pxNewQueue = ( Queue_t * ) pvPortMalloc( sizeof( Queue_t ) + xQueueSizeInBytes );

Because we will allocate a queue struct that stores this semaphore information.