Эх сурвалжийг харах

freertos: FreeRTOS SMP RISC-V port cleanup and enable esp32c3 in KConfig

This commit does general cleanup of the risc-v port files and restricts
FreeRTOS SMP config option to only esp32 and esp32c3.
Sudeep Mohanty 3 жил өмнө
parent
commit
12e2312aaa

+ 3 - 41
components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/include/freertos/FreeRTOSConfig_smp.h

@@ -17,54 +17,14 @@ This file get's pulled into assembly sources. Therefore, some includes need to b
 #include <assert.h>         //For configASSERT()
 #endif /* def __ASSEMBLER__ */
 
-#if __XTENSA__
-/* Required for configuration-dependent settings. */
-#include "xtensa_config.h"
-
-/* -------------------------------------------- Xtensa Additional Config  ----------------------------------------------
- * - Provide Xtensa definitions usually given by -D option when building with xt-make (see readme_xtensa.txt)
- * - xtensa_rtos.h and xtensa_timer.h will default some of these values
- *      - XT_SIMULATOR         configXT_SIMULATOR
- *      - XT_BOARD             configXT_BOARD
- *      - XT_CLOCK_FREQ        Should not be defined as we are using XT_BOARD mode
- *      - XT_TICK_PER_SEC      Defaults to configTICK_RATE_HZ
- *      - XT_TIMER_INDEX       Defaults to configXT_TIMER_INDEX
- *      - XT_INTEXC_HOOKS      Defaults to configXT_INTEXC_HOOKS
- *      - XT_USE_OVLY          We don't define this (unused)
- *      - XT_USE_SWPRI         We don't define this (unused)
- * ------------------------------------------------------------------------------------------------------------------ */
-
-#define configXT_SIMULATOR                                  0
-#define configXT_BOARD                                      1   /* Board mode */
-#if CONFIG_FREERTOS_CORETIMER_0
-#define configXT_TIMER_INDEX                                0
-#elif CONFIG_FREERTOS_CORETIMER_1
-#define configXT_TIMER_INDEX                                1
-#endif
-#define configXT_INTEXC_HOOKS                               0
-
-#define configBENCHMARK                                     0
-#endif // __XTENSA__
-
 /* ------------------------------------------------ ESP-IDF Additions --------------------------------------------------
  *
  * ------------------------------------------------------------------------------------------------------------------ */
 
-#if __XTENSA__
-/* The Xtensa port uses a separate interrupt stack. Adjust the stack size
- * to suit the needs of your specific application.
- * Size needs to be aligned to the stack increment, since the location of
- * the stack for the 2nd CPU will be calculated using configISR_STACK_SIZE.
- */
-#define configSTACK_ALIGNMENT                               16
-#ifndef configISR_STACK_SIZE
-#define configISR_STACK_SIZE                                ((CONFIG_FREERTOS_ISR_STACKSIZE + configSTACK_ALIGNMENT - 1) & (~(configSTACK_ALIGNMENT - 1)))
-#endif
-#else // RISC-V
 #ifndef configISR_STACK_SIZE
 #define configISR_STACK_SIZE                                (CONFIG_FREERTOS_ISR_STACKSIZE)
 #endif
-#endif // __XTENSA__
+
 /* ----------------------------------------------------- Helpers -------------------------------------------------------
  * - Macros that the FreeRTOS configuration macros depend on
  * ------------------------------------------------------------------------------------------------------------------ */
@@ -188,6 +148,8 @@ This file get's pulled into assembly sources. Therefore, some includes need to b
 #endif // CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS
 #define configSTACK_DEPTH_TYPE                          uint32_t
 #define configUSE_NEWLIB_REENTRANT                      1
+#define configNEWLIB_REENTRANT_IS_DYNAMIC               1   // IDF Newlib supports dynamic reentrancy.
+                                                            // We provide our own __getreent() function
 #define configENABLE_BACKWARD_COMPATIBILITY             0
 #define configASSERT(a)                                 assert(a)
 #define configINCLUDE_FREERTOS_TASK_C_ADDITIONS_H       1

+ 29 - 297
components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/include/freertos/portmacro.h

@@ -49,11 +49,8 @@ typedef uint32_t TickType_t;
 #define portTASK_FUNCTION_PROTO( vFunction, pvParameters )  void vFunction( void *pvParameters )
 #define portTASK_FUNCTION( vFunction, pvParameters )          void vFunction( void *pvParameters )
 
-//TODO: Check this
 // interrupt module will mask interrupt with priority less than threshold
 #define RVHAL_EXCM_LEVEL            4
