diff --git a/erpc_c/setup/erpc_mbf_setup.h b/erpc_c/setup/erpc_mbf_setup.h index 6cd79b3c..826ab2d0 100644 --- a/erpc_c/setup/erpc_mbf_setup.h +++ b/erpc_c/setup/erpc_mbf_setup.h @@ -29,7 +29,23 @@ typedef struct ErpcMessageBufferFactory *erpc_mbf_t; // API //////////////////////////////////////////////////////////////////////////////// +#if __cplusplus > 201703L +#include "erpc_setup_mbf_static_fixed.h" + +/*! + * @brief Create MessageBuffer factory which is using static fixed allocated buffers. + */ +template +erpc_mbf_t erpc_mbf_static_fixed_init(void){ + static ManuallyConstructed> s_msgFactory; + s_msgFactory.construct(); + return reinterpret_cast(s_msgFactory.get()); + return nullptr; +} +#endif + #ifdef __cplusplus + extern "C" { #endif diff --git a/erpc_c/setup/erpc_setup_mbf_static_fixed.h b/erpc_c/setup/erpc_setup_mbf_static_fixed.h new file mode 100644 index 00000000..62cef00f --- /dev/null +++ b/erpc_c/setup/erpc_setup_mbf_static_fixed.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2014-2016, Freescale Semiconductor, Inc. + * Copyright 2016-2020 NXP + * Copyright 2021 ACRIOS Systems s.r.o. + * Copyright 2021 DroidDrive GmbH + * All rights reserved. + * + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef _ERPC_SETUP_MBF_STATIC_FIXED_H_ +#define _ERPC_SETUP_MBF_STATIC_FIXED_H_ + +#include "erpc_config_internal.h" +#include "erpc_manually_constructed.h" +#include "erpc_mbf_setup.h" +#include "erpc_message_buffer.h" + +#include +#include +#include + +using namespace erpc; + +//////////////////////////////////////////////////////////////////////////////// +// Classes +//////////////////////////////////////////////////////////////////////////////// + +/*! + * @brief Static Message buffer factory + */ +template +class StaticFixedMessageBufferFactory : public MessageBufferFactory +{ +private: + static constexpr std::array init_free_buffer_bitmap() { + std::array a{}; + for(size_t i = 0; i < BUFFER_COUNT; i++) { + a[i] = true; + } + return a; + }; + template + static constexpr void init_buffer(T* b) { + for(size_t j = 0; j < WORD_COUNT; j++){ + b[j] = T{0}; + } + return; + }; + static constexpr std::array, BUFFER_COUNT> init_buffers() { + std::array, BUFFER_COUNT> bufs = {{}}; + for(size_t i = 0; i < BUFFER_COUNT; i++) { + init_buffer(bufs[i].data()); + } + return bufs; + }; +public: + /*! + * @brief Constructor. + */ + StaticFixedMessageBufferFactory(void) {} + /*! + * @brief This function creates new message buffer. + * + * @return MessageBuffer New created MessageBuffer. + */ + virtual MessageBuffer create(void) + { + WORD_SIZE* bufPtr = nullptr; + /// check free buffers and return first free one + for(size_t i = 0; i < BUFFER_COUNT; i++){ + bool free = free_buffer_bitmap_[i]; + if(free) + { + free_buffer_bitmap_[i] = false; + bufPtr = static_cast(buffers_[i].data()); + break; + } + } + // if free buffer found, return that + assert(nullptr != bufPtr); + uint8_t* buf = static_cast(bufPtr); + return MessageBuffer(buf, WORD_COUNT); + } + + /*! + * @brief This function disposes message buffer. + * + * @param[in] buf MessageBuffer to dispose. + */ + virtual void dispose(MessageBuffer *buf) + { + assert(buf); + uint8_t* bufPtr = buf->get(); + if (bufPtr != nullptr) + { + // check buf ptr against all current buffers to see which one it was + for(size_t i = 0; i < BUFFER_COUNT; i++) + { + uint8_t* internalBufPtr = static_cast(buffers_[i].data()); + if(bufPtr == internalBufPtr){ + free_buffer_bitmap_[i] = true; + init_buffer(bufPtr); + } + } + } + } + +protected: + static inline auto free_buffer_bitmap_ = init_free_buffer_bitmap(); + static inline auto buffers_ = init_buffers(); +}; + +#endif // _ERPC_SETUP_MBF_STATIC_FIXED_H_ \ No newline at end of file