Repository: EmbeddedRPC/erpc (language: python)

Issue:
Allow usage of rpmsg static freertos related api
This change depends on https://github.com/NXPmicro/rpmsg-lite/pull/14


Discussion / hints:

Fix patch:
diff --git a/erpc_c/config/erpc_config.h b/erpc_c/config/erpc_config.h
index 74f5ba2f..1881d5d2 100644
--- a/erpc_c/config/erpc_config.h
+++ b/erpc_c/config/erpc_config.h
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2016, Freescale Semiconductor, Inc.
  * Copyright 2016-2020 NXP
- * Copyright 2020 ACRIOS Systems s.r.o.
+ * Copyright 2020-2021 ACRIOS Systems s.r.o.
  * All rights reserved.
  *
  *
@@ -23,39 +23,77 @@
 
 //! @name Threading model options
 //@{
-#define ERPC_THREADS_NONE (0)     //!< No threads.
-#define ERPC_THREADS_PTHREADS (1) //!< POSIX pthreads.
-#define ERPC_THREADS_FREERTOS (2) //!< FreeRTOS.
-#define ERPC_THREADS_ZEPHYR (3)   //!< ZEPHYR.
-#define ERPC_THREADS_MBED (4)     //!< Mbed OS
-#define ERPC_THREADS_WIN32 (5)    //!< WIN32
-#define ERPC_THREADS_THREADX (6)    //!< THREADX
+#define ERPC_ALLOCATION_POLICY_DYNAMIC (0U) //!< Dynamic allocation policy
+#define ERPC_ALLOCATION_POLICY_STATIC (1U)  //!< Static allocation policy
 
-#define ERPC_NOEXCEPT_DISABLED (0) //!< Disabling noexcept feature.
-#define ERPC_NOEXCEPT_ENABLED (1)  //!<  Enabling noexcept feature.
+#define ERPC_THREADS_NONE (0U)     //!< No threads.
+#define ERPC_THREADS_PTHREADS (1U) //!< POSIX pthreads.
+#define ERPC_THREADS_FREERTOS (2U) //!< FreeRTOS.
+#define ERPC_THREADS_ZEPHYR (3U)   //!< ZEPHYR.
+#define ERPC_THREADS_MBED (4U)     //!< Mbed OS
+#define ERPC_THREADS_WIN32 (5U)    //!< WIN32
+#define ERPC_THREADS_THREADX (6U)  //!< THREADX
 
-#define ERPC_NESTED_CALLS_DISABLED (0) //!< No nested calls support.
-#define ERPC_NESTED_CALLS_ENABLED (1)  //!< Nested calls support.
+#define ERPC_NOEXCEPT_DISABLED (0U) //!< Disabling noexcept feature.
+#define ERPC_NOEXCEPT_ENABLED (1U)  //!<  Enabling noexcept feature.
 
-#define ERPC_NESTED_CALLS_DETECTION_DISABLED (0) //!< Nested calls detection disabled.
-#define ERPC_NESTED_CALLS_DETECTION_ENABLED (1)  //!< Nested calls detection enabled.
+#define ERPC_NESTED_CALLS_DISABLED (0U) //!< No nested calls support.
+#define ERPC_NESTED_CALLS_ENABLED (1U)  //!< Nested calls support.
 
-#define ERPC_MESSAGE_LOGGING_DISABLED (0) //!< Trace functions disabled.
-#define ERPC_MESSAGE_LOGGING_ENABLED (1)  //!< Trace functions enabled.
+#define ERPC_NESTED_CALLS_DETECTION_DISABLED (0U) //!< Nested calls detection disabled.
+#define ERPC_NESTED_CALLS_DETECTION_ENABLED (1U)  //!< Nested calls detection enabled.
 
-#define ERPC_TRANSPORT_MU_USE_MCMGR_DISABLED (0) //!< Do not use MCMGR for MU ISR management.
-#define ERPC_TRANSPORT_MU_USE_MCMGR_ENABLED (1)  //!< Use MCMGR for MU ISR management.
+#define ERPC_MESSAGE_LOGGING_DISABLED (0U) //!< Trace functions disabled.
+#define ERPC_MESSAGE_LOGGING_ENABLED (1U)  //!< Trace functions enabled.
 
-#define ERPC_PRE_POST_ACTION_DISABLED (0) //!< Pre post shim callbacks functions disabled.
-#define ERPC_PRE_POST_ACTION_ENABLED (1)  //!< Pre post shim callback functions enabled.
+#define ERPC_TRANSPORT_MU_USE_MCMGR_DISABLED (0U) //!< Do not use MCMGR for MU ISR management.
+#define ERPC_TRANSPORT_MU_USE_MCMGR_ENABLED (1U)  //!< Use MCMGR for MU ISR management.
 
-#define ERPC_PRE_POST_ACTION_DEFAULT_DISABLED (0) //!< Pre post shim default callbacks functions disabled.
-#define ERPC_PRE_POST_ACTION_DEFAULT_ENABLED (1)  //!< Pre post shim default callback functions enabled.
+#define ERPC_PRE_POST_ACTION_DISABLED (0U) //!< Pre post shim callbacks functions disabled.
+#define ERPC_PRE_POST_ACTION_ENABLED (1U)  //!< Pre post shim callback functions enabled.
+
+#define ERPC_PRE_POST_ACTION_DEFAULT_DISABLED (0U) //!< Pre post shim default callbacks functions disabled.
+#define ERPC_PRE_POST_ACTION_DEFAULT_ENABLED (1U)  //!< Pre post shim default callback functions enabled.
 //@}
 
 //! @name Configuration options
 //@{
 