-// TODO: Check this end
-
 
 /* ----------------------------------------------- Port Configurations -------------------------------------------------
  * - Configurations values supplied by each port
@@ -67,127 +64,28 @@ typedef uint32_t TickType_t;
 #define portNOP() __asm volatile        (" nop ")
 
 /* ---------------------------------------------- Forward Declarations -------------------------------------------------
- * - Forward declarations of all the port functions and macros need to implement the FreeRTOS porting interface
+ * - Forward declarations of all the port functions and macros needed to implement the FreeRTOS porting interface
  * - These must come before definition/declaration of the FreeRTOS porting interface
  * ------------------------------------------------------------------------------------------------------------------ */
 
 /* ---------------------- Spinlocks ------------------------
  - Spinlocks added to match API with SMP FreeRTOS. Single core RISC-V does not need spin locks
- - Because single core does not have a primitive spinlock data type, we have to implement one here
- * @note [refactor-todo] Refactor critical section API so that this is no longer required
  * ------------------------------------------------------ */
 
-/**
- * @brief Spinlock object
- * Owner:
- *  - Set to 0 if uninitialized
- *  - Set to portMUX_FREE_VAL when free
- *  - Set to CORE_ID_REGVAL_PRO or CORE_ID_REGVAL_AP when locked
- *  - Any other value indicates corruption
- * Count:
- *  - 0 if unlocked
- *  - Recursive count if locked
- *
- * @note Not a true spinlock as single core RISC-V does not have atomic compare and set instruction
- * @note Keep portMUX_INITIALIZER_UNLOCKED in sync with this struct
- */
-//typedef struct {
-//    uint32_t owner;
-//    uint32_t count;
-//} portMUX_TYPE;
 typedef spinlock_t                          portMUX_TYPE;               /**< Spinlock type used by FreeRTOS critical sections */
-#if 0
-#define portMUX_INITIALIZER_UNLOCKED {                      \
-            .owner = portMUX_FREE_VAL,                      \
-            .count = 0,                                     \
-        }
-#define portMUX_FREE_VAL                    SPINLOCK_FREE           /**< Spinlock is free. [refactor-todo] check if this is still required */
-#define portMUX_NO_TIMEOUT                  SPINLOCK_WAIT_FOREVER   /**< When passed for 'timeout_cycles', spin forever if necessary. [refactor-todo] check if this is still required */
-#define portMUX_TRY_LOCK                    SPINLOCK_NO_WAIT        /**< Try to acquire the spinlock a single time only. [refactor-todo] check if this is still required */
-#define portMUX_INITIALIZE(mux)    ({ \
-    (mux)->owner = portMUX_FREE_VAL; \
-    (mux)->count = 0; \
-})
-#endif
+
 #define portMUX_INITIALIZER_UNLOCKED        SPINLOCK_INITIALIZER        /**< Spinlock initializer */
 #define portMUX_FREE_VAL                    SPINLOCK_FREE               /**< Spinlock is free. [refactor-todo] check if this is still required */
 #define portMUX_NO_TIMEOUT                  SPINLOCK_WAIT_FOREVER       /**< When passed for 'timeout_cycles', spin forever if necessary. [refactor-todo] check if this is still required */
 #define portMUX_TRY_LOCK                    SPINLOCK_NO_WAIT            /**< Try to acquire the spinlock a single time only. [refactor-todo] check if this is still required */
 #define portMUX_INITIALIZE(mux)             spinlock_initialize(mux)    /*< Initialize a spinlock to its unlocked state */
 
-
-// ----------------------- Memory --------------------------
-
 // --------------------- Interrupts ------------------------
 
 BaseType_t xPortCheckIfInISR(void);
 
