diff --git a/CMakeLists.txt b/CMakeLists.txt
index f50a6b1ba33c7a5edfa0ba33fee2218f89bb7b22..347a3b9eda22db68353512b362f2a28d9768b541 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -135,6 +135,7 @@ add_executable(catch-tests-boardcore
     src/tests/catch/test-airbrakesInterp.cpp
     src/tests/catch/test-pitot.cpp
     src/tests/catch/test-units.cpp
+    src/tests/catch/test-registry-frontend.cpp
 )
 target_compile_definitions(catch-tests-boardcore PRIVATE USE_MOCK_PERIPHERALS)
 sbs_target(catch-tests-boardcore stm32f429zi_stm32f4discovery)
diff --git a/cmake/boardcore-host.cmake b/cmake/boardcore-host.cmake
index 977102ebbfb21ae52befaac414cea42d649da0d5..b3896678ec6530af04a9c1f113fef95699279077 100644
--- a/cmake/boardcore-host.cmake
+++ b/cmake/boardcore-host.cmake
@@ -57,6 +57,8 @@ add_library(boardcore-host STATIC EXCLUDE_FROM_ALL
     ${SBS_BASE}/src/shared/utils/SkyQuaternion/SkyQuaternion.cpp
     ${SBS_BASE}/src/shared/utils/Stats/Stats.cpp
     ${SBS_BASE}/src/shared/utils/TestUtils/TestHelper.cpp
+    ${SBS_BASE}/src/shared/utils/Registry/RegistryFrontend.cpp
+    ${SBS_BASE}/src/shared/utils/Registry/RegistrySerializer.cpp
 )
 add_library(SkywardBoardcore::Boardcore::host ALIAS boardcore-host)
 target_include_directories(boardcore-host PUBLIC ${SBS_BASE}/src/shared)
diff --git a/cmake/boardcore.cmake b/cmake/boardcore.cmake
index 49c749382bc5f0c28f9c8cadaaa283afae039ec5..c437586f8c34dc95259867961074f2e454082a59 100644
--- a/cmake/boardcore.cmake
+++ b/cmake/boardcore.cmake
@@ -130,7 +130,9 @@ foreach(OPT_BOARD ${BOARDS})
         ${SBS_BASE}/src/shared/utils/PinObserver/PinObserver.cpp
         ${SBS_BASE}/src/shared/utils/SkyQuaternion/SkyQuaternion.cpp
         ${SBS_BASE}/src/shared/utils/Stats/Stats.cpp
-        ${SBS_BASE}/src/shared/utils/TestUtils/TestHelper.cpp
+        ${SBS_BASE}/src/shared/utils/TestUtils/TestHelper.cpp        
+        ${SBS_BASE}/src/shared/utils/Registry/RegistryFrontend.cpp
+        ${SBS_BASE}/src/shared/utils/Registry/RegistrySerializer.cpp
     )
     add_library(SkywardBoardcore::Boardcore::${OPT_BOARD} ALIAS ${BOARDCORE_LIBRARY})
     target_include_directories(${BOARDCORE_LIBRARY} PUBLIC ${SBS_BASE}/src/shared)