+//! @def ERPC_ALLOCATION_POLICY
+//!
+//! @brief Choose which allocation policy should be used.
+//!
+//! Set ERPC_ALLOCATION_POLICY_DYNAMIC if dynamic allocations should be used.
+//! Set ERPC_ALLOCATION_POLICY_STATIC if static allocations should be used.
+//!
+//! Default value is ERPC_ALLOCATION_POLICY_DYNAMIC or in case of FreeRTOS it can be auto-detected if __has_include() is supported
+//! by compiler. Uncomment comment bellow to use static allocation policy.
+//! In case of static implementation user need consider another values to set (ERPC_CODEC_COUNT,
+//! ERPC_MESSAGE_LOGGERS_COUNT, ERPC_CLIENTS_THREADS_AMOUNT).
+// #define ERPC_ALLOCATION_POLICY (ERPC_ALLOCATION_POLICY_STATIC)
+
+//! @def ERPC_CODEC_COUNT
+//!
+//! @brief Set amount of codecs objects used simultaneously in case of ERPC_ALLOCATION_POLICY is set to
+//! ERPC_ALLOCATION_POLICY_STATIC. For example if client or server is used in one thread then 1. If both are used in one thread per
+//! each then 2, ... Default value 2.
+// #define ERPC_CODEC_COUNT (2U)
+
+//! @def ERPC_MESSAGE_LOGGERS_COUNT
+//!
+//! @brief Set amount of message loggers objects used simultaneously  in case of ERPC_ALLOCATION_POLICY is set to
+//! ERPC_ALLOCATION_POLICY_STATIC.
+//! For example if client or server is used in one thread then 1. If both are used in one thread per each then 2, ...
+//! For arbitrated client 1 is enough.
+//! Default value 0 (May not be used).
+// #define ERPC_MESSAGE_LOGGERS_COUNT (0U)
+
+//! @def ERPC_CLIENTS_THREADS_AMOUNT
+//!
+//! @brief Set amount of client threads objects used in case of ERPC_ALLOCATION_POLICY is set to ERPC_ALLOCATION_POLICY_STATIC.
+//! Default value 1 (Most of current cases).
+// #define ERPC_CLIENTS_THREADS_AMOUNT (1U)
+
 //! @def ERPC_THREADS
 //!
 //! @brief Select threading model.
diff --git a/erpc_c/infra/erpc_basic_codec.cpp b/erpc_c/infra/erpc_basic_codec.cpp
index b86db6e6..38c2c521 100644
--- a/erpc_c/infra/erpc_basic_codec.cpp
+++ b/erpc_c/infra/erpc_basic_codec.cpp
@@ -10,6 +10,11 @@
 
 #include "erpc_basic_codec.h"
 
+#include "erpc_manually_constructed.h"
+
+#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
+#include <new>
+#endif
 #include <cassert>
 
 using namespace erpc;
@@ -370,3 +375,15 @@ void BasicCodec::readCallback(funPtr callbacks1, funPtr *callback2)
     // callbacks = callback directly
     *callback2 = callbacks1;
 }
+
+ERPC_MANUALLY_CONSTRUCTED_ARRAY_STATIC(BasicCodec, s_basicCodecManual, ERPC_CODEC_COUNT);
+
+Codec *BasicCodecFactory ::create()
+{
+    ERPC_CREATE_NEW_OBJECT(BasicCodec, s_basicCodecManual, ERPC_CODEC_COUNT)
+}
+
+void BasicCodecFactory ::dispose(Codec *codec)
+{
+    ERPC_DESTROY_OBJECT(codec, s_basicCodecManual, ERPC_CODEC_COUNT)
+}
diff --git a/erpc_c/infra/erpc_basic_codec.h b/erpc_c/infra/erpc_basic_codec.h
index d3f6ef78..8fb44d0d 100644
--- a/erpc_c/infra/erpc_basic_codec.h
+++ b/erpc_c/infra/erpc_basic_codec.h
@@ -13,8 +13,6 @@
 
 #include "erpc_codec.h"
 
-#include <new>
-
 /*!
  * @addtogroup infra_codec
  * @{
@@ -385,14 +383,14 @@ class BasicCodecFactory : public CodecFactory
      *
      * @return Pointer to created codec.
      */
-    virtual Codec *create(void) override { return new (std::nothrow) BasicCodec; }
+    virtual Codec *create(void) override;
 
     /*!
      * @brief Dispose codec.
      *
      * @param[in] codec Codec to dispose.
      */
-    virtual void dispose(Codec *codec) override { delete codec; }
+    virtual void dispose(Codec *codec) override;
 };
 
 } // namespace erpc
diff --git a/erpc_c/infra/erpc_manually_constructed.h b/erpc_c/infra/erpc_manually_constructed.h
index 4ae27658..3021cec0 100644
--- a/erpc_c/infra/erpc_manually_constructed.h
+++ b/erpc_c/infra/erpc_manually_constructed.h
@@ -10,6 +10,9 @@
 
 #ifndef _EMBEDDED_RPC__MANUALLY_CONSTRUCTED_H_
 #define _EMBEDDED_RPC__MANUALLY_CONSTRUCTED_H_
+
+#include "erpc_config_internal.h"
+
 #include <new>
 #include <stdint.h>
 
@@ -154,6 +157,14 @@ class ManuallyConstructed
         }
     }
 
+    /*!
+     * @brief Returns information if object is free or is used.
+     *
+     * @return true Object is constructed and used.
+     * @return false Object wasn't constructer or it is destructed and free.
+     */
+    bool isUsed() { return m_isConstructed; }
+
 protected:
     /*!
      * @brief Storage for the object.
@@ -170,6 +181,56 @@ class ManuallyConstructed
     bool m_isConstructed = false;
 };
 
+#define ERPC_MANUALLY_CONSTRUCTED(class, variableName) static ManuallyConstructed<class> variableName
+#define ERPC_MANUALLY_CONSTRUCTED_ARRAY(class, variableName, dimension) \
+    ERPC_MANUALLY_CONSTRUCTED(class, variableName)[dimension]
+
+#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_STATIC
+#define ERPC_MANUALLY_CONSTRUCTED_STATIC(class, variableName) ERPC_MANUALLY_CONSTRUCTED(class, variableName)
+#else
+#define ERPC_MANUALLY_CONSTRUCTED_STATIC(class, variableName)
+#endif
+
+#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_STATIC
+#define ERPC_MANUALLY_CONSTRUCTED_ARRAY_STATIC(class, variableName, dimension) \
+    ERPC_MANUALLY_CONSTRUCTED_ARRAY(class, variableName, dimension)
+#else
+#define ERPC_MANUALLY_CONSTRUCTED_ARRAY_STATIC(class, variableName, dimension)
+#endif
+
+#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
+#define ERPC_CREATE_NEW_OBJECT(class, arrayOfObjects, numberOfObjects, ...) \
+    return new (std::nothrow) class(__VA_ARGS__);
+
+#define ERPC_DESTROY_OBJECT(object, ...) delete object;
+
+#elif ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_STATIC
+#define ERPC_CREATE_NEW_OBJECT(class, arrayOfObjects, numberOfObjects, ...)         \
+    uint8_t objectsIterator;                                                        \
+    class *ret = NULL;                                                              \
+    for (objectsIterator = 0; objectsIterator < numberOfObjects; objectsIterator++) \
+    {                                                                               \
+        if (!arrayOfObjects[objectsIterator].isUsed())                              \
+        {                                                                           \
+            arrayOfObjects[objectsIterator].construct(__VA_ARGS__);                 \
+            ret = arrayOfObjects[objectsIterator].get();                            \
+            break;                                                                  \
+        }                                                                           \
+    }                                                                               \
+    return ret;
+
+#define ERPC_DESTROY_OBJECT(object, arrayOfObjects, numberOfObjects)                \
+    uint8_t objectsIterator;                                                        \
+    for (objectsIterator = 0; objectsIterator < numberOfObjects; objectsIterator++) \
+    {                                                                               \
+        if (object == arrayOfObjects[objectsIterator].get())                        \
+        {                                                                           \
+            arrayOfObjects[objectsIterator].destroy();                              \
+            break;                                                                  \
+        }                                                                           \
+    }
+#endif
+
 } // namespace erpc
 
 /*! @} */