-// TODO: Check this
-#if 0
-/**
- * @brief Checks if the current core is in an ISR context
- *
- * - ISR context consist of Low/Mid priority ISR, or time tick ISR
- * - High priority ISRs aren't detected here, but they normally cannot call C code, so that should not be an issue anyway.
- *
- * @note [refactor-todo] Check if this should be inlined
- * @return
- *  - pdTRUE if in ISR
- *  - pdFALSE otherwise
- */
-BaseType_t xPortInIsrContext(void);
-#endif
-// TODO: Check this end
-
-// TODO: Check this
-/**
- * @brief Check if in ISR context from High priority ISRs
- *
- * - Called from High priority ISR
- * - Checks if the previous context (before high priority interrupt) was in ISR context (meaning low/med priority)
- *
- * @note [refactor-todo] Check if this should be inlined
- * @return
- *  - pdTRUE if in previous in ISR context
- *  - pdFALSE otherwise
- */
-BaseType_t xPortInterruptedFromISRContext(void);
-// TODO: Check this end
-
-// TODO: Check this
-/* ---------------------- Spinlocks ------------------------*/
-/**
- * @brief Wrapper for atomic compare-and-set instruction
- *
- * @note Isn't a real atomic CAS.
- * @note [refactor-todo] check if we still need this
- * @note [refactor-todo] Check if this function should be renamed (due to void return type)
- *
- * @param[inout] addr Pointer to target address
- * @param[in] compare Compare value
- * @param[inout] set Pointer to set value
- */
-static inline void __attribute__((always_inline)) uxPortCompareSet(volatile uint32_t *addr, uint32_t compare, uint32_t *set);
-
-/**
- * @brief Wrapper for atomic compare-and-set instruction in external RAM
- *
- * @note Isn't a real atomic CAS.
- * @note [refactor-todo] check if we still need this
- * @note [refactor-todo] Check if this function should be renamed (due to void return type)
- *
- * @param[inout] addr Pointer to target address
- * @param[in] compare Compare value
- * @param[inout] set Pointer to set value
- */
-static inline void uxPortCompareSetExtram(volatile uint32_t *addr, uint32_t compare, uint32_t *set);
-// TODO: Check this end
-
 // ------------------ Critical Sections --------------------
 
-UBaseType_t uxPortEnterCriticalFromISR( void );
-void vPortExitCriticalFromISR( UBaseType_t level );
-
 /*
 These are always called with interrupts already disabled. We simply need to get/release the spinlocks
 */
@@ -198,55 +96,24 @@ extern portMUX_TYPE port_xISRLock;
 void vPortTakeLock( portMUX_TYPE *lock );
 void vPortReleaseLock( portMUX_TYPE *lock );
 
-/**
- * @brief Enter a critical section
- *
- * - Simply disable interrupts
- * - Can be nested
- */
-void vPortEnterCritical(void);
-
-/**
- * @brief Exit a critical section
- *
- * - Reenables interrupts
- * - Can be nested
- */
-void vPortExitCritical(void);
-
 // ---------------------- Yielding -------------------------
 
 void vPortYield( void );
 static inline void __attribute__((always_inline)) vPortYieldCore( BaseType_t xCoreID );
-// TODO: Check this
-//static inline void __attribute__((always_inline)) vPortYieldFromISR( void );
-// TODO: Check this end
 
 /**
  * @brief Set interrupt mask and return current interrupt enable register
  *
- * @note [refactor-todo] Check if this function should be renamed (due to int return type)
- * @return int Current interrupt enable register before set
+ * @return UBaseType_t Current interrupt enable register before set
  */
-int vPortSetInterruptMask(void);
+UBaseType_t ulPortSetInterruptMask(void);
 
 /**
  * @brief Clear current interrupt mask and set given mask
  *
  * @param mask Interrupt mask
  */
-void vPortClearInterruptMask(int mask);
-
-// TODO: Check this
-#if 0
-/**
- * @brief Perform a context switch from a task
- *
- * @note [refactor-todo] The rest of ESP-IDF should call taskYield() instead
- */
-void vPortYield(void);
-#endif
-// TODO: Check this end
+void vPortClearInterruptMask(UBaseType_t mask);
 
 /**
  * @brief Perform a context switch from an ISR
@@ -260,31 +127,6 @@ void vPortYieldFromISR(void);
 })
 #define portYIELD_FROM_ISR_NO_CHECK()               vPortYieldFromISR()
 
-// TODO: Check this
-#if 0
-/**
- * @brief Yields the other core
- *
- * @note Added to be compatible with SMP API
- * @note [refactor-todo] Put this into private macros as its only called from task.c and is not public API
- * @param coreid ID of core to yield
- */
-void vPortYieldOtherCore(BaseType_t coreid);
-
-/**
- * @brief Checks if the current core can yield
- *
- * - A core cannot yield if its in an ISR or in a critical section
- *
- * @note [refactor-todo] See if this can be separated from port macro
- * @note [refactor-todo] Check if this function should be renamed (due to bool return type)
- * @return true Core can yield
- * @return false Core cannot yield
- */
-static inline bool xPortCanYield(void);
-#endif
-// TODO: Check this end
-
 // ----------------------- System --------------------------
 
 static inline BaseType_t __attribute__((always_inline)) xPortGetCoreID( void );
@@ -293,87 +135,15 @@ static inline BaseType_t __attribute__((always_inline)) xPortGetCoreID( void );
 
 void vPortCleanUpTCB ( void *pxTCB );
 
