/* * * Copyright (c) 2020 Project CHIP Authors * Copyright (c) 2018 Nest Labs, Inc. * * 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 use on FreeRTOS platforms. */ #pragma once #include #include #if defined(ESP_PLATFORM) #include "freertos/FreeRTOS.h" #include "freertos/queue.h" #include "freertos/semphr.h" #include "freertos/task.h" #else #include "FreeRTOS.h" #include "queue.h" #include "semphr.h" #include "task.h" #endif #include namespace chip { namespace DeviceLayer { namespace Internal { /** * Provides a generic implementation of PlatformManager features that works on FreeRTOS platforms. * * This template contains implementations of select features from the PlatformManager abstract * interface that are suitable for use on FreeRTOS-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 GenericPlatformManagerImpl_FreeRTOS : public GenericPlatformManagerImpl { protected: TimeOut_t mNextTimerBaseTime; TickType_t mNextTimerDurationTicks; SemaphoreHandle_t mChipStackLock = NULL; QueueHandle_t mChipEventQueue = NULL; TaskHandle_t mEventLoopTask = NULL; bool mChipTimerActive; #if defined(CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING) && CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING QueueHandle_t mBackgroundEventQueue = NULL; TaskHandle_t mBackgroundEventLoopTask = NULL; #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. void PostEventFromISR(const ChipDeviceEvent * event, BaseType_t & yieldRequired); private: // ===== Private members for use by this class only. inline ImplClass * Impl() { return static_cast(this); } static void EventLoopTaskMain(void * arg); #if defined(CHIP_CONFIG_FREERTOS_USE_STATIC_QUEUE) && CHIP_CONFIG_FREERTOS_USE_STATIC_QUEUE uint8_t mEventQueueBuffer[CHIP_DEVICE_CONFIG_MAX_EVENT_QUEUE_SIZE * sizeof(ChipDeviceEvent)]; StaticQueue_t mEventQueueStruct; #endif #if defined(CHIP_CONFIG_FREERTOS_USE_STATIC_TASK) && CHIP_CONFIG_FREERTOS_USE_STATIC_TASK StackType_t mEventLoopStack[CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE / sizeof(StackType_t)]; StaticTask_t mEventLoopTaskStruct; #endif std::atomic mShouldRunEventLoop; #if defined(CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING) && CHIP_DEVICE_CONFIG_ENABLE_BG_EVENT_PROCESSING static void BackgroundEventLoopTaskMain(void * arg); #if defined(CHIP_CONFIG_FREERTOS_USE_STATIC_QUEUE) && CHIP_CONFIG_FREERTOS_USE_STATIC_QUEUE uint8_t mBackgroundQueueBuffer[CHIP_DEVICE_CONFIG_BG_MAX_EVENT_QUEUE_SIZE * sizeof(ChipDeviceEvent)]; StaticQueue_t mBackgroundQueueStruct; #endif #if defined(CHIP_CONFIG_FREERTOS_USE_STATIC_TASK) && CHIP_CONFIG_FREERTOS_USE_STATIC_TASK StackType_t mBackgroundEventLoopStack[CHIP_DEVICE_CONFIG_BG_TASK_STACK_SIZE / sizeof(StackType_t)]; StaticTask_t mBackgroundEventLoopTaskStruct; #endif std::atomic mShouldRunBackgroundEventLoop; #endif #if defined(CHIP_CONFIG_FREERTOS_USE_STATIC_SEMAPHORE) && CHIP_CONFIG_FREERTOS_USE_STATIC_SEMAPHORE StaticSemaphore_t mChipStackLockMutex; #endif }; // Instruct the compiler to instantiate the template only when explicitly told to do so. extern template class GenericPlatformManagerImpl_FreeRTOS; } // namespace Internal } // namespace DeviceLayer } // namespace chip