diff --git a/erpc_c/infra/erpc_message_loggers.cpp b/erpc_c/infra/erpc_message_loggers.cpp
index e1aab613..0225c1fd 100644
--- a/erpc_c/infra/erpc_message_loggers.cpp
+++ b/erpc_c/infra/erpc_message_loggers.cpp
@@ -11,7 +11,11 @@
 
 #include "erpc_message_loggers.h"
 
+#include "erpc_manually_constructed.h"
+
+#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
 #include <new>
+#endif
 
 using namespace erpc;
 using namespace std;
@@ -20,6 +24,8 @@ using namespace std;
 // Code
 ////////////////////////////////////////////////////////////////////////////////
 
+ERPC_MANUALLY_CONSTRUCTED_ARRAY_STATIC(MessageLogger, s_messageLoggersManual, ERPC_MESSAGE_LOGGERS_COUNT);
+
 MessageLoggers::~MessageLoggers(void)
 {
     MessageLogger *logger;
@@ -28,7 +34,7 @@ MessageLoggers::~MessageLoggers(void)
     {
         logger = m_logger;
         m_logger = m_logger->getNext();
-        delete logger;
+        ERPC_DESTROY_OBJECT(logger, s_messageLoggersManual, ERPC_MESSAGE_LOGGERS_COUNT)
     }
 }
 
@@ -40,7 +46,7 @@ bool MessageLoggers::addMessageLogger(Transport *transport)
 
     if (transport != NULL)
     {
-        logger = new (nothrow) MessageLogger(transport);
+        logger = create(transport);
         if (logger != NULL)
         {
             if (m_logger == NULL)
@@ -84,4 +90,10 @@ erpc_status_t MessageLoggers::logMessage(MessageBuffer *msg)
 
     return err;
 }
+
+MessageLogger *MessageLoggers::create(Transport *transport)
+{
+    ERPC_CREATE_NEW_OBJECT(MessageLogger, s_messageLoggersManual, ERPC_MESSAGE_LOGGERS_COUNT, transport)
+}
+
 #endif /* ERPC_MESSAGE_LOGGING */
diff --git a/erpc_c/infra/erpc_message_loggers.h b/erpc_c/infra/erpc_message_loggers.h
index 1e3a396a..a37c7a62 100644
--- a/erpc_c/infra/erpc_message_loggers.h
+++ b/erpc_c/infra/erpc_message_loggers.h
@@ -109,6 +109,16 @@ class MessageLoggers
      * @return The eRPC status based on transport type.
      */
     erpc_status_t logMessage(MessageBuffer *msg);
+
+private:
+    /**
+     * @brief This function create new MessageLogger object
+     *
+     * @param[in] transport Transport used by MessageLogger.
+     *
+     * @return MessageLogger* Returns new MessageLogger object.
+     */
+    MessageLogger *create(Transport *transport);
 };
 
 } // namespace erpc
diff --git a/erpc_c/infra/erpc_transport_arbitrator.cpp b/erpc_c/infra/erpc_transport_arbitrator.cpp
index 8af996af..23f096cf 100644
--- a/erpc_c/infra/erpc_transport_arbitrator.cpp
+++ b/erpc_c/infra/erpc_transport_arbitrator.cpp
@@ -9,7 +9,7 @@
  */
 #include "erpc_transport_arbitrator.h"
 
-#include "erpc_config_internal.h"
+#include "erpc_manually_constructed.h"
 
 #include <cassert>
 #include <cstdio>
@@ -25,6 +25,9 @@ using namespace erpc;
 // Code
 ////////////////////////////////////////////////////////////////////////////////
 
+ERPC_MANUALLY_CONSTRUCTED_ARRAY_STATIC(TransportArbitrator::PendingClientInfo, s_pendingClientInfoArray,
+                                       ERPC_CLIENTS_THREADS_AMOUNT);
+
 TransportArbitrator::TransportArbitrator(void)
 : Transport()
 , m_sharedTransport(NULL)
@@ -169,6 +172,9 @@ erpc_status_t TransportArbitrator::clientReceive(client_token_t token)
     return kErpcStatus_Success;
 }
 