-// TODO: Check this
-#if 0
-// ------------------- Hook Functions ----------------------
-
-/**
- * @brief Hook function called on entry to tickless idle
- *
- * - Implemented in pm_impl.c
- *
- * @param xExpectedIdleTime Expected idle time
- */
-void vApplicationSleep(TickType_t xExpectedIdleTime);
-#endif
-// TODO: Check this end
-
-// TODO: Check this
-#if 0
-// ----------------------- System --------------------------
-
-/**
- * @brief Get the tick rate per second
- *
- * @note [refactor-todo] make this inline
- * @note [refactor-todo] Check if this function should be renamed (due to uint return type)
- * @return uint32_t Tick rate in Hz
- */
-uint32_t xPortGetTickRateHz(void);
-
-/**
- * @brief Set a watchpoint to watch the last 32 bytes of the stack
- *
- * Callback to set a watchpoint on the end of the stack. Called every context switch to change the stack watchpoint
- * around.
- *
- * @param pxStackStart Pointer to the start of the stack
- */
-void vPortSetStackWatchpoint(void *pxStackStart);
-
-/**
- * @brief Get the current core's ID
- *
- * @note Added to be compatible with SMP API
- * @note [refactor-todo] IDF should call a FreeRTOS like macro instead of port function directly
- * @return BaseType_t Core ID
- */
-static inline BaseType_t IRAM_ATTR xPortGetCoreID(void)
-{
-    return (BaseType_t) cpu_hal_get_core_id();
-}
-#endif
-// TODO: Check this end
-
-
-
 /* ------------------------------------------- FreeRTOS Porting Interface ----------------------------------------------
  * - Contains all the mappings of the macros required by FreeRTOS
  * - Most come after forward declare as porting macros map to declared functions
  * - Maps to forward declared functions
  * ------------------------------------------------------------------------------------------------------------------ */
 
-// ----------------------- Memory --------------------------
-
-// TODO: Check this
-#if 0
-/**
- * @brief Task memory allocation macros
- *
- * @note Because the ROM routines don't necessarily handle a stack in external RAM correctly, we force the stack
- * memory to always be internal.
- * @note [refactor-todo] Update portable.h to match v10.4.3 to use new malloc prototypes
- */
-#define portTcbMemoryCaps               (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)
-#define portStackMemoryCaps             (MALLOC_CAP_INTERNAL|MALLOC_CAP_8BIT)
-#define pvPortMallocTcbMem(size)        pvPortMalloc(size)
-#define pvPortMallocStackMem(size)      pvPortMalloc(size)
-#endif
-// TODO: Check this end
-
 // --------------------- Interrupts ------------------------
 
-#define portDISABLE_INTERRUPTS()                    vPortSetInterruptMask()
+#define portDISABLE_INTERRUPTS()                    ulPortSetInterruptMask()
 #define portENABLE_INTERRUPTS()                     vPortClearInterruptMask(1)
 #define portRESTORE_INTERRUPTS(x)                   vPortClearInterruptMask(x)
 
@@ -420,51 +190,11 @@ extern void vTaskExitCritical( void );
 #endif
 #define portYIELD_CORE(x)                           vPortYieldCore(x)
 
-// TODO: Check this
-#if 0
-#define portYIELD_FROM_ISR_NO_ARG() vPortYieldFromISR()
-#define portYIELD_FROM_ISR_ARG(xHigherPriorityTaskWoken) ({ \
-    if (xHigherPriorityTaskWoken == pdTRUE) { \
-        vPortYieldFromISR(); \
-    } \
-})
-/**
- * @note    The macro below could be used when passing a single argument, or without any argument,
- *          it was developed to support both usages of portYIELD inside of an ISR. Any other usage form
- *          might result in undesired behavior
- */
-#if defined(__cplusplus) && (__cplusplus >  201703L)
-#define portYIELD_FROM_ISR(...) CHOOSE_MACRO_VA_ARG(portYIELD_FROM_ISR_ARG, portYIELD_FROM_ISR_NO_ARG __VA_OPT__(,) __VA_ARGS__)(__VA_ARGS__)
-#else
-#define portYIELD_FROM_ISR(...) CHOOSE_MACRO_VA_ARG(portYIELD_FROM_ISR_ARG, portYIELD_FROM_ISR_NO_ARG, ##__VA_ARGS__)(__VA_ARGS__)
-#endif
-
-
-#define portEND_SWITCHING_ISR(xSwitchRequired) if(xSwitchRequired) vPortYield()
-/* Yielding within an API call (when interrupts are off), means the yield should be delayed
-   until interrupts are re-enabled.
-   To do this, we use the "cross-core" interrupt as a trigger to yield on this core when interrupts are re-enabled.This
-   is the same interrupt & code path which is used to trigger a yield between CPUs, although in this case the yield is
-   happening on the same CPU.
-*/
-#define portYIELD_WITHIN_API() portYIELD()
-#endif
-// TODO: Check this end
-
-//
 // ----------------------- System --------------------------
 
 #define portGET_CORE_ID()                           xPortGetCoreID()
 #define portCHECK_IF_IN_ISR()                       xPortCheckIfInISR()
 
