Add a GenericPlatformManager implementation based on CMSISOS V2 API (#35924)

* Add a GenericPlatformManager implementation based on CMSISOS V2 API

* Restyled by gn

* Fix efr32 test_driver build by including the needed headers as they were previously available through the freertos genericPlatformImplementation

* Address comments

---------

Co-authored-by: Restyled.io <commits@restyled.io>
diff --git a/src/include/platform/ConnectivityManager.h b/src/include/platform/ConnectivityManager.h
index 209d748..cac22ed 100644
--- a/src/include/platform/ConnectivityManager.h
+++ b/src/include/platform/ConnectivityManager.h
@@ -52,6 +52,8 @@
 template <class>
 class GenericPlatformManagerImpl;
 template <class>
+class GenericPlatformManagerImpl_CMSISOS;
+template <class>
 class GenericPlatformManagerImpl_FreeRTOS;
 template <class>
 class GenericPlatformManagerImpl_POSIX;
@@ -249,6 +251,8 @@
     template <class>
     friend class Internal::GenericPlatformManagerImpl;
     template <class>
+    friend class Internal::GenericPlatformManagerImpl_CMSISOS;
+    template <class>
     friend class Internal::GenericPlatformManagerImpl_FreeRTOS;
     template <class>
     friend class Internal::GenericPlatformManagerImpl_POSIX;
diff --git a/src/include/platform/PlatformManager.h b/src/include/platform/PlatformManager.h
index 4ce673e..c5fc1f1 100644
--- a/src/include/platform/PlatformManager.h
+++ b/src/include/platform/PlatformManager.h
@@ -53,6 +53,8 @@
 template <class>
 class GenericPlatformManagerImpl;
 template <class>
+class GenericPlatformManagerImpl_CMSISOS;
+template <class>
 class GenericPlatformManagerImpl_FreeRTOS;
 template <class>
 class GenericPlatformManagerImpl_POSIX;
@@ -261,6 +263,8 @@
     template <class>
     friend class Internal::GenericPlatformManagerImpl;
     template <class>
+    friend class Internal::GenericPlatformManagerImpl_CMSISOS;
+    template <class>
     friend class Internal::GenericPlatformManagerImpl_FreeRTOS;
     template <class>
     friend class Internal::GenericPlatformManagerImpl_POSIX;
diff --git a/src/include/platform/ThreadStackManager.h b/src/include/platform/ThreadStackManager.h
index f9f7aed..9498ad8 100644
--- a/src/include/platform/ThreadStackManager.h
+++ b/src/include/platform/ThreadStackManager.h
@@ -55,6 +55,8 @@
 template <class>
 class GenericConfigurationManagerImpl;
 template <class>
+class GenericPlatformManagerImpl_CMSISOS;
+template <class>
 class GenericPlatformManagerImpl_FreeRTOS;
 template <class>
 class GenericConnectivityManagerImpl_Thread;
@@ -168,6 +170,8 @@
     template <class>
     friend class Internal::GenericConfigurationManagerImpl;
     template <class>
+    friend class Internal::GenericPlatformManagerImpl_CMSISOS;
+    template <class>
     friend class Internal::GenericPlatformManagerImpl_FreeRTOS;
     template <class>
     friend class Internal::GenericConnectivityManagerImpl_Thread;
diff --git a/src/include/platform/internal/GenericPlatformManagerImpl_CMSISOS.h b/src/include/platform/internal/GenericPlatformManagerImpl_CMSISOS.h
new file mode 100644
index 0000000..e402815
--- /dev/null
+++ b/src/include/platform/internal/GenericPlatformManagerImpl_CMSISOS.h
@@ -0,0 +1,182 @@
+/*
+ *
+ *    Copyright (c) 2021-2024 Project CHIP Authors
+ *    All rights reserved.
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+/**
+ *    @file
+ *          Provides an generic implementation of PlatformManager features
+ *          for platform using CMSISOS 2 OS Abstraction APIs.
+ */
+
+#pragma once
+
+#include <platform/CHIPDeviceConfig.h>
+#include <platform/internal/GenericPlatformManagerImpl.h>
+
+#include <atomic>
+#include <cmsis_os2.h>
+
+namespace chip {
+namespace DeviceLayer {
+namespace Internal {
+
+/**
+ * Provides a generic implementation of PlatformManager features for platforms using CMSISOS 2 OS Abstraction APIs
+ *
+ * This template contains implementations of select features from the PlatformManager abstract
+ * interface that are suitable for use on CMSISOS-based platforms.  It is intended to be inherited
+ * (directly or indirectly) by the PlatformManagerImpl class, which also appears as the template's
+ * ImplClass parameter.
+ */
+template <class ImplClass>
+class GenericPlatformManagerImpl_CMSISOS : public GenericPlatformManagerImpl<ImplClass>
+{
+
+protected:
+    osMutexId_t mChipStackLock         = nullptr;
+    osMessageQueueId_t mChipEventQueue = nullptr;
+    osThreadId_t mEventLoopTask        = nullptr;
+    bool mChipTimerActive;
+
+#if defined(CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING) && CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING
+    osMessageQueueId_t mBackgroundEventQueue = nullptr;
+    osThreadId_t mBackgroundEventLoopTask    = nullptr;
+#endif
+
+    // ===== Methods that implement the PlatformManager abstract interface.
+
+    CHIP_ERROR _InitChipStack();
+
+    void _LockChipStack(void);
+    bool _TryLockChipStack(void);
+    void _UnlockChipStack(void);
+
+    CHIP_ERROR _PostEvent(const ChipDeviceEvent * event);
+    void _RunEventLoop(void);
+    CHIP_ERROR _StartEventLoopTask(void);
+    CHIP_ERROR _StopEventLoopTask();
+    CHIP_ERROR _StartChipTimer(System::Clock::Timeout duration);
+    void _Shutdown(void);
+
+#if CHIP_STACK_LOCK_TRACKING_ENABLED
+    bool _IsChipStackLockedByCurrentThread() const;
+#endif
+
+    CHIP_ERROR _PostBackgroundEvent(const ChipDeviceEvent * event);
+    void _RunBackgroundEventLoop(void);
+    CHIP_ERROR _StartBackgroundEventLoopTask(void);
+    CHIP_ERROR _StopBackgroundEventLoopTask();
+
+    // ===== Methods available to the implementation subclass.
+
+private:
+    // ===== Private members for use by this class only.
+
+    inline ImplClass * Impl() { return static_cast<ImplClass *>(this); }
+
+    static void EventLoopTaskMain(void * pvParameter);
+    uint32_t SyncNextChipTimerHandling();
+    uint32_t mNextTimerBaseTime      = 0;
+    uint32_t mNextTimerDurationTicks = 0;
+    std::atomic<bool> mShouldRunEventLoop;
+
+#if defined(CHIP_CONFIG_CMSISOS_USE_STATIC_QUEUE) && CHIP_CONFIG_CMSISOS_USE_STATIC_QUEUE
+    uint8_t mEventQueueBuffer[CHIP_DEVICE_CONFIG_MAX_EVENT_QUEUE_SIZE * sizeof(ChipDeviceEvent)];
+    osMessageQueue_t mEventQueueStruct;
+    const osMessageQueueAttr_t mEventQueueAttr = { .cb_mem  = &mEventQueueStruct,
+                                                   .cb_size = osMessageQueueCbSize,
+                                                   .mq_mem  = mEventQueueBuffer,
+                                                   .mq_size = sizeof(mEventQueueBuffer) };
+
+    const osMessageQueueAttr_t * mEventQueueAttrPtr = &mEventQueueAttr;
+#else
+    // Nothing to configure for queues, Just use this to avoid #ifdef in the class implementation
+    const osMessageQueueAttr_t * mEventQueueAttrPtr = nullptr;
+#endif // CHIP_CONFIG_CMSISOS_USE_STATIC_QUEUE
+
+#if defined(CHIP_CONFIG_CMSISOS_USE_STATIC_TASK) && CHIP_CONFIG_CMSISOS_USE_STATIC_TASK
+    uint8_t mEventLoopStack[CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE];
+    osThread_t mEventLoopTaskControlBlock;
+#endif // CHIP_CONFIG_CMSISOS_USE_STATIC_TASK
+
+    const osThreadAttr_t mEventLoopTaskAttr = {
+        .name      = CHIP_DEVICE_CONFIG_CHIP_TASK_NAME,
+        .attr_bits = osThreadDetached,
+#if defined(CHIP_CONFIG_CMSISOS_USE_STATIC_TASK) && CHIP_CONFIG_CMSISOS_USE_STATIC_TASK
+        .cb_mem    = &mEventLoopTaskControlBlock,
+        .cb_size   = osThreadCbSize,
+        .stack_mem = mEventLoopStack,
+#endif // CHIP_CONFIG_CMSISOS_USE_STATIC_TASK
+        .stack_size = CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE,
+        .priority   = CHIP_DEVICE_CONFIG_CHIP_TASK_PRIORITY
+    };
+
+#if defined(CHIP_CONFIG_CMSISOS_USE_STATIC_MUTEX) && CHIP_CONFIG_CMSISOS_USE_STATIC_MUTEX
+    osMutexCbSize uint8_t mMutexControlBlock[osMutexCbSize];
+#endif // CHIP_CONFIG_CMSISOS_USE_STATIC_MUTEX
+    const osMutexAttr_t mChipStackMutexAttr = {
+        .name = "",
+#if defined(CHIP_CONFIG_CMSISOS_USE_STATIC_MUTEX) && CHIP_CONFIG_CMSISOS_USE_STATIC_MUTEX
+        .cb_mem  = &mMutexControlBlock,
+        .cb_size = osMutexCbSize,
+#endif // CHIP_CONFIG_CMSISOS_USE_STATIC_MUTEX
+        .attr_bits = osMutexRecursive | osMutexPrioInherit,
+    };
+
+#if defined(CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING) && CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING
+    static void BackgroundEventLoopTaskMain(void * pvParameter);
+    std::atomic<bool> mShouldRunBackgroundEventLoop;
+
+#if defined(CHIP_CONFIG_CMSISOS_USE_STATIC_QUEUE) && CHIP_CONFIG_CMSISOS_USE_STATIC_QUEUE
+    uint8_t mBackgroundQueueBuffer[CHIP_DEVICE_CONFIG_BG_MAX_EVENT_QUEUE_SIZE * sizeof(ChipDeviceEvent)];
+    osMessageQueue_t mBackgroundQueueStruct;
+    const osMessageQueueAttr_t mBgQueueAttr = { .cb_mem  = &mBackgroundQueueStruct,
+                                                .cb_size = osMessageQueueCbSize,
+                                                .mq_mem  = mBackgroundQueueBuffer,
+                                                .mq_size = sizeof(mBackgroundQueueBuffer) };
+
+    const osMessageQueueAttr_t * mBgQueueAttrPtr = &mBgQueueAttr;
+#else
+    // Nothing to configure for queues, Just use this to avoid #ifdef in the class implementation
+    const osMessageQueueAttr_t * mBgQueueAttrPtr = nullptr;
+#endif // CHIP_CONFIG_CMSISOS_USE_STATIC_QUEUE
+
+#if defined(CHIP_CONFIG_CMSISOS_USE_STATIC_TASK) && CHIP_CONFIG_CMSISOS_USE_STATIC_TASK
+    uint8_t mBackgroundEventLoopStack[CHIP_DEVICE_CONFIG_BG_TASK_STACK_SIZE];
+    osThread_t mBackgroundEventLoopTaskControlBlock;
+#endif // CHIP_CONFIG_CMSISOS_USE_STATIC_TASK
+
+    const osThreadAttr_t mBgEventLoopTaskAttr = {
+        .name      = CHIP_DEVICE_CONFIG_BG_TASK_NAME,
+        .attr_bits = osThreadDetached,
+#if defined(CHIP_CONFIG_CMSISOS_USE_STATIC_TASK) && CHIP_CONFIG_CMSISOS_USE_STATIC_TASK
+        .cb_mem    = &mBackgroundEventLoopTaskControlBlock,
+        .cb_size   = osThreadCbSize,
+        .stack_mem = mBackgroundEventLoopStack,
+#endif // CHIP_CONFIG_CMSISOS_USE_STATIC_TASK
+        .stack_size = CHIP_DEVICE_CONFIG_BG_TASK_STACK_SIZE,
+        .priority   = CHIP_DEVICE_CONFIG_BG_TASK_PRIORITY
+    };
+#endif // CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING
+};
+
+// Instruct the compiler to instantiate the template only when explicitly told to do so.
+extern template class GenericPlatformManagerImpl_CMSISOS<PlatformManagerImpl>;
+
+} // namespace Internal
+} // namespace DeviceLayer
+} // namespace chip
diff --git a/src/include/platform/internal/GenericPlatformManagerImpl_CMSISOS.ipp b/src/include/platform/internal/GenericPlatformManagerImpl_CMSISOS.ipp
new file mode 100644
index 0000000..b75fcbe
--- /dev/null
+++ b/src/include/platform/internal/GenericPlatformManagerImpl_CMSISOS.ipp
@@ -0,0 +1,375 @@
+/*
+ *
+ *    Copyright (c) 2021-2024 Project CHIP Authors
+ *    All rights reserved.
+ *
+ *    Licensed under the Apache License, Version 2.0 (the "License");
+ *    you may not use this file except in compliance with the License.
+ *    You may obtain a copy of the License at
+ *
+ *        http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *    Unless required by applicable law or agreed to in writing, software
+ *    distributed under the License is distributed on an "AS IS" BASIS,
+ *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *    See the License for the specific language governing permissions and
+ *    limitations under the License.
+ */
+
+/**
+ *    @file
+ *          Contains non-inline method definitions for the
+ *          GenericPlatformManagerImpl_CMSISOS<> template.
+ */
+
+#ifndef GENERIC_PLATFORM_MANAGER_IMPL_CMSISOS_CPP
+#define GENERIC_PLATFORM_MANAGER_IMPL_CMSISOS_CPP
+
+#include <platform/PlatformManager.h>
+#include <platform/internal/CHIPDeviceLayerInternal.h>
+#include <platform/internal/GenericPlatformManagerImpl_CMSISOS.h>
+
+#include <lib/support/CodeUtils.h>
+
+// Include the non-inline definitions for the GenericPlatformManagerImpl<> template,
+// from which the GenericPlatformManagerImpl_CMSISOS<> template inherits.
+#include <platform/internal/GenericPlatformManagerImpl.ipp>
+
+namespace chip {
+namespace DeviceLayer {
+namespace Internal {
+
+template <class ImplClass>
+CHIP_ERROR GenericPlatformManagerImpl_CMSISOS<ImplClass>::_InitChipStack(void)
+{
+    mNextTimerBaseTime      = osKernelGetTickCount();
+    mNextTimerDurationTicks = 0;
+    mChipTimerActive        = false;
+
+    // We support calling Shutdown followed by InitChipStack, because some tests
+    // do that.  To keep things simple for existing consumers, we do not
+    // destroy our lock and queue at shutdown, but rather check whether they
+    // already exist here before trying to create them.
+    if (mChipStackLock == nullptr)
+    {
+        mChipStackLock = osMutexNew(&mChipStackMutexAttr);
+        VerifyOrReturnError(mChipStackLock != nullptr, CHIP_ERROR_NO_MEMORY,
+                            ChipLogError(DeviceLayer, "Failed to create CHIP stack lock"));
+    }
+
+    if (mChipEventQueue == nullptr)
+    {
+        mChipEventQueue = osMessageQueueNew(CHIP_DEVICE_CONFIG_MAX_EVENT_QUEUE_SIZE, sizeof(ChipDeviceEvent), mEventQueueAttrPtr);
+        VerifyOrReturnError(mChipEventQueue != nullptr, CHIP_ERROR_NO_MEMORY,
+                            ChipLogError(DeviceLayer, "Failed to allocate CHIP main event queue"));
+    }
+    else
+    {
+        // Clear out any events that might be stuck in the queue, so we start
+        // with a clean slate, as if we had just re-created the queue.
+        osMessageQueueReset(mChipEventQueue);
+    }
+
+    mShouldRunEventLoop.store(false);
+
+#if defined(CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING) && CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING
+    if (mBackgroundEventQueue == nullptr)
+    {
+        mBackgroundEventQueue =
+            osMessageQueueNew(CHIP_DEVICE_CONFIG_BG_MAX_EVENT_QUEUE_SIZE, sizeof(ChipDeviceEvent), mBgQueueAttrPtr);
+        VerifyOrReturnError(mBackgroundEventQueue != nullptr, CHIP_ERROR_NO_MEMORY,
+                            ChipLogError(DeviceLayer, "Failed to allocate CHIP background event queue"));
+    }
+    else
+    {
+        osMessageQueueReset(mBackgroundEventQueue);
+    }
+
+    mShouldRunBackgroundEventLoop.store(false);
+#endif
+
+    // Call up to the base class _InitChipStack() to perform the bulk of the initialization.
+    return GenericPlatformManagerImpl<ImplClass>::_InitChipStack();
+}
+
+template <class ImplClass>
+void GenericPlatformManagerImpl_CMSISOS<ImplClass>::_LockChipStack(void)
+{
+    osMutexAcquire(mChipStackLock, osWaitForever);
+}
+
+template <class ImplClass>
+bool GenericPlatformManagerImpl_CMSISOS<ImplClass>::_TryLockChipStack(void)
+{
+    return osMutexAcquire(mChipStackLock, 0) == osOK;
+}
+
+template <class ImplClass>
+void GenericPlatformManagerImpl_CMSISOS<ImplClass>::_UnlockChipStack(void)
+{
+    osMutexRelease(mChipStackLock);
+}
+
+#if CHIP_STACK_LOCK_TRACKING_ENABLED
+template <class ImplClass>
+bool GenericPlatformManagerImpl_CMSISOS<ImplClass>::_IsChipStackLockedByCurrentThread() const
+{
+    // If we have not started our event loop yet, return true because in that
+    // case we can't be racing against the (not yet started) event loop.
+    //
+    // Similarly, if mChipStackLock has not been created yet, might as well
+    // return true.
+    return (mEventLoopTask == nullptr) || (mChipStackLock == nullptr) || (osMutexGetOwner(mChipStackLock) == osThreadGetId());
+}
+#endif // CHIP_STACK_LOCK_TRACKING_ENABLED
+
+template <class ImplClass>
+CHIP_ERROR GenericPlatformManagerImpl_CMSISOS<ImplClass>::_PostEvent(const ChipDeviceEvent * event)
+{
+    VerifyOrReturnError(mChipEventQueue != nullptr, CHIP_ERROR_UNINITIALIZED);
+
+    osStatus_t status = osMessageQueuePut(mChipEventQueue, event, osPriorityNormal, 1);
+    if (status != osOK)
+    {
+        ChipLogError(DeviceLayer, "Failed to post event to CHIP Platform event queue");
+        return CHIP_ERROR(chip::ChipError::Range::kOS, status);
+    }
+    return CHIP_NO_ERROR;
+}
+
+template <class ImplClass>
+void GenericPlatformManagerImpl_CMSISOS<ImplClass>::_RunEventLoop(void)
+{
+    // Lock the CHIP stack.
+    StackLock lock;
+
+    bool oldShouldRunEventLoop = false;
+    if (!mShouldRunEventLoop.compare_exchange_strong(oldShouldRunEventLoop /* expected */, true /* desired */))
+    {
+        ChipLogError(DeviceLayer, "Error trying to run the event loop while it is already running");
+        return;
+    }
+
+    while (mShouldRunEventLoop.load())
+    {
+        uint32_t waitTimeInTicks;
+
+        // If one or more CHIP timers are active...
+        if (mChipTimerActive)
+        {
+            // Adjust the base time and remaining duration for the next scheduled timer based on the
+            // amount of time that has elapsed since it was started.
+            // When the timer's expiration time elapses, Handle the platform Timer
+            // else wait for a queue event for timer remaining time.
+            waitTimeInTicks = SyncNextChipTimerHandling();
+            if (waitTimeInTicks == 0)
+            {
+                // Reset the 'timer active' flag.  This will be set to true again by _StartChipTimer()
+                // if there are further timers beyond the expired one that are still active.
+                mChipTimerActive = false;
+
+                // Call into the system layer to dispatch the callback functions for all timers
+                // that have expired.
+                // TODO We use the same SystemLayer implementation as FreeRTOS, Nothing in it is freeRTOS specific. We should
+                // it.
+                CHIP_ERROR err = static_cast<System::LayerImplFreeRTOS &>(DeviceLayer::SystemLayer()).HandlePlatformTimer();
+                if (err != CHIP_NO_ERROR)
+                {
+                    ChipLogError(DeviceLayer, "Error handling CHIP timers: %" CHIP_ERROR_FORMAT, err.Format());
+                }
+            }
+        }
+        else
+        {
+            // No CHIP timers are active, so we wait indefinitely for an event to arrive on the event
+            // queue.
+            waitTimeInTicks = osWaitForever;
+        }
+
+        // Unlock the CHIP stack, allowing other threads to enter CHIP while
+        // the event loop thread is sleeping.
+        StackUnlock unlock;
+        ChipDeviceEvent event;
+        osStatus_t eventReceived = osMessageQueueGet(mChipEventQueue, &event, nullptr, waitTimeInTicks);
+
+        // If an event was received, dispatch it and continue until the queue is empty.
+        while (eventReceived == osOK)
+        {
+            StackLock lock;
+            Impl()->DispatchEvent(&event);
+            StackUnlock unlock;
+            eventReceived = osMessageQueueGet(mChipEventQueue, &event, nullptr, 0);
+        }
+    }
+}
+
+template <class ImplClass>
+CHIP_ERROR GenericPlatformManagerImpl_CMSISOS<ImplClass>::_StartEventLoopTask(void)
+{
+    mEventLoopTask = osThreadNew(EventLoopTaskMain, this, &mEventLoopTaskAttr);
+    return (mEventLoopTask != nullptr) ? CHIP_NO_ERROR : CHIP_ERROR_NO_MEMORY;
+}
+
+template <class ImplClass>
+void GenericPlatformManagerImpl_CMSISOS<ImplClass>::EventLoopTaskMain(void * pvParameter)
+{
+    ChipLogDetail(DeviceLayer, "CHIP event task running");
+    static_cast<GenericPlatformManagerImpl_CMSISOS<ImplClass> *>(pvParameter)->Impl()->RunEventLoop();
+}
+
+/**
+ * @brief Calculate the elapsed time of the active chip platform timer since it has been started,
+ *        as set in mNextTimerBaseTime, and adjust its remaining time with the mNextTimerDurationTicks member
+ *
+ * @return The next Timer remaining time in ticks
+ */
+template <class ImplClass>
+uint32_t GenericPlatformManagerImpl_CMSISOS<ImplClass>::SyncNextChipTimerHandling()
+{
+    uint32_t elapsedTime   = 0;
+    uint32_t timerBaseTime = mNextTimerBaseTime;
+    uint32_t currentTime   = osKernelGetTickCount();
+    if (currentTime < timerBaseTime)
+    {
+        // TickCount has wrapped around
+        elapsedTime = (UINT32_MAX - timerBaseTime) + currentTime;
+    }
+    else
+    {
+        elapsedTime = currentTime - timerBaseTime;
+    }
+
+    if (elapsedTime < mNextTimerDurationTicks)
+    {
+        // We didn't timeout yet, adjust the remaining time
+        mNextTimerDurationTicks -= elapsedTime;
+        mNextTimerBaseTime = osKernelGetTickCount();
+    }
+    else
+    {
+        mNextTimerDurationTicks = 0;
+    }
+    return mNextTimerDurationTicks;
+}
+
+template <class ImplClass>
+CHIP_ERROR GenericPlatformManagerImpl_CMSISOS<ImplClass>::_PostBackgroundEvent(const ChipDeviceEvent * event)
+{
+#if defined(CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING) && CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING
+    VerifyOrReturnError(mBackgroundEventQueue != nullptr, CHIP_ERROR_UNINITIALIZED);
+    if (!(event->Type == DeviceEventType::kCallWorkFunct || event->Type == DeviceEventType::kNoOp))
+    {
+        return CHIP_ERROR_INVALID_ARGUMENT;
+    }
+
+    osStatus_t status = osMessageQueuePut(mBackgroundEventQueue, event, osPriorityNormal, 1);
+    VerifyOrReturnError(status == osOk, CHIP_ERROR_NO_MEMORY,
+                        ChipLogError(DeviceLayer, "Failed to post event to CHIP background event queue"));
+    return CHIP_NO_ERROR;
+#else
+    // Use foreground event loop for background events
+    return _PostEvent(event);
+#endif
+}
+
+template <class ImplClass>
+void GenericPlatformManagerImpl_CMSISOS<ImplClass>::_RunBackgroundEventLoop(void)
+{
+#if defined(CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING) && CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING
+    bool oldShouldRunBackgroundEventLoop = false;
+    VerifyOrReturn(
+        mShouldRunBackgroundEventLoop.compare_exchange_strong(oldShouldRunBackgroundEventLoop /* expected */, true /* desired */),
+        ChipLogError(DeviceLayer, "Error trying to run the background event loop while it is already running"));
+
+    while (mShouldRunBackgroundEventLoop.load())
+    {
+        ChipDeviceEvent event;
+        osStatus_t eventReceived = osMessageQueueGet(mBackgroundEventQueue, &event, NULL, osWaitForever);
+        while (eventReceived == osOK)
+        {
+            Impl()->DispatchEvent(&event);
+            eventReceived = osMessageQueueGet(mBackgroundEventQueue, &event, portMAX_DELAY);
+        }
+    }
+#endif
+}
+
+template <class ImplClass>
+CHIP_ERROR GenericPlatformManagerImpl_CMSISOS<ImplClass>::_StartBackgroundEventLoopTask(void)
+{
+#if defined(CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING) && CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING
+    mBackgroundEventLoopTask = osThreadNew(BackgroundEventLoopTaskMain, this, &mBgEventLoopTaskAttr);
+    return (mBackgroundEventLoopTask != NULL) ? CHIP_NO_ERROR : CHIP_ERROR_NO_MEMORY;
+#else
+    // Use foreground event loop for background events
+    return CHIP_NO_ERROR;
+#endif
+}
+
+template <class ImplClass>
+CHIP_ERROR GenericPlatformManagerImpl_CMSISOS<ImplClass>::_StopBackgroundEventLoopTask(void)
+{
+#if defined(CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING) && CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING
+    bool oldShouldRunBackgroundEventLoop = true;
+    if (mShouldRunBackgroundEventLoop.compare_exchange_strong(oldShouldRunBackgroundEventLoop /* expected */, false /* desired */))
+    {
+        ChipDeviceEvent noop{ .Type = DeviceEventType::kNoOp };
+        osMessageQueuePut(mBackgroundEventQueue, &noop, osPriorityNormal, 0);
+    }
+    return CHIP_NO_ERROR;
+#else
+    // Use foreground event loop for background events
+    return CHIP_NO_ERROR;
+#endif
+}
+
+#if defined(CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING) && CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING
+template <class ImplClass>
+void GenericPlatformManagerImpl_CMSISOS<ImplClass>::BackgroundEventLoopTaskMain(void * pvParameter)
+{
+    ChipLogDetail(DeviceLayer, "CHIP background task running");
+    static_cast<GenericPlatformManagerImpl_CMSISOS<ImplClass> *>(pvParameter)->Impl()->RunBackgroundEventLoop();
+}
+#endif
+
+template <class ImplClass>
+CHIP_ERROR GenericPlatformManagerImpl_CMSISOS<ImplClass>::_StartChipTimer(System::Clock::Timeout delay)
+{
+    mChipTimerActive        = true;
+    mNextTimerBaseTime      = osKernelGetTickCount();
+    mNextTimerDurationTicks = (System::Clock::Milliseconds64(delay).count() * osKernelGetTickFreq()) / 1000;
+
+    // If the platform timer is being updated by a thread other than the event loop thread,
+    // trigger the event loop thread to recalculate its wait time by posting a no-op event
+    // to the event queue.
+    if (osThreadGetId() != mEventLoopTask)
+    {
+        ChipDeviceEvent noop{ .Type = DeviceEventType::kNoOp };
+        ReturnErrorOnFailure(Impl()->PostEvent(&noop));
+    }
+
+    return CHIP_NO_ERROR;
+}
+
+template <class ImplClass>
+void GenericPlatformManagerImpl_CMSISOS<ImplClass>::_Shutdown(void)
+{
+    GenericPlatformManagerImpl<ImplClass>::_Shutdown();
+}
+
+template <class ImplClass>
+CHIP_ERROR GenericPlatformManagerImpl_CMSISOS<ImplClass>::_StopEventLoopTask(void)
+{
+    mShouldRunEventLoop.store(false);
+    return CHIP_NO_ERROR;
+}
+
+// Fully instantiate the generic implementation class in whatever compilation unit includes this file.
+// NB: This must come after all templated class members are defined.
+template class GenericPlatformManagerImpl_CMSISOS<PlatformManagerImpl>;
+
+} // namespace Internal
+} // namespace DeviceLayer
+} // namespace chip
+
+#endif // GENERIC_PLATFORM_MANAGER_IMPL_CMSISOS_CPP
diff --git a/src/platform/BUILD.gn b/src/platform/BUILD.gn
index d379bd0..7f0b7ff 100644
--- a/src/platform/BUILD.gn
+++ b/src/platform/BUILD.gn
@@ -496,6 +496,8 @@
       "../include/platform/internal/GenericDeviceInstanceInfoProvider.ipp",
       "../include/platform/internal/GenericPlatformManagerImpl.h",
       "../include/platform/internal/GenericPlatformManagerImpl.ipp",
+      "../include/platform/internal/GenericPlatformManagerImpl_CMSISOS.h",
+      "../include/platform/internal/GenericPlatformManagerImpl_CMSISOS.ipp",
       "../include/platform/internal/GenericPlatformManagerImpl_FreeRTOS.h",
       "../include/platform/internal/GenericPlatformManagerImpl_FreeRTOS.ipp",
       "../include/platform/internal/GenericPlatformManagerImpl_POSIX.h",
diff --git a/src/platform/FreeRTOS/SystemTimeSupport.cpp b/src/platform/FreeRTOS/SystemTimeSupport.cpp
index a14c052..12fa8e6 100644
--- a/src/platform/FreeRTOS/SystemTimeSupport.cpp
+++ b/src/platform/FreeRTOS/SystemTimeSupport.cpp
@@ -28,6 +28,7 @@
 #include <lib/support/TimeUtils.h>
 
 #include "FreeRTOS.h"
+#include "task.h"
 
 namespace chip {
 namespace System {
diff --git a/src/platform/silabs/CHIPDevicePlatformConfig.h b/src/platform/silabs/CHIPDevicePlatformConfig.h
index d8c58a9..7e86c64 100644
--- a/src/platform/silabs/CHIPDevicePlatformConfig.h
+++ b/src/platform/silabs/CHIPDevicePlatformConfig.h
@@ -23,6 +23,8 @@
  */
 
 #pragma once
+#include <cmsis_os2.h>
+#include <sl_cmsis_os2_common.h>
 
 // ==================== Platform Adaptations ====================
 
@@ -129,6 +131,10 @@
 
 // ========== Platform-specific Configuration Overrides =========
 
+#ifndef CHIP_DEVICE_CONFIG_CHIP_TASK_PRIORITY
+#define CHIP_DEVICE_CONFIG_CHIP_TASK_PRIORITY osPriorityHigh
+#endif
+
 #ifndef CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE
 #if SLI_SI91X_MCU_INTERFACE
 #define CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE (7 * 1024)
diff --git a/src/platform/silabs/CHIPPlatformConfig.h b/src/platform/silabs/CHIPPlatformConfig.h
index c6c855e..c72c7fa 100644
--- a/src/platform/silabs/CHIPPlatformConfig.h
+++ b/src/platform/silabs/CHIPPlatformConfig.h
@@ -129,13 +129,13 @@
 #define CHIP_SHELL_MAX_LINE_SIZE 256
 #endif // CHIP_SHELL_MAX_LINE_SIZE
 
-// ==================== FreeRTOS Configuration Overrides ====================
-#ifndef CHIP_CONFIG_FREERTOS_USE_STATIC_TASK
-#define CHIP_CONFIG_FREERTOS_USE_STATIC_TASK 1
+// ==================== CMSISOS Configuration Overrides ====================
+#ifndef CHIP_CONFIG_CMSISOS_USE_STATIC_TASK
+#define CHIP_CONFIG_CMSISOS_USE_STATIC_TASK 1
 #endif
 
-#ifndef CHIP_CONFIG_FREERTOS_USE_STATIC_QUEUE
-#define CHIP_CONFIG_FREERTOS_USE_STATIC_QUEUE 1
+#ifndef CHIP_CONFIG_CMSISOS_USE_STATIC_QUEUE
+#define CHIP_CONFIG_CMSISOS_USE_STATIC_QUEUE 1
 #endif
 
 #ifndef CHIP_SHELL_MAX_TOKENS
diff --git a/src/platform/silabs/ConfigurationManagerImpl.cpp b/src/platform/silabs/ConfigurationManagerImpl.cpp
index 1227999..b4dd5c9 100644
--- a/src/platform/silabs/ConfigurationManagerImpl.cpp
+++ b/src/platform/silabs/ConfigurationManagerImpl.cpp
@@ -22,6 +22,7 @@
  *          for Silabs platforms using the Silicon Labs SDK.
  */
 /* this file behaves like a config.h, comes first */
+#include <cmsis_os2.h>
 #include <platform/ConfigurationManager.h>
 #include <platform/DiagnosticDataProvider.h>
 #include <platform/internal/CHIPDeviceLayerInternal.h>
@@ -304,7 +305,7 @@
     // When called from an RPC, the following reset occurs before the RPC can respond,
     // which breaks tests (because it looks like the RPC hasn't successfully completed).
     // Block the task for 500 ms before the reset occurs to allow RPC response to be sent
-    vTaskDelay(pdMS_TO_TICKS(500));
+    osDelay(pdMS_TO_TICKS(500));
 
     NVIC_SystemReset();
 }
diff --git a/src/platform/silabs/Logging.cpp b/src/platform/silabs/Logging.cpp
index 339bc8a..dea8913 100644
--- a/src/platform/silabs/Logging.cpp
+++ b/src/platform/silabs/Logging.cpp
@@ -293,13 +293,6 @@
     }
 
     PrintLog(formattedMsg);
-
-#if configCHECK_FOR_STACK_OVERFLOW
-    // Force a stack overflow check.
-    if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
-        taskYIELD();
-#endif
-
     // Let the application know that a log message has been emitted.
     chip::DeviceLayer::OnLogOutput();
 #endif // SILABS_LOG_ENABLED
@@ -348,12 +341,6 @@
         }
 
         PrintLog(formattedMsg);