+TransportArbitrator::PendingClientInfo *TransportArbitrator::createPendingClient(void){ ERPC_CREATE_NEW_OBJECT(
+    TransportArbitrator::PendingClientInfo, s_pendingClientInfoArray, ERPC_CLIENTS_THREADS_AMOUNT) }
+
 TransportArbitrator::PendingClientInfo *TransportArbitrator::addPendingClient(void)
 {
     Mutex::Guard lock(m_clientListMutex);
@@ -177,7 +183,7 @@ TransportArbitrator::PendingClientInfo *TransportArbitrator::addPendingClient(vo
     PendingClientInfo *info = NULL;
     if (!m_clientFreeList)
     {
-        info = new PendingClientInfo();
+        info = createPendingClient();
     }
     else
     {
@@ -241,7 +247,7 @@ void TransportArbitrator::freeClientList(PendingClientInfo *list)
     {
         temp = info;
         info = info->m_next;
-        delete temp;
+        ERPC_DESTROY_OBJECT(temp, s_pendingClientInfoArray, ERPC_CLIENTS_THREADS_AMOUNT)
     }
 }
 
diff --git a/erpc_c/infra/erpc_transport_arbitrator.h b/erpc_c/infra/erpc_transport_arbitrator.h
index 99b88ee6..da347c3b 100644
--- a/erpc_c/infra/erpc_transport_arbitrator.h
+++ b/erpc_c/infra/erpc_transport_arbitrator.h
@@ -129,10 +129,6 @@ class TransportArbitrator : public Transport
      */
     virtual bool hasMessage(void) override;
 
-protected:
-    Transport *m_sharedTransport; //!< Transport being shared through this arbitrator.
-    Codec *m_codec;               //!< Codec used to read incoming message headers.
-
     /*!
      * @brief Request info for a client trying to receive a response.
      */
@@ -154,10 +150,21 @@ class TransportArbitrator : public Transport
         ~PendingClientInfo(void);
     };
 
+protected:
+    Transport *m_sharedTransport; //!< Transport being shared through this arbitrator.
+    Codec *m_codec;               //!< Codec used to read incoming message headers.
+
     PendingClientInfo *m_clientList;     //!< Active client receive requests.
     PendingClientInfo *m_clientFreeList; //!< Unused client receive info structs.
     Mutex m_clientListMutex;             //!< Mutex guarding the client active and free lists.
 
+    /*!
+     * @brief Create a Pending Client object.
+     *
+     * @return PendingClientInfo* Return created object.
+     */
+    PendingClientInfo *createPendingClient(void);
+
     /*!
      * @brief This function adds pending client.
      *
diff --git a/erpc_c/port/erpc_config_internal.h b/erpc_c/port/erpc_config_internal.h
index 3263c980..1f67fe3e 100644
--- a/erpc_c/port/erpc_config_internal.h
+++ b/erpc_c/port/erpc_config_internal.h
@@ -47,6 +47,41 @@
     #endif
 #endif
 
+// Detect allocation policy if not already set.
+#if !defined(ERPC_ALLOCATION_POLICY)
+    #if defined(__has_include) && __has_include("FreeRTOSConfig.h")
+        #ifdef __cplusplus
+        extern "C" {
+        #endif
+        #include "FreeRTOSConfig.h"
+        #ifdef __cplusplus
+        }
+        #endif
+        #if defined(configSUPPORT_STATIC_ALLOCATION) && configSUPPORT_STATIC_ALLOCATION
+            #define ERPC_ALLOCATION_POLICY (ERPC_ALLOCATION_POLICY_STATIC)
+        #else
+            #define ERPC_ALLOCATION_POLICY (ERPC_ALLOCATION_POLICY_DYNAMIC)
+        #endif
+    #else
+        #define ERPC_ALLOCATION_POLICY (ERPC_ALLOCATION_POLICY_DYNAMIC)
+    #endif
+#endif
+
+#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_STATIC
+#if !defined(ERPC_CODEC_COUNT)
+#define ERPC_CODEC_COUNT (2U)
+#warning "ERPC_CODEC_COUNT is not defined. Default is used."
+#endif
+#if !defined(ERPC_MESSAGE_LOGGERS_COUNT)
+#define ERPC_MESSAGE_LOGGERS_COUNT (0U)
+#warning "ERPC_MESSAGE_LOGGERS_COUNT is not defined. Default is used."
+#endif
+#if !defined(ERPC_CLIENTS_THREADS_AMOUNT)
+#define ERPC_CLIENTS_THREADS_AMOUNT (1U)
+#warning "ERPC_CLIENTS_THREADS_AMOUNT is not defined. Default is used."
+#endif
+#endif
+
 // Safely detect tx_api.h.
 #define ERPC_HAS_THREADX_API_H (0)
 #if defined(__has_include)
diff --git a/erpc_c/port/erpc_setup_extensions_freertos.cpp b/erpc_c/port/erpc_setup_extensions_freertos.cpp
index 9d45126b..0ac87d4f 100644
--- a/erpc_c/port/erpc_setup_extensions_freertos.cpp
+++ b/erpc_c/port/erpc_setup_extensions_freertos.cpp
@@ -7,6 +7,7 @@
  * SPDX-License-Identifier: BSD-3-Clause
  */
 
+#include "erpc_manually_constructed.h"
 #include "erpc_setup_extensions.h"
 #include "erpc_threading.h"
 
@@ -16,6 +17,11 @@ using namespace erpc;
 
 static Semaphore *s_erpc_call_in_progress = NULL;
 static TimerHandle_t s_erpc_call_timer_cb = NULL;
+#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_STATIC
+static StaticTimer_t s_static_erpc_call_timer_cb;
+#endif
+
+ERPC_MANUALLY_CONSTRUCTED_STATIC(Semaphore, s_semaphore);
 
 void erpc::erpc_pre_cb_default(void)
 {
@@ -43,11 +49,22 @@ void erpc_init_call_progress_detection_default(
     erpc_call_timer_cb_default_t erpc_call_timer_cb = erpc_call_timer_cb_default,
     uint32_t waitTimeMs = (5U * 60U * 1000U))
 {
-    s_erpc_call_in_progress = new Semaphore(1);
+    const uint32_t semaphoreCount = 1;
+#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
+    s_erpc_call_in_progress = new Semaphore(semaphoreCount);
+#elif ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_STATIC
+    s_semaphore.construct(semaphoreCount);
+    s_erpc_call_in_progress = s_semaphore.get();
+#endif
     assert(s_erpc_call_in_progress && "Creating eRPC semaphore failed.");
 
+#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_STATIC
+    s_erpc_call_timer_cb = xTimerCreateStatic("Erpc client call timer", waitTimeMs / portTICK_PERIOD_MS, pdFALSE, NULL,
+                                              erpc_call_timer_cb, &s_static_erpc_call_timer_cb);
+#else
     s_erpc_call_timer_cb =
         xTimerCreate("Erpc client call timer", waitTimeMs / portTICK_PERIOD_MS, pdFALSE, NULL, erpc_call_timer_cb);
+#endif
     assert(s_erpc_call_timer_cb && "Creating eRPC timer failed.");
 }
 
@@ -55,7 +72,9 @@ void erpc_deinit_call_progress_detection_default(void)
 {
     if (s_erpc_call_in_progress != NULL)
     {
+#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
         delete s_erpc_call_in_progress;
+#endif
         s_erpc_call_in_progress = NULL;
     }
 
diff --git a/erpc_c/setup/erpc_arbitrated_client_setup.cpp b/erpc_c/setup/erpc_arbitrated_client_setup.cpp
index 719fb055..6df4a830 100644
--- a/erpc_c/setup/erpc_arbitrated_client_setup.cpp
+++ b/erpc_c/setup/erpc_arbitrated_client_setup.cpp
@@ -31,14 +31,14 @@ using namespace erpc;
 ////////////////////////////////////////////////////////////////////////////////
 
 // global client variables
-static ManuallyConstructed<ArbitratedClientManager> s_client;
+ERPC_MANUALLY_CONSTRUCTED(ArbitratedClientManager, s_client);
 ClientManager *g_client;
 #pragma weak g_client
 
-static ManuallyConstructed<BasicCodecFactory> s_codecFactory;
-static ManuallyConstructed<TransportArbitrator> s_arbitrator;
-static ManuallyConstructed<BasicCodec> s_codec;
-static ManuallyConstructed<Crc16> s_crc16;
+ERPC_MANUALLY_CONSTRUCTED(BasicCodecFactory, s_codecFactory);
+ERPC_MANUALLY_CONSTRUCTED(TransportArbitrator, s_arbitrator);
+ERPC_MANUALLY_CONSTRUCTED(BasicCodec, s_codec);
+ERPC_MANUALLY_CONSTRUCTED(Crc16, s_crc16);
 
 ////////////////////////////////////////////////////////////////////////////////
 // Code
diff --git a/erpc_c/setup/erpc_client_setup.cpp b/erpc_c/setup/erpc_client_setup.cpp
index 6c45b64d..e653bf4f 100644
--- a/erpc_c/setup/erpc_client_setup.cpp
+++ b/erpc_c/setup/erpc_client_setup.cpp
@@ -29,11 +29,11 @@ using namespace erpc;
 ////////////////////////////////////////////////////////////////////////////////
 
 // global client variables
-static ManuallyConstructed<ClientManager> s_client;
+ERPC_MANUALLY_CONSTRUCTED(ClientManager, s_client);
 ClientManager *g_client;
 #pragma weak g_client
-static ManuallyConstructed<BasicCodecFactory> s_codecFactory;
-static ManuallyConstructed<Crc16> s_crc16;
+ERPC_MANUALLY_CONSTRUCTED(BasicCodecFactory, s_codecFactory);
+ERPC_MANUALLY_CONSTRUCTED(Crc16, s_crc16);
 
 ////////////////////////////////////////////////////////////////////////////////
 // Code
diff --git a/erpc_c/setup/erpc_server_setup.cpp b/erpc_c/setup/erpc_server_setup.cpp
index 6376e434..3288a1f7 100644
--- a/erpc_c/setup/erpc_server_setup.cpp
+++ b/erpc_c/setup/erpc_server_setup.cpp
@@ -26,11 +26,11 @@ using namespace erpc;
 ////////////////////////////////////////////////////////////////////////////////
 
 // global server variables
-static ManuallyConstructed<SimpleServer> s_server;
+ERPC_MANUALLY_CONSTRUCTED(SimpleServer, s_server);
 extern SimpleServer *g_server;
 SimpleServer *g_server = NULL;
-static ManuallyConstructed<BasicCodecFactory> s_codecFactory;
-static ManuallyConstructed<Crc16> s_crc16;
+ERPC_MANUALLY_CONSTRUCTED(BasicCodecFactory, s_codecFactory);
+ERPC_MANUALLY_CONSTRUCTED(Crc16, s_crc16);
 
 ////////////////////////////////////////////////////////////////////////////////
 // Code
diff --git a/erpc_c/setup/erpc_setup_dspi_master.cpp b/erpc_c/setup/erpc_setup_dspi_master.cpp
index 60dc6923..e9717b8a 100644
--- a/erpc_c/setup/erpc_setup_dspi_master.cpp
+++ b/erpc_c/setup/erpc_setup_dspi_master.cpp
@@ -17,7 +17,7 @@ using namespace erpc;
 // Variables
 ////////////////////////////////////////////////////////////////////////////////
 
-static ManuallyConstructed<DspiMasterTransport> s_transport;
+ERPC_MANUALLY_CONSTRUCTED(DspiMasterTransport, s_transport);
 
 ////////////////////////////////////////////////////////////////////////////////
 // Code
diff --git a/erpc_c/setup/erpc_setup_dspi_slave.cpp b/erpc_c/setup/erpc_setup_dspi_slave.cpp
index 5595fdf0..961161cb 100644
--- a/erpc_c/setup/erpc_setup_dspi_slave.cpp
+++ b/erpc_c/setup/erpc_setup_dspi_slave.cpp
@@ -17,7 +17,7 @@ using namespace erpc;
 // Variables
 ////////////////////////////////////////////////////////////////////////////////
 
-static ManuallyConstructed<DspiSlaveTransport> s_transport;
+ERPC_MANUALLY_CONSTRUCTED(DspiSlaveTransport, s_transport);
 
 ////////////////////////////////////////////////////////////////////////////////
 // Code
diff --git a/erpc_c/setup/erpc_setup_mbf_dynamic.cpp b/erpc_c/setup/erpc_setup_mbf_dynamic.cpp
index 1eca39d2..e0e0ab69 100644
--- a/erpc_c/setup/erpc_setup_mbf_dynamic.cpp
+++ b/erpc_c/setup/erpc_setup_mbf_dynamic.cpp
@@ -48,7 +48,7 @@ class DynamicMessageBufferFactory : public MessageBufferFactory
 // Variables
 ////////////////////////////////////////////////////////////////////////////////
 
-static ManuallyConstructed<DynamicMessageBufferFactory> s_msgFactory;
+ERPC_MANUALLY_CONSTRUCTED(DynamicMessageBufferFactory, s_msgFactory);
 
 erpc_mbf_t erpc_mbf_dynamic_init(void)
 {
diff --git a/erpc_c/setup/erpc_setup_mbf_rpmsg.cpp b/erpc_c/setup/erpc_setup_mbf_rpmsg.cpp
index 30a53601..de769061 100644
--- a/erpc_c/setup/erpc_setup_mbf_rpmsg.cpp
+++ b/erpc_c/setup/erpc_setup_mbf_rpmsg.cpp
@@ -105,7 +105,7 @@ class RPMsgMessageBufferFactory : public MessageBufferFactory
 // Variables
 ////////////////////////////////////////////////////////////////////////////////
 
-static ManuallyConstructed<RPMsgMessageBufferFactory> s_msgFactory;
+ERPC_MANUALLY_CONSTRUCTED(RPMsgMessageBufferFactory, s_msgFactory);
 
 erpc_mbf_t erpc_mbf_rpmsg_init(erpc_transport_t transport)
 {
diff --git a/erpc_c/setup/erpc_setup_mbf_rpmsg_tty.cpp b/erpc_c/setup/erpc_setup_mbf_rpmsg_tty.cpp
index 715ff466..25daebb5 100644
--- a/erpc_c/setup/erpc_setup_mbf_rpmsg_tty.cpp
+++ b/erpc_c/setup/erpc_setup_mbf_rpmsg_tty.cpp
@@ -109,7 +109,7 @@ class RPMsgTTYMessageBufferFactory : public MessageBufferFactory
 // Variables
 ////////////////////////////////////////////////////////////////////////////////
 
-static ManuallyConstructed<RPMsgTTYMessageBufferFactory> s_msgFactory;
+ERPC_MANUALLY_CONSTRUCTED(RPMsgTTYMessageBufferFactory, s_msgFactory);
 
 erpc_mbf_t erpc_mbf_rpmsg_tty_init(erpc_transport_t transport)
 {
diff --git a/erpc_c/setup/erpc_setup_mbf_static.cpp b/erpc_c/setup/erpc_setup_mbf_static.cpp
index 0362a831..bc6fd378 100644
--- a/erpc_c/setup/erpc_setup_mbf_static.cpp
+++ b/erpc_c/setup/erpc_setup_mbf_static.cpp
@@ -127,7 +127,7 @@ class StaticMessageBufferFactory : public MessageBufferFactory
 // Variables
 ////////////////////////////////////////////////////////////////////////////////
 
-static ManuallyConstructed<StaticMessageBufferFactory> s_msgFactory;
+ERPC_MANUALLY_CONSTRUCTED(StaticMessageBufferFactory, s_msgFactory);
 
 erpc_mbf_t erpc_mbf_static_init(void)
 {
diff --git a/erpc_c/setup/erpc_setup_mu.cpp b/erpc_c/setup/erpc_setup_mu.cpp
index f2f66141..f69b08bc 100644
--- a/erpc_c/setup/erpc_setup_mu.cpp
+++ b/erpc_c/setup/erpc_setup_mu.cpp
@@ -16,7 +16,7 @@ using namespace erpc;
 // Variables
 ////////////////////////////////////////////////////////////////////////////////
 
-static ManuallyConstructed<MUTransport> s_transport;
+ERPC_MANUALLY_CONSTRUCTED(MUTransport, s_transport);
 
 ////////////////////////////////////////////////////////////////////////////////
 // Code
diff --git a/erpc_c/setup/erpc_setup_rpmsg_linux.cpp b/erpc_c/setup/erpc_setup_rpmsg_linux.cpp
index 5000c22f..ecde3870 100644
--- a/erpc_c/setup/erpc_setup_rpmsg_linux.cpp
+++ b/erpc_c/setup/erpc_setup_rpmsg_linux.cpp
@@ -13,8 +13,8 @@
 
 using namespace erpc;
 
-static ManuallyConstructed<RPMsgLinuxTransport> s_transport;
-static ManuallyConstructed<RPMsgEndpoint> s_endpoint;
+ERPC_MANUALLY_CONSTRUCTED(RPMsgLinuxTransport, s_transport);
+ERPC_MANUALLY_CONSTRUCTED(RPMsgEndpoint, s_endpoint);
 
 erpc_transport_t erpc_transport_rpmsg_linux_init(int16_t local_addr, int8_t type, int16_t remote_addr)
 {
diff --git a/erpc_c/setup/erpc_setup_rpmsg_lite_master.cpp b/erpc_c/setup/erpc_setup_rpmsg_lite_master.cpp
index 5e8c9873..0f9241e1 100644
--- a/erpc_c/setup/erpc_setup_rpmsg_lite_master.cpp
+++ b/erpc_c/setup/erpc_setup_rpmsg_lite_master.cpp
@@ -33,7 +33,7 @@ char rpmsg_lite_base[SH_MEM_TOTAL_SIZE] __attribute__((section(".noinit.$rpmsg_s
 #error "RPMsg: Please provide your definition of rpmsg_lite_base[]!"
 #endif
 
-static ManuallyConstructed<RPMsgTransport> s_transport;
+ERPC_MANUALLY_CONSTRUCTED(RPMsgTransport, s_transport);
 
 ////////////////////////////////////////////////////////////////////////////////
 // Code
diff --git a/erpc_c/setup/erpc_setup_rpmsg_lite_remote.cpp b/erpc_c/setup/erpc_setup_rpmsg_lite_remote.cpp
index d788ff06..8b451ecf 100644
--- a/erpc_c/setup/erpc_setup_rpmsg_lite_remote.cpp
+++ b/erpc_c/setup/erpc_setup_rpmsg_lite_remote.cpp
@@ -18,7 +18,7 @@ using namespace erpc;
 // Variables
 ////////////////////////////////////////////////////////////////////////////////
 
-static ManuallyConstructed<RPMsgTransport> s_transport;
+ERPC_MANUALLY_CONSTRUCTED(RPMsgTransport, s_transport);
 
 ////////////////////////////////////////////////////////////////////////////////
 // Code
diff --git a/erpc_c/setup/erpc_setup_rpmsg_lite_rtos_master.cpp b/erpc_c/setup/erpc_setup_rpmsg_lite_rtos_master.cpp
index 7313ca59..65565519 100644
--- a/erpc_c/setup/erpc_setup_rpmsg_lite_rtos_master.cpp
+++ b/erpc_c/setup/erpc_setup_rpmsg_lite_rtos_master.cpp
@@ -32,7 +32,7 @@ char rpmsg_lite_base[SH_MEM_TOTAL_SIZE] __attribute__((section(".noinit.$rpmsg_s
 #error "RPMsg: Please provide your definition of rpmsg_lite_base[]!"
 #endif
 
-static ManuallyConstructed<RPMsgRTOSTransport> s_transport;
+ERPC_MANUALLY_CONSTRUCTED(RPMsgRTOSTransport, s_transport);
 
 ////////////////////////////////////////////////////////////////////////////////
 // Code
diff --git a/erpc_c/setup/erpc_setup_rpmsg_lite_rtos_remote.cpp b/erpc_c/setup/erpc_setup_rpmsg_lite_rtos_remote.cpp
index d38499ed..0a34c13b 100644
--- a/erpc_c/setup/erpc_setup_rpmsg_lite_rtos_remote.cpp
+++ b/erpc_c/setup/erpc_setup_rpmsg_lite_rtos_remote.cpp
@@ -18,7 +18,7 @@ using namespace erpc;
 // Variables
 ////////////////////////////////////////////////////////////////////////////////
 
-static ManuallyConstructed<RPMsgRTOSTransport> s_transport;
+ERPC_MANUALLY_CONSTRUCTED(RPMsgRTOSTransport, s_transport);
 
 ////////////////////////////////////////////////////////////////////////////////
 // Code
diff --git a/erpc_c/setup/erpc_setup_rpmsg_tty_rtos_remote.cpp b/erpc_c/setup/erpc_setup_rpmsg_tty_rtos_remote.cpp
index c48a38d6..51cb4de5 100644
--- a/erpc_c/setup/erpc_setup_rpmsg_tty_rtos_remote.cpp
+++ b/erpc_c/setup/erpc_setup_rpmsg_tty_rtos_remote.cpp
@@ -18,7 +18,7 @@ using namespace erpc;
 // Variables
 ////////////////////////////////////////////////////////////////////////////////
 
-static ManuallyConstructed<RPMsgTTYRTOSTransport> s_transport;
+ERPC_MANUALLY_CONSTRUCTED(RPMsgTTYRTOSTransport, s_transport);
 
 ////////////////////////////////////////////////////////////////////////////////
 // Code
diff --git a/erpc_c/setup/erpc_setup_serial.cpp b/erpc_c/setup/erpc_setup_serial.cpp
index 306439ca..4098004c 100644
--- a/erpc_c/setup/erpc_setup_serial.cpp
+++ b/erpc_c/setup/erpc_setup_serial.cpp
@@ -18,7 +18,7 @@ using namespace erpc;
 // Variables
 ////////////////////////////////////////////////////////////////////////////////
 
-static ManuallyConstructed<SerialTransport> s_transport;
+ERPC_MANUALLY_CONSTRUCTED(SerialTransport, s_transport);
 
 ////////////////////////////////////////////////////////////////////////////////
 // Code
diff --git a/erpc_c/setup/erpc_setup_spi_master.cpp b/erpc_c/setup/erpc_setup_spi_master.cpp
index 9d4d07b6..64be4e83 100644
--- a/erpc_c/setup/erpc_setup_spi_master.cpp
+++ b/erpc_c/setup/erpc_setup_spi_master.cpp
@@ -17,7 +17,7 @@ using namespace erpc;
 // Variables
 ////////////////////////////////////////////////////////////////////////////////
 
-static ManuallyConstructed<SpiMasterTransport> s_transport;
+ERPC_MANUALLY_CONSTRUCTED(SpiMasterTransport, s_transport);
 
 ////////////////////////////////////////////////////////////////////////////////
 // Code
diff --git a/erpc_c/setup/erpc_setup_spi_slave.cpp b/erpc_c/setup/erpc_setup_spi_slave.cpp
index 2ef7c924..11265451 100644
--- a/erpc_c/setup/erpc_setup_spi_slave.cpp
+++ b/erpc_c/setup/erpc_setup_spi_slave.cpp
@@ -17,7 +17,7 @@ using namespace erpc;
 // Variables
 ////////////////////////////////////////////////////////////////////////////////
 
-static ManuallyConstructed<SpiSlaveTransport> s_transport;
+ERPC_MANUALLY_CONSTRUCTED(SpiSlaveTransport, s_transport);
 
 ////////////////////////////////////////////////////////////////////////////////
 // Code
diff --git a/erpc_c/setup/erpc_setup_spidev_master.cpp b/erpc_c/setup/erpc_setup_spidev_master.cpp
index 2c705411..bd6b6afc 100644
--- a/erpc_c/setup/erpc_setup_spidev_master.cpp
+++ b/erpc_c/setup/erpc_setup_spidev_master.cpp
@@ -16,7 +16,7 @@ using namespace erpc;
 // Variables
 ////////////////////////////////////////////////////////////////////////////////
 
-static ManuallyConstructed<SpidevMasterTransport> s_transport;
+ERPC_MANUALLY_CONSTRUCTED(SpidevMasterTransport, s_transport);
 
 ////////////////////////////////////////////////////////////////////////////////
 // Code
diff --git a/erpc_c/setup/erpc_setup_tcp.cpp b/erpc_c/setup/erpc_setup_tcp.cpp
index 3b45acc8..b0ea1915 100644
--- a/erpc_c/setup/erpc_setup_tcp.cpp
+++ b/erpc_c/setup/erpc_setup_tcp.cpp
@@ -17,7 +17,7 @@ using namespace erpc;
 // Variables
 ////////////////////////////////////////////////////////////////////////////////
 
-static ManuallyConstructed<TCPTransport> s_transport;
+ERPC_MANUALLY_CONSTRUCTED(TCPTransport, s_transport);
 
 ////////////////////////////////////////////////////////////////////////////////
 // Code
diff --git a/erpc_c/setup/erpc_setup_uart_cmsis.cpp b/erpc_c/setup/erpc_setup_uart_cmsis.cpp
index 00d8152f..5b34e290 100644
--- a/erpc_c/setup/erpc_setup_uart_cmsis.cpp
+++ b/erpc_c/setup/erpc_setup_uart_cmsis.cpp
@@ -18,7 +18,7 @@ using namespace erpc;
 // Variables
 ////////////////////////////////////////////////////////////////////////////////
 
-static ManuallyConstructed<UartTransport> s_transport;
+ERPC_MANUALLY_CONSTRUCTED(UartTransport, s_transport);
 
 ////////////////////////////////////////////////////////////////////////////////
 // Code
diff --git a/erpc_c/setup/erpc_setup_usb_cdc.cpp b/erpc_c/setup/erpc_setup_usb_cdc.cpp
index f3ad2d5d..494220c1 100644
--- a/erpc_c/setup/erpc_setup_usb_cdc.cpp
+++ b/erpc_c/setup/erpc_setup_usb_cdc.cpp
@@ -17,7 +17,7 @@ using namespace erpc;
 // Variables
 ////////////////////////////////////////////////////////////////////////////////
 
-static ManuallyConstructed<UsbCdcTransport> s_usb_transport;
+ERPC_MANUALLY_CONSTRUCTED(ClientManager, s_client);
 
 ////////////////////////////////////////////////////////////////////////////////
 // Code
diff --git a/erpcgen/src/Generator.cpp b/erpcgen/src/Generator.cpp
index 8a278858..cfd4c538 100644
--- a/erpcgen/src/Generator.cpp
+++ b/erpcgen/src/Generator.cpp
@@ -44,7 +44,6 @@ Generator::Generator(InterfaceDefinition *def, generator_type_t generatorType)
 
     m_templateData["sharedMemBeginAddr"] = "";
     m_templateData["sharedMemEndAddr"] = "";
-    m_templateData["dynamicServices"] = false;
 
     m_outputDirectory = m_def->getOutputDirectory();
 
@@ -76,11 +75,6 @@ Generator::Generator(InterfaceDefinition *def, generator_type_t generatorType)
             m_templateData["crc16"] = m_idlCrc16;
         }
 
-        if (findAnnotation(program, DYNAMIC_SERVICES_ANNOTATION) != nullptr)
-        {
-            m_templateData["dynamicServices"] = true;
-        }
-
         m_outputDirectory /= getAnnStringValue(m_def->getProgramSymbol(), OUTPUT_DIR_ANNOTATION);
     }
 
diff --git a/erpcgen/src/annotations.h b/erpcgen/src/annotations.h
index f51d036b..148d15f6 100644
--- a/erpcgen/src/annotations.h
+++ b/erpcgen/src/annotations.h
@@ -16,9 +16,6 @@
 //! Define union discriminator name for non-encapsulated unions.
 #define DISCRIMINATOR_ANNOTATION "discriminator"
 
-//! Service objects will be dynamically allocated.
-#define DYNAMIC_SERVICES_ANNOTATION "dynamic_services"
-
 //! Set error value for provide error to client
 #define ERROR_RETURN_ANNOTATION "error_return"
 
diff --git a/erpcgen/src/templates/c_client_source.template b/erpcgen/src/templates/c_client_source.template
index 4719f055..b1aabb99 100644
--- a/erpcgen/src/templates/c_client_source.template
+++ b/erpcgen/src/templates/c_client_source.template
@@ -5,7 +5,9 @@
 {$commonHeader()}
 
 #include "erpc_client_manager.h"
+#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
 #include "erpc_port.h"
+#endif
 #include "{$codecHeader}"
 extern "C"
 {
diff --git a/erpcgen/src/templates/c_server_header.template b/erpcgen/src/templates/c_server_header.template
index 52e2aba2..68ed101d 100644
--- a/erpcgen/src/templates/c_server_header.template
+++ b/erpcgen/src/templates/c_server_header.template
@@ -50,11 +50,13 @@ typedef void * erpc_service_t;
 {% for iface in group.interfaces %}
 erpc_service_t create_{$iface.serviceClassName}(void);
 
-{% if dynamicServices == true %}
+#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
 void destroy_{$iface.serviceClassName}(erpc_service_t *service);
-{% else --dynamicServices == true %}
+#elif ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_STATIC
 void destroy_{$iface.serviceClassName}(void);
-{% endif --dynamicServices == true %}
+#else
+#warning "Unknow eRPC allocation policy!"
+#endif
 
 {% endfor -- iface %}
 #ifdef __cplusplus
diff --git a/erpcgen/src/templates/c_server_source.template b/erpcgen/src/templates/c_server_source.template
index 5f556783..5195b6c1 100644
--- a/erpcgen/src/templates/c_server_source.template
+++ b/erpcgen/src/templates/c_server_source.template
@@ -5,11 +5,11 @@
 {$commonHeader()}
 
 #include "{$serverHeaderName}"
+#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
 #include <new>
 #include "erpc_port.h"
-{% if dynamicServices == false %}
+#endif
 #include "erpc_manually_constructed.h"
-{% endif --dynamicServices == false %}
 {% if empty(group.includes) == false %}
 extern "C"
 {
@@ -28,8 +28,8 @@ using namespace std;
 extern bool nestingDetection;
 #endif
 
-{% for iface in group.interfaces if dynamicServices == false %}
-static ManuallyConstructed<{$iface.serviceClassName}> s_{$iface.serviceClassName};
+{% for iface in group.interfaces %}
+ERPC_MANUALLY_CONSTRUCTED_STATIC({$iface.serviceClassName}, s_{$iface.serviceClassName});
 
 {% endfor -- iface %}
 {$generateCrcVariable()}
@@ -244,7 +244,7 @@ erpc_status_t {$iface.serviceClassName}::{$fn.name}_shim({$codecClass} * codec,
 {% endfor -- iface %}
 {% for iface in group.interfaces %}
 
-{% if dynamicServices == true %}
+#if ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_DYNAMIC
 erpc_service_t create_{$iface.serviceClassName}()
 {
     return new (nothrow) {$iface.serviceClassName}();
@@ -257,7 +257,7 @@ void destroy_{$iface.serviceClassName}(erpc_service_t *service)
         delete service;
     }
 }
-{% else --dynamicServices == true %}
+#elif ERPC_ALLOCATION_POLICY == ERPC_ALLOCATION_POLICY_STATIC
 erpc_service_t create_{$iface.serviceClassName}()
 {
     s_{$iface.serviceClassName}.construct();
@@ -268,5 +268,7 @@ void destroy_{$iface.serviceClassName}()
 {
     s_{$iface.serviceClassName}.destroy();
 }
-{% endif --dynamicServices == true %}
+#else
+#warning "Unknow eRPC allocation policy!"
+#endif
 {% endfor -- iface %}


Test patch:
diff --git a/erpcgen/test/test_dynamic_ann_c.yml b/erpcgen/test/test_dynamic_ann_c.yml
index 8a90d94c..50b86acd 100644
--- a/erpcgen/test/test_dynamic_ann_c.yml
+++ b/erpcgen/test/test_dynamic_ann_c.yml
@@ -9,27 +9,9 @@ idl: |
     }
 
 test_server.cpp:
-  - static ManuallyConstructed<ErrorTest_service> s_ErrorTest_service;
-  - erpc_service_t create_ErrorTest_service()
-  - '{'
-  - s_ErrorTest_service.construct();
-  - return s_ErrorTest_service.get();
-  - '}'
-
----
-name: dynamic
-desc: dynamic annotation is used.
-idl: |
-    @dynamic_services
-    program test
-
-    interface ErrorTest{
-        oneway f()
-    }
-
-test_server.cpp:
-  - erpc_service_t create_ErrorTest_service()
-  - '{'
-  - return new (nothrow) ErrorTest_service();
-  - '}'
-
+    - ERPC_MANUALLY_CONSTRUCTED_STATIC(ErrorTest_service, s_ErrorTest_service);
+    - erpc_service_t create_ErrorTest_service()
+    - "{"
+    - s_ErrorTest_service.construct();
+    - return s_ErrorTest_service.get();
+    - "}"
diff --git a/test/test_annotations/test_annotations.erpc b/test/test_annotations/test_annotations.erpc
index 3265deab..0fc16d70 100644
--- a/test/test_annotations/test_annotations.erpc
+++ b/test/test_annotations/test_annotations.erpc
@@ -12,7 +12,6 @@
 @output_dir("erpc_outputs/") // testing directory with slash on end
 @include("addOne.h")
 @include("external.h")
-@dynamic_services
 program test;
 import "../common/unit_test_common.erpc"