-// TODO: Check this
-#if 0
-// ------------------- Hook Functions ----------------------
-
-#define portSUPPRESS_TICKS_AND_SLEEP(idleTime) vApplicationSleep(idleTime)
-#endif
-// TODO: Check this end
-
 // ------------------- Run Time Stats ----------------------
 
 #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS()
@@ -484,10 +214,6 @@ extern void vTaskExitCritical( void );
  * - For implementation of non-inlined functions, see port.c, port_common.c, or other assembly files
  * ------------------------------------------------------------------------------------------------------------------ */
 
-// --------------------- Interrupts ------------------------
-
-// ------------------ Critical Sections --------------------
-
 // ---------------------- Yielding -------------------------
 
 static inline void __attribute__((always_inline)) vPortYieldCore( BaseType_t xCoreID )
@@ -495,20 +221,6 @@ static inline void __attribute__((always_inline)) vPortYieldCore( BaseType_t xCo
     esp_crosscore_int_send_yield( xCoreID );
 }
 
-// TODO: Check this
-#if 0
-static inline bool IRAM_ATTR xPortCanYield(void)
-{
-    uint32_t threshold = REG_READ(INTERRUPT_CORE0_CPU_INT_THRESH_REG);
-    /* when enter critical code, FreeRTOS will mask threshold to RVHAL_EXCM_LEVEL
-     * and exit critical code, will recover threshold value (1). so threshold <= 1
-     * means not in critical code
-     */
-    return (threshold <= 1);
-}
-#endif
-// TODO: Check this end
-
 // ----------------------- System --------------------------
 
 static inline BaseType_t __attribute__((always_inline)) xPortGetCoreID( void )
@@ -520,8 +232,6 @@ static inline BaseType_t __attribute__((always_inline)) xPortGetCoreID( void )
  * - These macros and functions need to be defined for IDF to compile
  * ------------------------------------------------------------------------------------------------------------------ */
 