-
-#if configCHECK_FOR_STACK_OVERFLOW
-        // Force a stack overflow check.
-        if (xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED)
-            taskYIELD();
-#endif
     }
 
     // Let the application know that a log message has been emitted.
diff --git a/src/platform/silabs/PlatformManagerImpl.cpp b/src/platform/silabs/PlatformManagerImpl.cpp
index 14dd4f7..dccb5db 100644
--- a/src/platform/silabs/PlatformManagerImpl.cpp
+++ b/src/platform/silabs/PlatformManagerImpl.cpp
@@ -28,7 +28,7 @@
 #include <platform/FreeRTOS/SystemTimeSupport.h>
 #include <platform/KeyValueStoreManager.h>
 #include <platform/PlatformManager.h>
-#include <platform/internal/GenericPlatformManagerImpl_FreeRTOS.ipp>
+#include <platform/internal/GenericPlatformManagerImpl_CMSISOS.ipp>
 #include <platform/silabs/DiagnosticDataProviderImpl.h>
 
 #if defined(SL_MBEDTLS_USE_TINYCRYPT)
@@ -104,7 +104,7 @@
 
     // Call _InitChipStack() on the generic implementation base class
     // to finish the initialization process.
-    err = Internal::GenericPlatformManagerImpl_FreeRTOS<PlatformManagerImpl>::_InitChipStack();
+    err = Internal::GenericPlatformManagerImpl_CMSISOS<PlatformManagerImpl>::_InitChipStack();
     SuccessOrExit(err);
 
     // Start timer to increment TotalOperationalHours every hour