diff --git a/src/shared/utils/Registry/README.md b/src/shared/utils/Registry/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..1d9750a49d921d4f0cffc3d75274286cdd9013d2
--- /dev/null
+++ b/src/shared/utils/Registry/README.md
@@ -0,0 +1,253 @@
+# Skyward Registry
+
+### Goal and purpose
+
+Skyward Registry is a Skyward project to develop a configuration saving
+mechanism into persistent (flash memory) and non persistent memories (RAM).
+
+Its purpose is to save the configurations for the rocket and retrieve them after
+a reboot or momentary CPU issues and transient events.
+
+The need of such sw development has its roots in some events in which
+the reboot of the rocket, and therefore its configuration, lent to a misconfiguration, taking defaults values. This caused the propulsion chamber's valves
+to open with wrong timing and therefore causing a misfire.
+Therefore, it is of the utmost importance to save the configuration and avoid default and hardcoded values.
+
+## The front-end
+
+### Invocation examples
+In this case we take as example a fictitious configuration entry with uint32_t configuration `id` and value `value`
+
+Type-unsafe interface methods (which takes any data type given as value, without having any map id->data type if the entry was not already set):
+
+#### setConfigurationUnsafe
+```cpp
+float value = 1.3;
+// The id could also be a specific enum (will be casted to uint32_t)
+uint32_t id = 10;
+
+if(frontEnd.setUnsafe(id, value) == RegistryError::OK)
+{    
+    // correctly set
+}
+
+```
+#### getConfigurationUnsafe
+```cpp
+float value;
+// The id could also be a specific enum (will be casted to uint32_t)
+uint32_t id;
+
+
+if(frontEnd.getConfigurationUnsafe(id, value) == RegistryError::OK) 
+{
+    /* Getted the value */
+}
+```
+
+#### getConfigurationOrDefaultUnsafe
+```cpp
+uint32_t ignitionTime, ignitionDefault = 200;
+//The id could also be a specific enum (will be casted to uint32_t)
+uint32_t id = 0;
+/* Default value that will be get (and possibly set) if cannot get an already initialized value*/
+uint32_t default = 400;
+
+ignitionTime = frontEnd.getConfigurationOrDefaultUnsafe(id, ignitionDefault);
+```
+
+#### arm
+```cpp
+frontEnd.arm()
+```
+
+#### disarm
+```cpp
+frontEnd.disarm()
+```
+
+#### isEmpty
+```cpp
+if(frontEnd.isEmpty())
+{
+    /* The front end configuration is empty */
+}
+```
+
+#### save
+```cpp
+if(frontEnd.save() == RegistryError::OK)
+{
+    // Saved correctly the configuration
+}
+```
+
+#### load
+```cpp
+if(frontEnd.load() == RegistryError::OK){
+    // Loaded the configuration correctly
+}
+```
+
+#### clear
+```cpp
+frontEnd.clear();
+```
+
+### How to add new structs
+The correct flow to add new types/configuration entries is:
+
+If the data type needed not exists already you need to follow these steps:
+
+- `TypeStructure.h`: 
+    - Add the type to the TypeUnion;
+    - Update the type enum; 
+    - Create the correct overloads in EntryStructsUnion;
+
+ - `RegistrySerializer.h`, `RegistrySerializer.cpp`: 
+    - Update the write
+    - Update the deserialize
+
+
+### Goals
+
+| Goal |  Description  |
+|:-----|:--------:|
+| G1 | The configuration could be possibly saved in memory |
+| G2 | The configuration could be possibly loaded from memory |
+|G3 | It will be possible to set the value of a particular configuration entry|
+|G4 | It will be possible to get the value of a particular configuration entry |
+|G5 | It will be possible to inspect the configured entries |
+|G6 | More data types can be used as value for the different configurations entries |
+|G7 | There will be a protection against changes to the configuration during flight |
+|G8 | No dynamic allocations will be executed during the flight |
+|G9 | The registry will offer a persistent configuration saving |
+|G10 | It will be possible to verify the integrity of the configuration|
+|G11 | It will be possible to explore the current configuration |
+|G12 | Thread safeness is guaranteed |
+
+**Note:** the Registry Frontend purpose is not to assure with 100% certainty that a configuration is saved in memory and will be loaded. Instead it is an
+additional safety net which, in case of a restart of the rocket, could possibly lead to have the saved configuration re-loaded after reboot/reset.
+
+This note about the registry frontend purpose also considers the fact that a configuration may not be saved in memory, that the memory could have issues or even that a configuration is saved but corrupted.
+
+### Assumptions
+The front-end, FE, considers some important assumptions about the usage of such sw component.
+This assumptions are about the method call, the order of operations and other assumptions on the usage.
+Such assumptions considers the actual necessities for Skyward Registry and might not be true in future.
+
+| Assumption |  Description  |
+|:-----|:--------:|
+|A1 | The FE is constructed and started once, a single time|
+|A2 | The FE does saves and loads a single configuration from the registry and no multiple versions|
+|A3 | The FE is called before the flight phase for instantiation, load and set |
+|A4 | The FE is correctly armed before the flight |
+|A5 | The FE disarming is not used during flight phase |
+|A6 | The caller considers the return of the get and set methods|
+|A7 | Configuration entries does not have pointers as datatype |
+|A8 | The backend does not modify the vector to be saved.|
+|A9 | The save method is correctly trigger externally when a save is needed |
+
+### Requirements
+
+| Requirements |  Description  |
+|:-----|:--------:|
+|R1 | The interface must allow setting a value for the specific configuration entries |
+|R2 | The interface must allow getting a specified value for a   configuration entries |
+|R3 | The interface must perform some type check for the specifics entries to get |
+|R4 | The interface must not allocate memory during the flight phase |
+|R5 | The interface must not change the configuration entries during flight phase |
+|R6 | The interface does save the configuration entries using the back-end components |
+|R7 | The FE must manage concurrent get/set by multiple threads (Thread safety)|
+|R8 | The FE must manage concurrent arm/disarm by multiple threads  (Thread safety)|
+|R9 | The FE must allow exploration of the actual configuration|
+|R10 | The FE should be able to control the configuration state (empty or has elements)|
+| R11 | The FE should not be blocked during the actual backend saving procedure |
+
+### Interface methods
+
+The unsafe (type-unsafe) methods uses a parameter value for a specific registry entry uint32_t index identifier (could be a casted enumerator from OBSW structures) and a value from a specific data type. The Unsafeness is given by the fact that the data type is given from the value data type given to the set/get methods.
+
+- `start`: Starts the backend and other objects that requires to be started, as an ActiveObject.
+
+- `setUnsafe`:  A setter method is in need to ensure R1. This method should allow 
+    insert a value for a specific configuration entry while guarantee the different data types for the values (R3).
+    
+- `getUnsafe`:  A getter method is in need to ensure the visibility of the configuration. 
+    Such method should get a value for a specified configuration entry and changes the value to passed by reference value parameter. It does check that the type is consistent with the saved one.
+
+- `getOrSetDefaultUnsafe`: A particular get method which returns the get value and if it is not existing in the configuration set it (if possible!) and returns the default value.
+
+ - `arm`:  An "arm" method which guarantees no memory allocations and no changes to the configuration are in place
+    until a "disarm" method. It is an important functionality to ensure a "safe" memory configuration during flight.
+
+ - `disarm`: A "disarm" method, to disable the stable and "safe" configuration mode of the registry to allow again 
+    allocations and settings on the configuration.
+
+ - `isEmpty`: A method to know if there is an existing configuration or if it is empty
+
+- `configuredEntries`: A method which returns the already existing entries of the configuration as a set.
+
+- `load`: Loads from the backend the configuration. If no backend, it loads it from its own vector. 
+
+- `save`: Saves the configuration to the backend.
+
+- `clear`: Clears the configuration both in frontend and backend components, starting with an empty configuration.
+
+- `forEach`: Given a callback, it does apply it for each element of the actual configuration with the id and EntryStructUnion parameters. 
+
+### Data structures
+The data structures are managed in 2 main header files.
+#### RegistryTypes.h
+Type structures have:
+
+- `TypeUnion`: The union type for saving the values of the different configuration entries
+
+- `EntryStructsUnion`: The structure actually saved into the configuration, with the value and type attributes. Also, it does expose all the useful operations for get/set the value from/to union and create a new instance of EntryStructsUnion through `make(value)` method.
+
+#### RegistrySerializer.h
+
+- `RegistryHeader`: The header structure for the serialization and de-serialization. Contains the attributes and information useful for the serialization and de-serialization procedures.
+- `RegistryFooter`: Contains the custom checksum of the serialized configuration.
+
+## The serializer
+The serializer simply taken a configuration, it serialize or deserialize it on the vector given in the constructor, following the format specified above. It isolates the serialize and de-serialize procedure from the frontend by making it simpler and more coherent.
+
+### Exposed methods:
+- `RegistrySerializer(vector)` The constructor needs the vector to/from which it writes the serialized data or reads to deserialize it.
+
+- `serializeConfiguration(configuration)` Serializes the configuration + header and footer to the vector given in the constructor.
+
+ - `deserializeConfiguration(configuration)` From the vector, loads the configuration inserting the entries if the vector checks (Checksum, length, startBytes) are verified.
+
+### Data saving serialization
+serializationVector is a vector that after getSerializedVector will contain:
+|||
+|:-----|--------:|
+|Header| serializardConfigurations|
+
+As for now, the header (visible in RegistryTypes.h) is composed with 8B of bytes equal to decimal 1 for endianess checking, 4 bytes of vector length (whole vector including the header), 4B of nr. of configuration entries in the serialized vector, 4B of checksum - checksum computed with xor byte per byte of the serialized configurations following the header.
+
+|||||||||
+|:-----|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|----:|
+|8B = 1| 4B Length vector | 4B Nr. entries | 4B Checksum | ID_0 | TypeID_0 | Value_0| ... |
+
+Header closeup (0bit as rightmost one / big endian):
+
+|||||||||||||||||||||
+|:-----|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|:--------:|----:|
+|0|0|0|0|0|0|0|1|v_len 31-24|v_len 23-16|v_len 15-8|v_len 7-0|nr_en 31-24|nr_en 23-16|nr_en 15-8|nr_en 7-0|chsum 31-24|chsum 23-16|chsum 15-8|chsum 7-0|
+
+The vector will contain only the set configurations. After the header, there will be all the configured entries with configuration ID, Type ID, Value(s).
+
+In case of multiple values, they are one after the other 
+
+e.g. for a Coordinate: 
+|||||
+|:-----|:--------:|:--------:|--------:|
+| ID: 2 | TypeID: 1 | Val_1: 45.50109 | Val_2: 9.15633 | 
+
+Where TypeID in this example is a coordinates type and therefore 45.50109 is the latitude and 9.15633 the longitude
+
+### Saving
+The save of the configuration is done manually by using the RegistryFrontend `save()` method. To reset the memory `clear()` + `save()` should be used.
\ No newline at end of file
diff --git a/src/shared/utils/Registry/RegistryBackend.h b/src/shared/utils/Registry/RegistryBackend.h
new file mode 100644
index 0000000000000000000000000000000000000000..9a1f8cffa571d0068ff685444dbd094082605475
--- /dev/null
+++ b/src/shared/utils/Registry/RegistryBackend.h
@@ -0,0 +1,81 @@
+/* Copyright (c) 2024 Skyward Experimental Rocketry
+ * Author: Nicolò Caruso, Davide Mor
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <vector>
+
+#include "RegistryTypes.h"
+
+namespace Boardcore
+{
+
+/**
+ * @brief Registry Backend class used to save and load data to the designated
+ * storage/memory.
+ */
+class RegistryBackend
+{
+public:
+    /**
+     * @brief Starts the backend, eventually used in backends that
+     * need to start classes and other things e.g. an ActiveObject
+     *
+     * @return true if successful, false otherwise
+     */
+    virtual bool start() = 0;
+
+    /**
+     * @brief Loads into the buffer the saved configuration from the
+     * storage/memory.
+     *
+     * @param buf The buffer where the data will be loaded from the
+     * storage/memory if any is saved.
+     *
+     * @return true if successful, false otherwise.
+     */
+    virtual bool load(std::vector<uint8_t>& buf) = 0;
+
+    /**
+     * @brief Saves the data in the buf to the storage/memory.
+     *
+     * @param buf The buf vector with the data to be saved.
+     *
+     * @return true if successful, false otherwise.
+     */
+    virtual bool save(std::vector<uint8_t>& buf) = 0;
+};
+
+/**
+ * @brief Dummy no-op backend
+ */
+class DummyBackend final : public RegistryBackend
+{
+public:
+    bool start() override { return true; }
+
+    bool load(std::vector<uint8_t>& buf) override { return true; }
+
+    bool save(std::vector<uint8_t>& buf) override { return true; }
+};
+
+}  // namespace Boardcore
\ No newline at end of file
diff --git a/src/shared/utils/Registry/RegistryFrontend.cpp b/src/shared/utils/Registry/RegistryFrontend.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..87bed26e89e9006a5b20dd0610a0fa50122bbbfa
--- /dev/null
+++ b/src/shared/utils/Registry/RegistryFrontend.cpp
@@ -0,0 +1,116 @@
+/* Copyright (c) 2023 Skyward Experimental Rocketry
+ * Author: Nicolò Caruso
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "RegistryFrontend.h"
+
+namespace Boardcore
+{
+RegistryFrontend::RegistryFrontend(std::unique_ptr<RegistryBackend> backend)
+    : backend{std::move(backend)}
+{
+    serializationVector.reserve(1024);
+    configuration.reserve(
+        1024 / sizeof(std::pair<ConfigurationId, EntryStructsUnion>));
+}
+
+RegistryError RegistryFrontend::start()
+{
+    const std::lock_guard<std::recursive_mutex> lock(mutexForRegistry);
+    if (!backend->start())
+        return RegistryError::BACKEND_START_FAIL;
+
+    return RegistryError::OK;
+}
+
+void RegistryFrontend::arm()
+{
+    const std::lock_guard<std::recursive_mutex> lock(mutexForRegistry);
+    isArmed = true;
+}
+
+void RegistryFrontend::disarm()
+{
+    const std::lock_guard<std::recursive_mutex> lock(mutexForRegistry);
+    isArmed = false;
+}
+
+void RegistryFrontend::forEach(const EntryFunc& predicate)
+{
+    const std::lock_guard<std::recursive_mutex> lock(mutexForRegistry);
+    for (auto& it : configuration)
+    {
+        predicate(it.first, it.second);
+    }
+}
+
+RegistryError RegistryFrontend::load()
+{
+    const std::lock_guard<std::recursive_mutex> lock(mutexForRegistry);
+    if (isArmed)
+        return RegistryError::ARMED;
+
+    if (!backend->load(serializationVector))
+        return RegistryError::BACKEND_LOAD_FAIL;
+
+    RegistrySerializer serializer(serializationVector);
+    return serializer.deserializeConfiguration(configuration);
+}
+
+bool RegistryFrontend::isEntryConfigured(
+    const ConfigurationId configurationIndex)
+{
+    const std::lock_guard<std::recursive_mutex> lock(mutexForRegistry);
+    auto iterator = configuration.find(configurationIndex);
+    return !(iterator == configuration.end());
+}
+
+bool RegistryFrontend::isEmpty()
+{
+    const std::lock_guard<std::recursive_mutex> lock(mutexForRegistry);
+    return configuration.empty();
+}
+
+RegistryError RegistryFrontend::save()
+{
+    const std::lock_guard<std::recursive_mutex> lock(mutexForRegistry);
+    // In case the registry is armed inhibit the saving
+    if (isArmed)
+        return RegistryError::ARMED;
+
+    RegistrySerializer serializer(serializationVector);
+    RegistryError error = serializer.serializeConfiguration(configuration);
+    if (error != RegistryError::OK)
+        return error;
+
+    if (!backend->save(serializationVector))
+        return RegistryError::BACKEND_SAVE_FAIL;
+
+    return RegistryError::OK;
+}
+
+void RegistryFrontend::clear()
+{
+    const std::lock_guard<std::recursive_mutex> lock(mutexForRegistry);
+    configuration.clear();
+};
+
+}  // namespace Boardcore
\ No newline at end of file
diff --git a/src/shared/utils/Registry/RegistryFrontend.h b/src/shared/utils/Registry/RegistryFrontend.h
new file mode 100644
index 0000000000000000000000000000000000000000..b1d79c67bb5bb004b610a4b53465788d7e5c633b
--- /dev/null
+++ b/src/shared/utils/Registry/RegistryFrontend.h
@@ -0,0 +1,255 @@
+/* Copyright (c) 2023 Skyward Experimental Rocketry
+ * Author: Nicolò Caruso
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#pragma once
+
+#include <diagnostic/PrintLogger.h>
+#include <utils/Debug.h>
+
+#include <cstdint>
+#include <mutex>
+#include <unordered_map>
+#include <vector>
+
+#include "RegistryBackend.h"
+#include "RegistrySerializer.h"
+#include "RegistryTypes.h"
+
+namespace Boardcore
+{
+
+/**
+ * @brief This is the front-end for the registry to store and load the
+ * configuration. Its methods are type unsafe since the type is determined by
+ * the entry setted. It does check the data types but its job is mainly the one
+ * of get and set for the given ConfigurationId, the value of the entry. It also
+ * exposes methods for go into a "safe" state during armed state / flight.
+ * Finally there are methods to visit the entire configuration (forEach).
+ */
+class RegistryFrontend
+{
+public:
+    using EntryFunc = std::function<void(ConfigurationId, EntryStructsUnion&)>;
+
+    /**
+     * @brief Registry front end constructor. Initializes the configuration of
+     * the underlying objects and reserves 1KB for the vectors and map data
+     * structures.
+     */
+    RegistryFrontend(std::unique_ptr<RegistryBackend> backend =
+                         std::make_unique<DummyBackend>());
+
+    /**
+     * @brief Start function to start frontend and other objects, such as
+     * ActiveObjects, needed to write to backend, and the backend itself
+     */
+    [[nodiscard]] RegistryError start();
+
+    /**
+     * @brief Disables the memory registry set and allocations.
+     * To be use when the rocket itself is armed and during flight.
+     */
+    void arm();
+
+    /**
+     * @brief Enable set methods and memory allocations.
+     *
+     * @note To be used when the rocket is NOT in an "armed" state and while on
+     * ground.
+     */
+    void disarm();
+
+    /**
+     * @brief Executes immediately the predicate for each to the configuration
+     * applying the callback with the id and EntryStructsUnion union as
+     * parameter for each configured entry in the configuration.
+     *
+     * @param predicate The predicate function to execute for each configuration
+     * entry
+     */
+    void forEach(const EntryFunc& predicate);
+
+    /**
+     * @brief Verify if there is an existing entry given its enum entry.
+     *
+     * @param configurationIndex The configuration entry ID for which we
+     * verify the entry is configured.
+     * @return True if such configuration entry exists in the configuration
+     * otherwise False.
+     */
+    bool isEntryConfigured(const ConfigurationId configurationIndex);
+
+    /**
+     * @brief Verify that the configuration is empty or exists some setted
+     * entries
+     *
+     * @return True if the configuration has no entries. False otherwise
+     */
+    bool isEmpty();
+
+    // TYPE UNSAFE INTERFACE METHODS
+
+    /**
+     * @brief Gets the value for a given configuration entry.
+     *
+     * @note It does change the given variable with the correct value if
+     * existing
+     * @tparam T The value data type for such configuration entry
+     * @param configurationIndex Identifies the configuration entry with its
+     * enumeration value
+     * @param outValue the specified configuration entry value
+     * @return OK in case of successful insertion.
+     * @return ENTRY_NOT_FOUND In case the entry is not found in the
+     * configuration
+     * @return INCORRECT_TYPE If the setted data type not corresponds with the
+     * given value data type
+     */
+    template <typename T>
+    RegistryError getUnsafe(const ConfigurationId configurationIndex,
+                            T& outValue)
+    {
+        std::lock_guard<std::recursive_mutex> lock(mutexForRegistry);
+        auto iterator = configuration.find(configurationIndex);
+        /** Checks that the value type corresponds to the set type and finds
+         * the entry*/
+        if (iterator == configuration.end())
+            return RegistryError::ENTRY_NOT_FOUND;
+        if (!iterator->second.get(outValue))
+            return RegistryError::INCORRECT_TYPE;
+        return RegistryError::OK;
+    }
+
+    /**
+     * @brief Gets the value for a specified configuration entry. Otherwise
+     * returns default and try to set the default value
+     *
+     * @tparam T The value data type to be returned and eventually set.
+     * @param configurationIndex Identifies the configuration entry with its
+     * enumeration value
+     * @param defaultValue The default value to be returned and set
+     * (eventually) in case of non-existing configuration entry
+     * @return The value saved for the configuration entry in the
+     * configuration or the default value if there is no such entry in the
+     * configuration
+     */
+    template <typename T>
+    T getOrSetDefaultUnsafe(const ConfigurationId configurationIndex,
+                            T defaultValue)
+    {
+        std::lock_guard<std::recursive_mutex> lock(mutexForRegistry);
+        T returnValue;
+        if (getUnsafe(configurationIndex, returnValue) == RegistryError::OK)
+        {
+            return returnValue;
+        }
+        if (setUnsafe(configurationIndex, defaultValue) != RegistryError::OK)
+            LOG_ERR(logger,
+                    "Registry - Could not insert the default configuration");
+        return defaultValue;
+    }
+
+    /**
+     * @brief Sets the value for the configuration entry with the specified
+     * enum
+     *
+     * @note The set applies only to frontend, the change does not apply to
+     * backend, save should be triggered manually to do so
+     * @tparam T The configuration value datatype
+     * @param configurationIndex The ID of the configuration entry to set
+     * @param value The value to be set for the specified configuration
+     * entry
+     * @return OK if it was possible to set the configurationEntry.
+     * @return ARMED If the registry is in an armed state, therefore setting a
+     * configuration is forbidden
+     */
+    template <typename T>
+    RegistryError setUnsafe(ConfigurationId configurationIndex, T value)
+    {
+        std::lock_guard<std::recursive_mutex> lock(mutexForRegistry);
+        /* In case that the configuration is in an armed state it cannot be
+         * modified */
+        if (isArmed)
+            return RegistryError::ARMED;
+        EntryStructsUnion entry = EntryStructsUnion::make(value);
+        auto insert = configuration.insert({configurationIndex, entry});
+        if (!insert.second)
+            insert.first->second = entry;
+        return RegistryError::OK;
+    }
+
+    // LOAD AND SAVE TO BACKEND
+
+    /**
+     * @brief Loads from the backend the configuration
+     *
+     * @note The operation overrides configurations but maintains the ones that
+     * are not present in the backend configuration
+     * @return OK if the configuration exists in memory and is not
+     * corrupted
+     * @return MALFORMED_SERIALIZED_VECTOR if the vector has a bad format (see
+     * serializer)
+     * @return CHECKSUM_FAIL In case the saved Checksum is incorrect (see
+     * serializer)
+     * @return NO_SUCH_TYPE In case there are unspecified type ids (see
+     * serializer)
+     * @return WRONG_ENDIANESS In case the endianess of serialization not
+     * corresponds (see serializer)
+     */
+    RegistryError load();
+
+    /**
+     * @brief Saves the configuration to the backend
+     *
+     * @attention: The save will be inhibited in case of "armed" state in order
+     * to avoid unwanted allocations to the serializationVector during flight.
+     *
+     * @return OK if could save correctly
+     * @return MALFORMED_SERIALIZED_DATA if the vector not have the
+     * appropriate length (see serializer)
+     * @return CHECKSUM_FAIL In case the saved Checksum not corresponds (see
+     * serializer)
+     * @return NO_SUCH_TYPE In case there are unspecified type ids (see
+     * serializer)
+     */
+    RegistryError save();
+
+    /**
+     * @brief Clear the configuration actually saved, resetting to empty
+     * configuration.
+     *
+     * @note Does affect the underlying backend.
+     *
+     * @attention It does not directly delete the backend saved copy, save
+     * should be used to trigger such action
+     */
+    void clear();
+
+private:
+    std::recursive_mutex mutexForRegistry;
+    std::unordered_map<ConfigurationId, EntryStructsUnion> configuration;
+    bool isArmed = false;
+    std::vector<uint8_t> serializationVector;
+    std::unique_ptr<RegistryBackend> backend;
+    PrintLogger logger = Logging::getLogger("registry-frontend");
+};
+
+}  // namespace Boardcore
diff --git a/src/shared/utils/Registry/RegistrySerializer.cpp b/src/shared/utils/Registry/RegistrySerializer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4cea30426e02659d6a9f3f74cce70107c7a1c3b4
--- /dev/null
+++ b/src/shared/utils/Registry/RegistrySerializer.cpp
@@ -0,0 +1,232 @@
+/* Copyright (c) 2023 Skyward Experimental Rocketry
+ * Author: Nicolò Caruso
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "RegistrySerializer.h"
+
+#include <functional>
+#include <numeric>
+
+namespace Boardcore
+{
+RegistrySerializer::RegistrySerializer(std::vector<uint8_t>& vector)
+    : serializationVector(vector), vectorWritePosition(0)
+{
+}
+
+RegistryError RegistrySerializer::serializeConfiguration(
+    RegistryConfiguration& configuration)
+{
+    RegistryError error = RegistryError::OK;
+    bool success        = true;
+
+    // Resizes the serialization vector
+    serializationVector.resize(size(configuration));
+
+    // Write the header
+    RegistryHeader header;
+    header.startBytes = 1;
+    header.totalSize  = serializationVector.size();
+    header.nrEntries  = configuration.size();
+    error             = serialize(header);
+    if (error != RegistryError::OK)
+        return RegistryError::NO_SPACE_FOR_HEADER;
+
+    // Add the configuration entries one after the other
+    for (auto& entry : configuration)
+    {
+        TypesEnum type;
+        // Appends the entry ID
+        success &= (serialize(entry.first) == RegistryError::OK);
+        // Appends the configuration entry
+        type = entry.second.getType();
+        success &= (serialize(type) == RegistryError::OK);
+        if (!success)
+            return RegistryError::WRONG_WRITES_SIZE;
+
+        switch (entry.second.getType())
+        {
+            case TypesEnum::COORDINATES:
+            {
+                Coordinates coordinate{0, 0};
+                entry.second.get(coordinate);
+                success &= (serialize(coordinate) == RegistryError::OK);
+                break;
+            }
+
+            case TypesEnum::UINT32:
+            {
+                uint32_t uint32Value = 0;
+                entry.second.get(uint32Value);
+                success &= (serialize(uint32Value) == RegistryError::OK);
+                break;
+            }
+
+            case TypesEnum::FLOAT:
+            {
+                float floatValue = 0;
+                entry.second.get(floatValue);
+                success &= (serialize(floatValue) == RegistryError::OK);
+                break;
+            }
+
+            default:
+                return RegistryError::NO_SUCH_TYPE;
+                break;
+        }
+        if (!success)
+            return RegistryError::WRONG_WRITES_SIZE;
+    }
+
+    // Compute the Footer and write it
+    RegistryFooter footer;
+    footer.checksum = computeChecksum();
+
+    // Add the footer to the serialized data
+    return serialize(footer);
+}
+
+RegistryError RegistrySerializer::deserializeConfiguration(
+    RegistryConfiguration& configuration)
+{
+    bool success = true;
+
+    // Case the vector is empty/not have even the vector size
+    if (serializationVector.size() <
+        sizeof(RegistryHeader) + sizeof(RegistryFooter))
+        return RegistryError::MALFORMED_SERIALIZED_DATA;
+
+    RegistryHeader header;
+    success &= (deserialize(header) == RegistryError::OK);
+    if (!success)
+        return RegistryError::MALFORMED_SERIALIZED_DATA;
+
+    if (header.startBytes != 1)
+    {
+        return RegistryError::WRONG_ENDIANESS;
+    }
+
+    // Save the current vector position before jumping to the footer
+    uint32_t previousPos = vectorWritePosition;
+    vectorWritePosition  = header.totalSize - sizeof(RegistryFooter);
+    RegistryFooter footer;
+    success &= (deserialize(footer) == RegistryError::OK);
+    if (!success)
+        return RegistryError::MALFORMED_SERIALIZED_DATA;
+    // Restore vector position
+    vectorWritePosition = previousPos;
+
+    uint32_t savedChecksum = computeChecksum();
+    if (footer.checksum != savedChecksum)
+        return RegistryError::CHECKSUM_FAIL;
+
+    // Set the configuration from the saved configuration
+    uint32_t counter = 0;
+
+    while (vectorWritePosition < serializationVector.size() - sizeof(footer) &&
+           counter < header.nrEntries)
+    {
+        ConfigurationId id = 0;
+        TypesEnum typeId;
+        // Gets the ID of the entry, the ID of the data type, the value
+        success &= (deserialize(id) == RegistryError::OK);
+        success &= (deserialize(typeId) == RegistryError::OK);
+        if (!success)
+            return RegistryError::MALFORMED_SERIALIZED_DATA;
+
+        switch (typeId)
+        {
+            case TypesEnum::COORDINATES:
+            {
+                Coordinates coordinate{0, 0};
+                success &= (deserialize(coordinate) == RegistryError::OK);
+                if (!success)
+                    return RegistryError::MALFORMED_SERIALIZED_DATA;
+                EntryStructsUnion entry = EntryStructsUnion::make(coordinate);
+                auto insert             = configuration.insert({id, entry});
+                if (!insert.second)
+                    insert.first->second = entry;
+                break;
+            }
+            case TypesEnum::FLOAT:
+            {
+                float floatValue = 0;
+                success &= (deserialize(floatValue) == RegistryError::OK);
+                if (!success)
+                    return RegistryError::MALFORMED_SERIALIZED_DATA;
+                EntryStructsUnion entry = EntryStructsUnion::make(floatValue);
+                auto insert             = configuration.insert({id, entry});
+                if (!insert.second)
+                    insert.first->second = entry;
+                break;
+            }
+            case TypesEnum::UINT32:
+            {
+                uint32_t uint32Value = 0;
+                success &= (deserialize(uint32Value) == RegistryError::OK);
+                if (!success)
+                    return RegistryError::MALFORMED_SERIALIZED_DATA;
+                EntryStructsUnion entry = EntryStructsUnion::make(uint32Value);
+                auto insert             = configuration.insert({id, entry});
+                if (!insert.second)
+                    insert.first->second = entry;
+                break;
+            }
+            default:
+            {
+                return RegistryError::NO_SUCH_TYPE;
+            }
+        }
+
+        counter++;
+    }
+
+    return RegistryError::OK;
+}
+
+uint32_t RegistrySerializer::computeChecksum()
+{
+    uint32_t counter = 0;
+    return std::accumulate(
+        serializationVector.begin() + sizeof(RegistryHeader),
+        serializationVector.end() - sizeof(RegistryFooter), 0,
+        [&counter](uint32_t acc, uint8_t element)
+        {
+            acc ^= static_cast<uint32_t>(element >> (3 - (counter % 4)) * 8);
+            counter++;
+            return acc;
+        });
+}
+
+size_t RegistrySerializer::size(RegistryConfiguration& configuration)
+{
+    size_t totalSize = sizeof(RegistryHeader) + sizeof(RegistryFooter);
+
+    // Compute the overall space required for the configurations
+    for (auto& entry : configuration)
+    {
+        totalSize += sizeof(entry.first);
+        totalSize += entry.second.sizeBytes();
+    }
+    return totalSize;
+}
+
+}  // namespace Boardcore
\ No newline at end of file
diff --git a/src/shared/utils/Registry/RegistrySerializer.h b/src/shared/utils/Registry/RegistrySerializer.h
new file mode 100644
index 0000000000000000000000000000000000000000..1f1685d000214d0375b87659608abe7acefc2d3d
--- /dev/null
+++ b/src/shared/utils/Registry/RegistrySerializer.h
@@ -0,0 +1,195 @@
+/* Copyright (c) 2023 Skyward Experimental Rocketry
+ * Author: Nicolò Caruso
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#pragma once
+
+#include <utils/Debug.h>
+
+#include <cstdint>
+#include <cstring>
+#include <functional>
+#include <unordered_map>
+#include <vector>
+
+#include "RegistryTypes.h"
+
+namespace Boardcore
+{
+
+using RegistryConfiguration =
+    std::unordered_map<ConfigurationId, EntryStructsUnion>;
+
+/**
+ * @brief Serialization header, with useful information about the serialized
+ * data. Header to the actually serialized data.
+ */
+struct RegistryHeader
+{
+    uint64_t startBytes;  ///< Bytes at start, initialized as 1
+    uint32_t totalSize;   ///< Total size of serialized data in bytes
+    uint32_t nrEntries;   ///< Nr of configuration entries
+};
+
+/**
+ * @brief Registry Footer, with checksum of the configuration data (not whole
+ * data). Placed at the end of the actually serialized data
+ */
+struct RegistryFooter
+{
+    uint32_t checksum;
+};
+
+/**
+ * @brief Serialization and de-serialization class for the registry. It does
+ * serialize and deserialize the configuration to the specified vector.
+ */
+class RegistrySerializer
+{
+public:
+    /**
+     * @brief Construct a new Registry Serializer object
+     *
+     * @param vector The reference to the vector for
+     * serialization/deserialization procedures
+     */
+    explicit RegistrySerializer(std::vector<uint8_t>& vector);
+
+    /**
+     * @brief Serializes the configuration map into the uint8_t vector for
+     * serialized data
+     *
+     * @note In case an error is returned no guarantees are made about the
+     * contents of the vector
+     * @note The vector is resized if not of the exact size for serialization
+     * @param configuration The configuration from which we read the
+     * current entries to be serialized
+     * @return OK If the de-serialization was successful and the entries where
+     * added into the map
+     * @return MALFORMED_SERIALIZED_DATA if the vector not have the
+     * appropriate length for the header, footer and configuration
+     * @return CHECKSUM_FAIL In case the saved Checksum not corresponds with the
+     * one recomputed from the serialized configuration
+     * @return NO_SUCH_TYPE In case the type id not corresponds to any defined
+     * data type for the configuration
+     */
+    RegistryError serializeConfiguration(RegistryConfiguration& configuration);
+
+    /**
+     * @brief De-serializes the data from a serialized vector into the
+     * configuration map. In case of malformed serialized vectors, does not
+     * changes the configuration map and returns an error
+     *
+     * @param configuration The map in which we want to insert the entries
+     * from the serialized vector
+     * @note The deserialization adds/overwrites configuration entries. The
+     * already present entries, if in the deserialized data, are overriden.
+     * @note Pre-existing configuration entries are not removed (but might be
+     * overwritten)
+     * @return OK If the de-serialization was successful and the entries where
+     * added into the map
+     * @return MALFORMED_SERIALIZED_DATA if the vector not have the
+     * appropriate length for the header, footer and configuration data
+     * @return CHECKSUM_FAIL In case the saved Checksum not corresponds with the
+     * one recomputed from the serialized configuration
+     * @return NO_SUCH_TYPE In case the type id not corresponds to any defined
+     * data type for the configuration
+     * @return WRONG_ENDIANESS In case the endianess of the loaded data not
+     * corresponds
+     */
+    RegistryError deserializeConfiguration(
+        RegistryConfiguration& configuration);
+
+private:
+    std::vector<uint8_t>& serializationVector;
+    uint32_t vectorWritePosition;
+
+    /**
+     * @brief Computes a custom checksum of the serialized configuration data
+     *
+     * @return uint32_t The computed custom checksum
+     */
+    uint32_t computeChecksum();
+
+    /**
+     *
+     * @brief Deserializes from the vector the data in sequential order and
+     * inserts/overwrites entries into the configuration.
+     *
+     * @tparam T the element data type
+     * @param element The element we want to get from the serialized vector
+     * @return OK If the read was successful
+     * @return MALFORMED_SERIALIZED_DATA Otherwise, in case the vector is not
+     * long enough to read the element
+     */
+    template <typename T>
+    RegistryError deserialize(T& element)
+    {
+        size_t elSize = sizeof(T);
+
+        if (serializationVector.size() < vectorWritePosition + elSize)
+            return RegistryError::MALFORMED_SERIALIZED_DATA;
+
+        std::memcpy(&element, serializationVector.data() + vectorWritePosition,
+                    elSize);
+
+        vectorWritePosition += elSize;
+        return RegistryError::OK;
+    }
+
+    /**
+     * @brief serialize functions writes to the vector the elements to
+     * serialize. It does such task using memcpy and using the positional
+     * attribute to know the current position where to write and updates such
+     * attribute.
+     *
+     * @tparam T the element data type
+     * @param element The element to be written in the serialized vector
+     * @return OK If it could successfully write
+     * @return WRONG_WRITES_SIZE Otherwise, in case could not write due to not
+     * enough space in the vector
+     */
+    template <typename T>
+    RegistryError serialize(T& element)
+    {
+        size_t elSize = sizeof(T);
+
+        if (serializationVector.size() < vectorWritePosition + elSize)
+            return RegistryError::WRONG_WRITES_SIZE;
+
+        std::memcpy(serializationVector.data() + vectorWritePosition, &element,
+                    elSize);
+
+        vectorWritePosition += elSize;
+        return RegistryError::OK;
+    }
+
+    /**
+     * @brief The size function to get the size of the vector that will be
+     * serialized. It does take into account the header, actual configuration
+     * and footer.
+     *
+     * @return size_t The size that the serialized vector will have after the
+     * serialization process
+     */
+    size_t size(RegistryConfiguration& configuration);
+};
+
+}  // namespace Boardcore
\ No newline at end of file
diff --git a/src/shared/utils/Registry/RegistryTypes.h b/src/shared/utils/Registry/RegistryTypes.h
new file mode 100644
index 0000000000000000000000000000000000000000..fa05eb9bdebeed21dba5c530ec3efebf7fe40e94
--- /dev/null
+++ b/src/shared/utils/Registry/RegistryTypes.h
@@ -0,0 +1,230 @@
+/* Copyright (c) 2023 Skyward Experimental Rocketry
+ * Author: Nicolò Caruso
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#pragma once
+
+#include <cstdint>
+
+namespace Boardcore
+{
+/**
+ * @brief Coordinates struct with latitude [degree], longitude [degree]
+ */
+struct Coordinates
+{
+    float latitude;
+    float longitude;
+};
+
+// The Configuration ID for the configuration entries
+using ConfigurationId = uint32_t;
+
+// Types used for the union
+enum TypesEnum
+{
+    UINT32,
+    FLOAT,
+    COORDINATES
+};
+
+/**
+ * @brief Union type used for the underlying saving mechanism for the
+ * configuration values
+ */
+union TypeUnion
+{
+    float float_type;
+    uint32_t
+        uint32_type;  ///< used for both uint32_t and uint8_t type with upcast
+    Coordinates coordinates_type;
+};
+
+static_assert(
+    sizeof(TypeUnion) == 0x8,
+    "TypeUnion size has changed, make sure to update code relying on it.");
+
+/**
+ * @brief RegistryError enumeration as return type.
+ */
+enum RegistryError
+{
+    OK,                         ///< Correct condition
+    MALFORMED_SERIALIZED_DATA,  ///< Malformed data while deserializing
+    CHECKSUM_FAIL,              ///< The custom checksum check fails
+    INCORRECT_TYPE,             ///< The typeId and value type not correspond
+    WRONG_WRITES_SIZE,          ///< Cannot write due to wrong data size
+    NO_SPACE_FOR_HEADER,  ///< There is not enough space to write the header
+    NO_SUCH_TYPE,         ///< There is no such type in TypeEnum
+    ARMED,            ///< The registry is armed, the operation is not allowed
+    ENTRY_NOT_FOUND,  ///< Not found such entry
+    WRONG_ENDIANESS,  ///< The endianess not corresponds
+    BACKEND_START_FAIL,  //< Backend failed to start
+    BACKEND_LOAD_FAIL,   //< Backend failed to load data
+    BACKEND_SAVE_FAIL,   //< Backend failed to save data
+};
+
+/**
+ * @brief Union data struct to be stored in the map. It does contain the
+ * enumeration index and the value of such configuration entry
+ */
+struct EntryStructsUnion
+{
+
+    /**
+     * @brief Default constructor to construct a new Entry Structs Union object
+     */
+    EntryStructsUnion() = default;
+
+    /**
+     * @brief Returns the size in byte of the type + value
+     *
+     * @return size_t The type + value size in Bytes
+     */
+    size_t sizeBytes()
+    {
+        size_t returnVal = sizeof(TypesEnum);
+        switch (type)
+        {
+            case TypesEnum::COORDINATES:
+                returnVal += sizeof(Coordinates);
+                break;
+            case TypesEnum::UINT32:
+                returnVal += sizeof(uint32_t);
+                break;
+            case TypesEnum::FLOAT:
+                returnVal += sizeof(float);
+                break;
+            default:
+                break;
+        }
+
+        return returnVal;
+    }
+
+    /**
+     * @brief Gets from the TypeUnion the float value and returns it.
+     *
+     * @param outValue the float value saved into the union type
+     * @return True if the data type is correct w.r.t. the saved one
+     */
+    bool get(float& outValue)
+    {
+        if (type != TypesEnum::FLOAT)
+            return false;
+        outValue = value.float_type;
+        return true;
+    }
+
+    /**
+     * @brief Get from Union object the unsigned integer 32b value.
+     *
+     * @param outValue the uint32_t value saved into the union type
+     * @return True if the data type is correct w.r.t. the saved one
+     */
+    bool get(uint32_t& outValue)
+    {
+        if (type != TypesEnum::UINT32)
+            return false;
+        outValue = value.uint32_type;
+        return true;
+    }
+
+    /**
+     * @brief Get from Union object the coordinates value.
+     *
+     * @param outValue the coordinates value saved into the union type
+     * @return True if the data type is correct w.r.t. the saved one
+     */
+    bool get(Coordinates& outValue)
+    {
+        if (type != TypesEnum::COORDINATES)
+            return false;
+        outValue = value.coordinates_type;
+        return true;
+    }
+
+    /**
+     * @brief Set the Union object with its float value
+     *
+     * @param value The value to be set into the union type
+     * @return The created EntryStructUnion instance for such value and type
+     */
+    static EntryStructsUnion make(float value)
+    {
+        TypeUnion returnValue;
+        returnValue.float_type = value;
+        return EntryStructsUnion(returnValue, TypesEnum::FLOAT);
+    }
+
+    /**
+     * @brief Set the Union object with its unsigned 32bit integer value
+     *
+     * @param value The value to be set into the union type
+     * @return The created EntryStructUnion instance for such value and type
+     */
+    static EntryStructsUnion make(uint32_t value)
+    {
+        TypeUnion returnValue;
+        returnValue.uint32_type = value;
+        return EntryStructsUnion(returnValue, TypesEnum::UINT32);
+    }
+
+    /**
+     * @brief Set the Union object with its Coordinates value
+     *
+     * @param value The value to be set into the union type
+     * @return The created EntryStructUnion instance for such value and type
+     */
+    static EntryStructsUnion make(Coordinates value)
+    {
+        TypeUnion returnValue;
+        returnValue.coordinates_type = value;
+        return EntryStructsUnion(returnValue, TypesEnum::COORDINATES);
+    }
+
+    /**
+     * @brief Get the Value object
+     *
+     * @return TypeUnion the type of this entry
+     */
+    TypeUnion getValue() { return value; }
+
+    /**
+     * @brief Get the Type object
+     *
+     * @return TypeUnion the type of this entry
+     */
+    TypesEnum getType() { return type; }
+
+private:
+    TypeUnion value;
+    TypesEnum type;
+    /**
+     * @brief Constructor for the struct. It does take the right configuration
+     * struct for such entry configuration
+     */
+    EntryStructsUnion(TypeUnion value, TypesEnum typeId)
+        : value(value), type(typeId)
+    {
+    }
+};
+
+}  // namespace Boardcore
\ No newline at end of file
diff --git a/src/tests/catch/test-registry-frontend.cpp b/src/tests/catch/test-registry-frontend.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..aa989018e04395113c26baa2666d53c3ed0e7fea
--- /dev/null
+++ b/src/tests/catch/test-registry-frontend.cpp
@@ -0,0 +1,396 @@
+/* Copyright (c) 2023 Skyward Experimental Rocketry
+ * Author: Nicolò Caruso
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#ifdef STANDALONE_CATCH1_TEST
+#include "catch-tests-entry.cpp"
+#endif
+#include <utils/Registry/RegistryFrontend.h>
+
+#include <catch2/catch.hpp>
+#include <cstdint>
+
+using namespace Boardcore;
+
+/* Magic numbers for testing the set/get for each data type, they do not
+ * reflect the reals configuration ids and values in use! */
+static constexpr uint32_t TEST_VALUE_UINT32              = 30;
+static constexpr uint32_t TEST_VALUE_UINT32_2            = 32;
+static constexpr float TEST_VALUE_FLOAT                  = 1.45;
+static constexpr float TEST_VALUE_LATITUDE               = 45.50109;
+static constexpr float TEST_VALUE_LONGITUDE              = 9.15633;
+static constexpr uint32_t COORDINATE_ID                  = 8;
+static constexpr uint32_t DEPLOYMENT_ALTITUDE_ID         = 50;
+static constexpr uint32_t TARGET_COORDINATES_ID          = 1;
+static constexpr uint32_t VENTING_VALVE_ATOMIC_TIMING_ID = 49;
+static constexpr uint32_t ALGORITHM_ID                   = 128;
+static constexpr uint32_t IGNITION_TIME_ID               = 3;
+static constexpr uint32_t FLOAT_VALUE_ID                 = 13;
+
+/**
+ * @brief Test function for the forEach frontend function. Tests that the value
+ * and id are correctly passed to this function
+ *
+ * @param entryId The id of the configuration entry
+ * @param entry The EntryStructsUnion structure of the configuration entry
+ */
+void visitFunction(ConfigurationId entryId, EntryStructsUnion &entry)
+{
+    switch (entryId)
+    {
+        case FLOAT_VALUE_ID:
+            float valf;
+            entry.get(valf);
+            REQUIRE(valf == TEST_VALUE_FLOAT);
+            break;
+
+        case ALGORITHM_ID:
+            uint32_t valu32;
+            entry.get(valu32);
+            REQUIRE(valu32 == TEST_VALUE_UINT32);
+            break;
+
+        case COORDINATE_ID:
+            Coordinates coordinate;
+            entry.get(coordinate);
+            REQUIRE(coordinate.latitude == TEST_VALUE_LATITUDE);
+            REQUIRE(coordinate.longitude == TEST_VALUE_LONGITUDE);
+            break;
+
+        default:
+            REQUIRE(false);
+    }
+};
+
+/**
+ * @brief Fake backend to test the frontend without a real backend class that
+ * uses memory/storage
+ */
+class FakeBackend : public RegistryBackend
+{
+public:
+    int &startCount, &saveCount, &loadCount;
+
+    FakeBackend(int &startCount, int &saveCount, int &loadCount)
+        : startCount(startCount), saveCount(saveCount), loadCount(loadCount)
+    {
+    }
+
+    bool start() override
+    {
+        startCount++;
+        return true;
+    }
+
+    bool load(std::vector<uint8_t> &) override
+    {
+        loadCount++;
+        return true;
+    }
+
+    bool save(std::vector<uint8_t> &) override
+    {
+        saveCount++;
+        return true;
+    }
+};
+
+TEST_CASE(
+    "RegistryFrontend test - Set, Get, GetOrSetDefault, forEach, isEmpty, ")
+{
+    RegistryFrontend registry;
+    float floatValue;
+    uint32_t uint32Value;
+    Coordinates coordinatesValue{TEST_VALUE_LATITUDE, TEST_VALUE_LONGITUDE},
+        coordinatesGet;
+
+    // IS EMTPY
+
+    /* Check that the registry is first empty and see that isEntryConfigured
+     * works */
+    REQUIRE(registry.isEmpty());
+    REQUIRE_FALSE(registry.isEntryConfigured(ALGORITHM_ID));
+
+    // GET, SET, IS CONFIGURED
+
+    // Checks that there are effectively non-initialized entry configurations
+    REQUIRE(registry.getUnsafe(static_cast<uint32_t>(DEPLOYMENT_ALTITUDE_ID),
+                               floatValue) != RegistryError::OK);
+    REQUIRE(registry.getUnsafe(static_cast<uint32_t>(TARGET_COORDINATES_ID),
+                               coordinatesValue) != RegistryError::OK);
+    REQUIRE(registry.getUnsafe(
+                static_cast<uint32_t>(VENTING_VALVE_ATOMIC_TIMING_ID),
+                uint32Value) != RegistryError::OK);
+    REQUIRE(registry.getUnsafe(static_cast<uint32_t>(ALGORITHM_ID),
+                               uint32Value) != RegistryError::OK);
+
+    // Check set configuration results in right get
+    REQUIRE(registry.setUnsafe(static_cast<uint32_t>(ALGORITHM_ID),
+                               TEST_VALUE_UINT32) == RegistryError::OK);
+    REQUIRE(!registry.isEmpty());
+
+    uint32Value = 0;
+    REQUIRE(registry.isEntryConfigured(ALGORITHM_ID));
+    REQUIRE(registry.getUnsafe(ALGORITHM_ID, uint32Value) == RegistryError::OK);
+    REQUIRE(uint32Value == TEST_VALUE_UINT32);
+    uint32Value = 0;
+    REQUIRE(registry.setUnsafe(COORDINATE_ID, TEST_VALUE_UINT32_2) ==
+            RegistryError::OK);
+    REQUIRE(registry.getUnsafe(COORDINATE_ID, uint32Value) ==
+            RegistryError::OK);
+    REQUIRE(uint32Value == TEST_VALUE_UINT32_2);
+    uint32Value = 0;
+    REQUIRE(registry.setUnsafe(COORDINATE_ID, TEST_VALUE_UINT32) ==
+            RegistryError::OK);
+    REQUIRE(registry.getUnsafe(COORDINATE_ID, uint32Value) ==
+            RegistryError::OK);
+    REQUIRE(uint32Value == TEST_VALUE_UINT32);
+
+    /* Checks that get configuration is false if the type is incorrect w.r.t.
+     * the type of the set type */
+    REQUIRE_FALSE(registry.getUnsafe(COORDINATE_ID, floatValue) ==
+                  RegistryError::OK);
+
+    // GET OR SET DEFAULT TEST
+    uint32Value =
+        registry.getOrSetDefaultUnsafe(ALGORITHM_ID, TEST_VALUE_UINT32);
+    REQUIRE(uint32Value == TEST_VALUE_UINT32);
+
+    registry.clear();
+    REQUIRE(registry.getUnsafe(ALGORITHM_ID, uint32Value) ==
+            RegistryError::ENTRY_NOT_FOUND);
+    uint32Value =
+        registry.getOrSetDefaultUnsafe(ALGORITHM_ID, TEST_VALUE_UINT32);
+    REQUIRE(uint32Value == TEST_VALUE_UINT32);
+    REQUIRE(registry.getUnsafe(ALGORITHM_ID, uint32Value) == RegistryError::OK);
+    REQUIRE(uint32Value == TEST_VALUE_UINT32);
+
+    floatValue = 0;
+    REQUIRE(registry.getUnsafe(FLOAT_VALUE_ID, floatValue) ==
+            RegistryError::ENTRY_NOT_FOUND);
+    floatValue =
+        registry.getOrSetDefaultUnsafe(FLOAT_VALUE_ID, TEST_VALUE_FLOAT);
+    REQUIRE(floatValue == TEST_VALUE_FLOAT);
+    REQUIRE(registry.getUnsafe(FLOAT_VALUE_ID, floatValue) ==
+            RegistryError::OK);
+    REQUIRE(floatValue == TEST_VALUE_FLOAT);
+
+    coordinatesGet =
+        registry.getOrSetDefaultUnsafe(COORDINATE_ID, coordinatesValue);
+    REQUIRE(coordinatesGet.latitude == coordinatesValue.latitude);
+    REQUIRE(coordinatesGet.longitude == coordinatesValue.longitude);
+
+    // VISIT
+    registry.forEach(visitFunction);
+}
+
+TEST_CASE("RegistryFrontend test - Arm/Disarm test")
+{
+    RegistryFrontend registry;
+    uint32_t uint32Value = 0;
+    Coordinates coordinatesValue{TEST_VALUE_LATITUDE, TEST_VALUE_LONGITUDE},
+        coordinateGet;
+    float floatValue = 0;
+
+    REQUIRE(registry.setUnsafe(COORDINATE_ID, coordinatesValue) ==
+            RegistryError::OK);
+    registry.arm();
+
+    // If the registry is "armed" no set are allowed but gets are
+    REQUIRE(registry.setUnsafe(ALGORITHM_ID, TEST_VALUE_UINT32) !=
+            RegistryError::OK);
+    REQUIRE(registry.getUnsafe(ALGORITHM_ID, uint32Value) != RegistryError::OK);
+    REQUIRE(registry.getUnsafe(COORDINATE_ID, coordinateGet) ==
+            RegistryError::OK);
+    REQUIRE(coordinateGet.latitude == coordinatesValue.latitude);
+    REQUIRE(coordinateGet.longitude == coordinatesValue.longitude);
+    floatValue =
+        registry.getOrSetDefaultUnsafe(FLOAT_VALUE_ID, TEST_VALUE_FLOAT);
+    REQUIRE(floatValue == TEST_VALUE_FLOAT);
+    REQUIRE(registry.getUnsafe(FLOAT_VALUE_ID, floatValue) !=
+            RegistryError::OK);
+
+    // DISARM AND SET NEW ENTRIES
+
+    registry.disarm();
+    REQUIRE(registry.setUnsafe(ALGORITHM_ID, TEST_VALUE_UINT32) ==
+            RegistryError::OK);
+    REQUIRE(registry.getUnsafe(ALGORITHM_ID, uint32Value) == RegistryError::OK);
+    REQUIRE(uint32Value == TEST_VALUE_UINT32);
+    floatValue =
+        registry.getOrSetDefaultUnsafe(FLOAT_VALUE_ID, TEST_VALUE_FLOAT);
+    REQUIRE(floatValue == TEST_VALUE_FLOAT);
+    REQUIRE(registry.getUnsafe(FLOAT_VALUE_ID, floatValue) ==
+            RegistryError::OK);
+}
+
+TEST_CASE("RegistryFrontend test - serialization/deserialization test")
+{
+    RegistryFrontend registry;
+    Coordinates coordinatesValue{TEST_VALUE_LATITUDE, TEST_VALUE_LONGITUDE},
+        coordinateGet{0, 0};
+    uint32_t valueInt = 0;
+    float valueFloat  = 0;
+
+    registry.clear();
+    // FIRST SET OF THE CONFIGURATION
+    REQUIRE(registry.setUnsafe(COORDINATE_ID, coordinatesValue) ==
+            RegistryError::OK);
+    REQUIRE(registry.save() == RegistryError::OK);
+
+    // LOAD AND CHECK CONFIGURATION
+    REQUIRE(registry.save() == RegistryError::OK);
+    REQUIRE(registry.getUnsafe(COORDINATE_ID, coordinateGet) ==
+            RegistryError::OK);
+    REQUIRE(registry.load() == RegistryError::OK);
+    REQUIRE(registry.load() == RegistryError::OK);
+    REQUIRE(registry.save() == RegistryError::OK);
+    REQUIRE(registry.load() == RegistryError::OK);
+    REQUIRE(registry.getUnsafe(COORDINATE_ID, coordinateGet) ==
+            RegistryError::OK);
+    REQUIRE(coordinateGet.latitude == coordinatesValue.latitude);
+    REQUIRE(coordinateGet.longitude == coordinatesValue.longitude);
+
+    // SET OTHER DATA TYPES CONFIGURATIONS ENTRIES
+
+    REQUIRE(registry.setUnsafe((VENTING_VALVE_ATOMIC_TIMING_ID),
+                               TEST_VALUE_UINT32) == RegistryError::OK);
+    valueInt = 0;
+    REQUIRE(registry.save() == RegistryError::OK);
+    REQUIRE(registry.getUnsafe(VENTING_VALVE_ATOMIC_TIMING_ID, valueInt) ==
+            RegistryError::OK);
+    REQUIRE(valueInt == TEST_VALUE_UINT32);
+    REQUIRE(registry.setUnsafe(FLOAT_VALUE_ID, TEST_VALUE_FLOAT) ==
+            RegistryError::OK);
+    valueFloat = 0;
+
+    REQUIRE(registry.getUnsafe(VENTING_VALVE_ATOMIC_TIMING_ID, valueInt) ==
+            RegistryError::OK);
+    REQUIRE(valueInt == TEST_VALUE_UINT32);
+    REQUIRE(registry.getUnsafe(FLOAT_VALUE_ID, valueFloat) ==
+            RegistryError::OK);
+    REQUIRE(valueFloat == TEST_VALUE_FLOAT);
+
+    // SAVE AGAIN WITH ALL TYPES INSIDE CONFIGURATION
+
+    REQUIRE(registry.getUnsafe(COORDINATE_ID, coordinateGet) ==
+            RegistryError::OK);
+    REQUIRE(registry.getUnsafe(COORDINATE_ID, coordinateGet) ==
+            RegistryError::OK);
+    REQUIRE(registry.save() == RegistryError::OK);
+    REQUIRE(registry.getUnsafe(COORDINATE_ID, coordinateGet) ==
+            RegistryError::OK);
+    REQUIRE(registry.save() == RegistryError::OK);
+    REQUIRE(registry.getUnsafe(COORDINATE_ID, coordinateGet) ==
+            RegistryError::OK);
+    REQUIRE(registry.load() == RegistryError::OK);
+    REQUIRE(registry.getUnsafe(VENTING_VALVE_ATOMIC_TIMING_ID, valueInt) ==
+            RegistryError::OK);
+    REQUIRE(registry.getUnsafe(FLOAT_VALUE_ID, valueFloat) ==
+            RegistryError::OK);
+    REQUIRE(registry.getUnsafe(COORDINATE_ID, coordinateGet) ==
+            RegistryError::OK);
+
+    registry.save();
+    registry.save();
+    registry.save();
+    registry.save();
+    registry.save();
+    registry.save();
+    registry.load();
+
+    REQUIRE(registry.getUnsafe(COORDINATE_ID, coordinateGet) ==
+            RegistryError::OK);
+
+    registry.save();
+    REQUIRE(registry.load() == RegistryError::OK);
+    registry.save();
+    REQUIRE(registry.load() == RegistryError::OK);
+    registry.save();
+    REQUIRE(registry.load() == RegistryError::OK);
+    REQUIRE(registry.load() == RegistryError::OK);
+    REQUIRE(registry.load() == RegistryError::OK);
+    REQUIRE(registry.load() == RegistryError::OK);
+
+    REQUIRE(registry.getUnsafe(COORDINATE_ID, coordinateGet) ==
+            RegistryError::OK);
+    REQUIRE(registry.getUnsafe(VENTING_VALVE_ATOMIC_TIMING_ID, valueInt) ==
+            RegistryError::OK);
+    REQUIRE(registry.getUnsafe(FLOAT_VALUE_ID, valueFloat) ==
+            RegistryError::OK);
+    REQUIRE(registry.getUnsafe(COORDINATE_ID, coordinateGet) ==
+            RegistryError::OK);
+
+    // CHECK AFTER RELOAD
+
+    coordinateGet.latitude  = 0;
+    coordinateGet.longitude = 0;
+    REQUIRE(registry.getUnsafe(COORDINATE_ID, coordinateGet) ==
+            RegistryError::OK);
+    REQUIRE(coordinateGet.latitude == coordinatesValue.latitude);
+    REQUIRE(coordinateGet.longitude == coordinatesValue.longitude);
+
+    valueInt = 0;
+    REQUIRE(registry.getUnsafe(VENTING_VALVE_ATOMIC_TIMING_ID, valueInt) ==
+            RegistryError::OK);
+    REQUIRE(valueInt == TEST_VALUE_UINT32);
+
+    valueFloat = 0;
+    REQUIRE(registry.getUnsafe(FLOAT_VALUE_ID, valueFloat) ==
+            RegistryError::OK);
+    REQUIRE(valueFloat == TEST_VALUE_FLOAT);
+
+    // CANCEL CONFIGURATION
+
+    registry.clear();
+    REQUIRE(registry.getUnsafe(COORDINATE_ID, coordinateGet) !=
+            RegistryError::OK);
+    REQUIRE(registry.getUnsafe(VENTING_VALVE_ATOMIC_TIMING_ID, valueInt) !=
+            RegistryError::OK);
+    REQUIRE(registry.getUnsafe(FLOAT_VALUE_ID, valueFloat) !=
+            RegistryError::OK);
+}
+
+TEST_CASE("RegistryFrontend test - Backend test")
+{
+    int startCount = 0, saveCount = 0, loadCount = 0;
+
+    RegistryFrontend registry(
+        std::make_unique<FakeBackend>(startCount, saveCount, loadCount));
+
+    REQUIRE(startCount == 0);
+    REQUIRE(saveCount == 0);
+    REQUIRE(loadCount == 0);
+
+    REQUIRE(registry.start() == RegistryError::OK);
+    REQUIRE(startCount == 1);
+    REQUIRE(saveCount == 0);
+    REQUIRE(loadCount == 0);
+
+    REQUIRE(registry.save() == RegistryError::OK);
+    REQUIRE(startCount == 1);
+    REQUIRE(saveCount == 1);
+    REQUIRE(loadCount == 0);
+
+    REQUIRE(registry.load() == RegistryError::OK);
+    REQUIRE(startCount == 1);
+    REQUIRE(saveCount == 1);
+    REQUIRE(loadCount == 1);
+}
\ No newline at end of file