-// --------------------- Interrupts ------------------------
-
 static inline BaseType_t xPortInIsrContext(void)
 {
     //Just call the FreeRTOS port interface version
@@ -530,11 +240,33 @@ static inline BaseType_t xPortInIsrContext(void)
 
 // ---------------------- Spinlocks ------------------------
 
+/**
+ * @brief Wrapper for atomic compare-and-set instruction
+ *
+ * @note Isn't a real atomic CAS.
+ * @note [refactor-todo] check if we still need this
+ * @note [refactor-todo] Check if this function should be renamed (due to void return type)
+ *
+ * @param[inout] addr Pointer to target address
+ * @param[in] compare Compare value
+ * @param[inout] set Pointer to set value
+ */
 static inline void __attribute__((always_inline)) uxPortCompareSet(volatile uint32_t *addr, uint32_t compare, uint32_t *set)
 {
     compare_and_set_native(addr, compare, set);
 }
 
+/**
+ * @brief Wrapper for atomic compare-and-set instruction in external RAM
+ *
+ * @note Isn't a real atomic CAS.
+ * @note [refactor-todo] check if we still need this
+ * @note [refactor-todo] Check if this function should be renamed (due to void return type)
+ *
+ * @param[inout] addr Pointer to target address
+ * @param[in] compare Compare value
+ * @param[inout] set Pointer to set value
+ */
 static inline void uxPortCompareSetExtram(volatile uint32_t *addr, uint32_t compare, uint32_t *set)
 {
 #if defined(CONFIG_SPIRAM)
@@ -606,7 +338,7 @@ extern int xPortSwitchFlag;
 // --------------------- Debugging -------------------------
 
 #if CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION
-#define UNTESTED_FUNCTION() { esp_rom_printf("Untested FreeRTOS function %s\r\n", __FUNCTION__); configASSERT(false); } while(0)
+#define UNTESTED_FUNCTION() do{ esp_rom_printf("Untested FreeRTOS function %s\r\n", __FUNCTION__); configASSERT(false); } while(0)
 #else
 #define UNTESTED_FUNCTION()
 #endif

+ 95 - 129
components/freertos/FreeRTOS-Kernel-SMP/portable/riscv/port.c

@@ -46,10 +46,10 @@
 static const char *TAG = "cpu_start"; // [refactor-todo]: might be appropriate to change in the future, but
 
 BaseType_t uxSchedulerRunning = 0;
-UBaseType_t uxInterruptNesting = 0;
+volatile UBaseType_t uxInterruptNesting = 0;
 portMUX_TYPE port_xTaskLock = portMUX_INITIALIZER_UNLOCKED;
 portMUX_TYPE port_xISRLock = portMUX_INITIALIZER_UNLOCKED;
-BaseType_t xPortSwitchFlag = 0;
+volatile BaseType_t xPortSwitchFlag = 0;
 __attribute__((aligned(16))) static StackType_t xIsrStack[configISR_STACK_SIZE];
 StackType_t *xIsrStackTop = &xIsrStack[0] + (configISR_STACK_SIZE & (~((portPOINTER_SIZE_TYPE)portBYTE_ALIGNMENT_MASK)));
 
@@ -61,26 +61,32 @@ static UBaseType_t port_uxCriticalOldInterruptStateIDF = 0;
  * - These need to be defined for IDF to compile
  * ------------------------------------------------------------------------------------------------------------------ */
 
-// --------------------- Interrupts ------------------------
+// ------------------ Critical Sections --------------------
 
-BaseType_t IRAM_ATTR xPortInterruptedFromISRContext(void)
+void vPortEnterCriticalIDF(void)
 {
-    /* For single core, this can be the same as xPortCheckIfInISR() because reading it is atomic */
-    return uxInterruptNesting;
+    // Save current interrupt threshold and disable interrupts
+    UBaseType_t old_thresh = ulPortSetInterruptMask();
+    // Update the IDF critical nesting count
+    port_uxCriticalNestingIDF++;
+    if (port_uxCriticalNestingIDF == 1) {
+        // Save a copy of the old interrupt threshold
+        port_uxCriticalOldInterruptStateIDF = (UBaseType_t) old_thresh;
+    }
 }
 
-// ------------------ Critical Sections --------------------
-
-// ----------------------- System --------------------------
-
-// TODO: Check this
-#if 0
-uint32_t xPortGetTickRateHz(void)
+void vPortExitCriticalIDF(void)
 {
-    return (uint32_t)configTICK_RATE_HZ;
+    if (port_uxCriticalNestingIDF > 0) {
+        port_uxCriticalNestingIDF--;
+        if (port_uxCriticalNestingIDF == 0) {
+            // Restore the saved interrupt threshold
+            vPortClearInterruptMask((int)port_uxCriticalOldInterruptStateIDF);
+        }
+    }
 }
-#endif
-// TODO: Check this end
+
+// ----------------------- System --------------------------
 
 #define STACK_WATCH_AREA_SIZE 32
 #define STACK_WATCH_POINT_NUMBER (SOC_CPU_WATCHPOINTS_NUM - 1)
@@ -282,6 +288,50 @@ void esp_startup_start_app(void)
 
 // --------------------- Interrupts ------------------------
 
+UBaseType_t ulPortSetInterruptMask(void)
+{
+    int ret;
+    unsigned old_mstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
+    ret = REG_READ(INTERRUPT_CORE0_CPU_INT_THRESH_REG);
+    REG_WRITE(INTERRUPT_CORE0_CPU_INT_THRESH_REG, RVHAL_EXCM_LEVEL);
+    RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE);
+    /**
+     * In theory, this function should not return immediately as there is a
+     * delay between the moment we mask the interrupt threshold register and
+     * the moment a potential lower-priority interrupt is triggered (as said
+     * above), it should have a delay of 2 machine cycles/instructions.
+     *
+     * However, in practice, this function has an epilogue of one instruction,
+     * thus the instruction masking the interrupt threshold register is
+     * followed by two instructions: `ret` and `csrrs` (RV_SET_CSR).
+     * That's why we don't need any additional nop instructions here.
+     */
+    return ret;
+}
+
+void vPortClearInterruptMask(UBaseType_t mask)
+{
+    REG_WRITE(INTERRUPT_CORE0_CPU_INT_THRESH_REG, mask);
+    /**
+     * The delay between the moment we unmask the interrupt threshold register
+     * and the moment the potential requested interrupt is triggered is not
+     * null: up to three machine cycles/instructions can be executed.
+     *
+     * When compilation size optimization is enabled, this function and its
+     * callers returning void will have NO epilogue, thus the instruction
+     * following these calls will be executed.
+     *
+     * If the requested interrupt is a context switch to a higher priority
+     * task then the one currently running, we MUST NOT execute any instruction
+     * before the interrupt effectively happens.
+     * In order to prevent this, force this routine to have a 3-instruction
+     * delay before exiting.
+     */
+    asm volatile ( "nop" );
+    asm volatile ( "nop" );
+    asm volatile ( "nop" );
+}
+
 BaseType_t xPortCheckIfInISR(void)
 {
     return uxInterruptNesting;
@@ -289,19 +339,45 @@ BaseType_t xPortCheckIfInISR(void)
 
 // ------------------ Critical Sections --------------------
 
-void vPortTakeLock( portMUX_TYPE *lock )
+void IRAM_ATTR vPortTakeLock( portMUX_TYPE *lock )
 {
     spinlock_acquire( lock, portMUX_NO_TIMEOUT);
 }
 
-void vPortReleaseLock( portMUX_TYPE *lock )
+void IRAM_ATTR vPortReleaseLock( portMUX_TYPE *lock )
 {
     spinlock_release( lock );
 }
 
 // ---------------------- Yielding -------------------------
 
-// ----------------------- System --------------------------
+void vPortYield(void)
+{
+    if (uxInterruptNesting) {
+        vPortYieldFromISR();
+    } else {
+
+        esp_crosscore_int_send_yield(0);
+        /* There are 3-4 instructions of latency between triggering the software
+           interrupt and the CPU interrupt happening. Make sure it happened before
+           we return, otherwise vTaskDelay() may return and execute 1-2
+           instructions before the delay actually happens.
+
+           (We could use the WFI instruction here, but there is a chance that
+           the interrupt will happen while evaluating the other two conditions
+           for an instant yield, and if that happens then the WFI would be
+           waiting for the next interrupt to occur...)
+        */
+        while (uxSchedulerRunning && REG_READ(SYSTEM_CPU_INTR_FROM_CPU_0_REG) != 0) {}
+    }
+}
+
+void vPortYieldFromISR( void )
+{
+    //traceISR_EXIT_TO_SCHEDULER();
+    uxSchedulerRunning = 1;
+    xPortSwitchFlag = 1;
+}
 
 /* ------------------------------------------------ FreeRTOS Portable --------------------------------------------------
  * - Provides implementation for functions required by FreeRTOS
@@ -507,8 +583,6 @@ StackType_t *pxPortInitialiseStack(StackType_t *pxTopOfStack, TaskFunction_t pxC
     return (StackType_t *)frame;
 }
 
-// -------------------- Co-Processor -----------------------
-
 // ------- Thread Local Storage Pointers Deletion Callbacks -------
 
 #if ( CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS )
@@ -617,111 +691,3 @@ void vPortCleanUpTCB ( void *pxTCB )
     vPortTLSPointersDelCb( pxTCB );
 #endif /* CONFIG_FREERTOS_TLSP_DELETION_CALLBACKS */
 }
-
-/* ---------------------------------------------- Port Implementations -------------------------------------------------
- *
- * ------------------------------------------------------------------------------------------------------------------ */
-
-// ------------------ Critical Sections --------------------
-
-void vPortEnterCriticalIDF(void)
-{
-    // Save current interrupt threshold and disable interrupts
-    int old_thresh = vPortSetInterruptMask();
-    // Update the IDF critical nesting count
-    port_uxCriticalNestingIDF++;
-    if (port_uxCriticalNestingIDF == 1) {
-        // Save a copy of the old interrupt threshold
-        port_uxCriticalOldInterruptStateIDF = (UBaseType_t) old_thresh;
-    }
-}
-
-void vPortExitCriticalIDF(void)
-{
-    if (port_uxCriticalNestingIDF > 0) {
-        port_uxCriticalNestingIDF--;
-        if (port_uxCriticalNestingIDF == 0) {
-            // Restore the saved interrupt threshold
-            vPortClearInterruptMask((int)port_uxCriticalOldInterruptStateIDF);
-        }
-    }
-}
-
-// ---------------------- Yielding -------------------------
-
-int vPortSetInterruptMask(void)
-{
-    int ret;
-    unsigned old_mstatus = RV_CLEAR_CSR(mstatus, MSTATUS_MIE);
-    ret = REG_READ(INTERRUPT_CORE0_CPU_INT_THRESH_REG);
-    REG_WRITE(INTERRUPT_CORE0_CPU_INT_THRESH_REG, RVHAL_EXCM_LEVEL);
-    RV_SET_CSR(mstatus, old_mstatus & MSTATUS_MIE);
-    /**
-     * In theory, this function should not return immediately as there is a
-     * delay between the moment we mask the interrupt threshold register and
-     * the moment a potential lower-priority interrupt is triggered (as said
-     * above), it should have a delay of 2 machine cycles/instructions.
-     *
-     * However, in practice, this function has an epilogue of one instruction,
-     * thus the instruction masking the interrupt threshold register is
-     * followed by two instructions: `ret` and `csrrs` (RV_SET_CSR).
-     * That's why we don't need any additional nop instructions here.
-     */
-    return ret;
-}
-
-void vPortClearInterruptMask(int mask)
-{
-    REG_WRITE(INTERRUPT_CORE0_CPU_INT_THRESH_REG, mask);
-    /**
-     * The delay between the moment we unmask the interrupt threshold register
-     * and the moment the potential requested interrupt is triggered is not
-     * null: up to three machine cycles/instructions can be executed.
-     *
-     * When compilation size optimization is enabled, this function and its
-     * callers returning void will have NO epilogue, thus the instruction
-     * following these calls will be executed.
-     *
-     * If the requested interrupt is a context switch to a higher priority
-     * task then the one currently running, we MUST NOT execute any instruction
-     * before the interrupt effectively happens.
-     * In order to prevent this, force this routine to have a 3-instruction
-     * delay before exiting.
-     */
-    asm volatile ( "nop" );
-    asm volatile ( "nop" );
-    asm volatile ( "nop" );
-}
-
-void vPortYield(void)
-{
-    if (uxInterruptNesting) {
-        vPortYieldFromISR();
-    } else {
-
-        esp_crosscore_int_send_yield(0);
-        /* There are 3-4 instructions of latency between triggering the software
-           interrupt and the CPU interrupt happening. Make sure it happened before
-           we return, otherwise vTaskDelay() may return and execute 1-2
-           instructions before the delay actually happens.
-
-           (We could use the WFI instruction here, but there is a chance that
-           the interrupt will happen while evaluating the other two conditions
-           for an instant yield, and if that happens then the WFI would be
-           waiting for the next interrupt to occur...)
-        */
-        while (uxSchedulerRunning && REG_READ(SYSTEM_CPU_INTR_FROM_CPU_0_REG) != 0) {}
-    }
-}
-
-void vPortYieldFromISR( void )
-{
-    //traceISR_EXIT_TO_SCHEDULER();
-    uxSchedulerRunning = 1;
-    xPortSwitchFlag = 1;
-}
-
-void vPortYieldOtherCore(BaseType_t coreid)
-{
-    esp_crosscore_int_send_yield(coreid);
-}

+ 1 - 1
components/freertos/FreeRTOS-Kernel/portable/riscv/include/freertos/portmacro.h

@@ -507,7 +507,7 @@ extern int xPortSwitchFlag;
 // --------------------- Debugging -------------------------
 
 #if CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION
-#define UNTESTED_FUNCTION() { esp_rom_printf("Untested FreeRTOS function %s\r\n", __FUNCTION__); configASSERT(false); } while(0)
+#define UNTESTED_FUNCTION() do{ esp_rom_printf("Untested FreeRTOS function %s\r\n", __FUNCTION__); configASSERT(false); } while(0)
 #else
 #define UNTESTED_FUNCTION()
 #endif

+ 1 - 1
components/freertos/FreeRTOS-Kernel/portable/xtensa/include/freertos/portmacro.h

@@ -760,7 +760,7 @@ extern uint32_t port_switch_flag[];
 // --------------------- Debugging -------------------------
 
 #if CONFIG_FREERTOS_ASSERT_ON_UNTESTED_FUNCTION
-#define UNTESTED_FUNCTION() { esp_rom_printf("Untested FreeRTOS function %s\r\n", __FUNCTION__); configASSERT(false); } while(0)
+#define UNTESTED_FUNCTION() do{ esp_rom_printf("Untested FreeRTOS function %s\r\n", __FUNCTION__); configASSERT(false); } while(0)
 #else
 #define UNTESTED_FUNCTION()
 #endif

+ 1 - 0
components/freertos/Kconfig

@@ -5,6 +5,7 @@ menu "FreeRTOS"
 
         config FREERTOS_SMP
             bool "Run the SMP FreeRTOS kernel instead (FEATURE UNDER DEVELOPMENT)"
+            depends on IDF_TARGET_ESP32 || IDF_TARGET_ESP32C3
             default  "n"
             help
                 This will cause the FreeRTOS component to compile with the SMP FreeRTOS kernel instead.