@@ -129,9 +129,10 @@
 
     SystemLayer().StartTimer(System::Clock::Seconds32(kSecondsPerHour), UpdateOperationalHours, NULL);
 }
+
 void PlatformManagerImpl::_Shutdown()
 {
-    Internal::GenericPlatformManagerImpl_FreeRTOS<PlatformManagerImpl>::_Shutdown();
+    Internal::GenericPlatformManagerImpl_CMSISOS<PlatformManagerImpl>::_Shutdown();
 }
 
 #if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION
diff --git a/src/platform/silabs/PlatformManagerImpl.h b/src/platform/silabs/PlatformManagerImpl.h
index 25813af..1abbb9f 100644
--- a/src/platform/silabs/PlatformManagerImpl.h
+++ b/src/platform/silabs/PlatformManagerImpl.h
@@ -24,7 +24,7 @@
 
 #pragma once
 
-#include <platform/internal/GenericPlatformManagerImpl_FreeRTOS.h>
+#include <platform/internal/GenericPlatformManagerImpl_CMSISOS.h>
 #if CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION
 #include "wfx_host_events.h"
 #endif
@@ -36,7 +36,7 @@
 /**
  * Concrete implementation of the PlatformManager singleton object for the SILABS platform.
  */
-class PlatformManagerImpl final : public PlatformManager, public Internal::GenericPlatformManagerImpl_FreeRTOS<PlatformManagerImpl>
+class PlatformManagerImpl final : public PlatformManager, public Internal::GenericPlatformManagerImpl_CMSISOS<PlatformManagerImpl>
 {
     // Allow the PlatformManager interface class to delegate method calls to
     // the implementation methods provided by this class.
@@ -57,7 +57,7 @@
     // Allow the generic implementation base class to call helper methods on
     // this class.
 #ifndef DOXYGEN_SHOULD_SKIP_THIS
-    friend Internal::GenericPlatformManagerImpl_FreeRTOS<PlatformManagerImpl>;
+    friend Internal::GenericPlatformManagerImpl_CMSISOS<PlatformManagerImpl>;
 #endif
 
 public:
@@ -87,8 +87,6 @@
     System::Clock::Timestamp mStartTime = System::Clock::kZero;
 
     static PlatformManagerImpl sInstance;
-
-    using Internal::GenericPlatformManagerImpl_FreeRTOS<PlatformManagerImpl>::PostEventFromISR;
 };
 
 /**