Adding NVS to project

This commit is contained in:
2025-01-01 21:15:01 +01:00
parent dd9f59e418
commit 968d078c07
19 changed files with 812 additions and 28 deletions
+5
View File
@@ -0,0 +1,5 @@
idf_component_register(
SRC_DIRS "src"
INCLUDE_DIRS "include"
REQUIRES project_bases nvs_flash esp_common
)
@@ -0,0 +1,38 @@
/**
* @file nvsFunctions.hpp
* @author Gustice
* @brief NVS-Diagnosis utility
*
* @copyright Copyright (c) 2024
*/
#pragma once
#include <string>
class NvsApi {
public:
/// @brief Init and mount file system
/// @param mount rooted SubType of partition eg "nvs"
static void init(std::string mount = std::string{"nvs"});
/// @brief Get instance, ensure initialization
/// @param mount rooted SubType of partition eg "nvs"
/// @return Instance reference
static NvsApi &getInstance(std::string mount = std::string{"nvs"});
void setValue(const std::string &key, const std::string &value);
std::string getValue(const std::string &key);
// Disable move and assignment
NvsApi(NvsApi &other) = delete;
void operator=(const NvsApi &) = delete;
protected:
NvsApi(std::string mount);
~NvsApi();
private:
static NvsApi *_instance;
const std::string _mountingPoint;
};
+41
View File
@@ -0,0 +1,41 @@
/**
* @file nvsDefines.hpp
* @author Gustice
* @brief Defines and record types
*
* @copyright Copyright (c) 2024
*/
#pragma once
#include "nvs.h"
#include <array>
#include <map>
#include <string>
#include <tuple>
static std::tuple<
std::map<nvs_type_t, const char *>,
std::map<std::string, nvs_type_t>>
CreateNvsDictionaries() {
std::array<std::pair<nvs_type_t, const char *>, 11> defines{
{{NVS_TYPE_I8, "i8"},
{NVS_TYPE_U8, "u8"},
{NVS_TYPE_U16, "u16"},
{NVS_TYPE_I16, "i16"},
{NVS_TYPE_U32, "u32"},
{NVS_TYPE_I32, "i32"},
{NVS_TYPE_U64, "u64"},
{NVS_TYPE_I64, "i64"},
{NVS_TYPE_STR, "str"},
{NVS_TYPE_BLOB, "blob"},
{NVS_TYPE_ANY, "any"}}};
std::map<nvs_type_t, const char *> k2s;
std::map<std::string, nvs_type_t> s2k;
for (auto &&e : defines) {
k2s.emplace(e.first, e.second);
s2k.emplace(e.second, e.first);
}
return {k2s, s2k};
}
+316
View File
@@ -0,0 +1,316 @@
/**
* @file cmd_nvs.cpp
* @author Gustice
* @brief NVS-Diagnosis utility (derived from ESP-IDF Console-Example)
*
* @copyright Copyright (c) 2024
*/
#include "nvsFunctions.hpp"
#include "esp_err.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "nvs.h"
#include "nvsIo.hpp"
#include "nvs_flash.h"
#include <errno.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "nvsDefines.hpp"
static void initializeNvs() {
esp_err_t err = nvs_flash_init();
if (err == ESP_ERR_NVS_NO_FREE_PAGES || err == ESP_ERR_NVS_NEW_VERSION_FOUND) {
// 1.OTA app partition table has a smaller NVS partition size than the non-OTA
// partition table. This size mismatch may cause NVS initialization to fail.
// 2.NVS partition contains data in new format and cannot be recognized by this version of code.
// If this happens, we erase NVS partition and initialize NVS again.
ESP_ERROR_CHECK(nvs_flash_erase());
err = nvs_flash_init();
}
ESP_ERROR_CHECK(err);
}
NvsApi *NvsApi::_instance = nullptr;
NvsApi::NvsApi(std::string mount) : _mountingPoint(mount) {
initializeNvs();
}
NvsApi::~NvsApi() {
}
NvsApi &NvsApi::getInstance(std::string mount) {
if (_instance == nullptr) {
init(mount);
}
return *_instance;
}
void NvsApi::init(std::string mount) {
if (_instance != nullptr) {
return;
}
_instance = new NvsApi(mount);
}
const auto [TypeStrMap, StrTypeMap] = CreateNvsDictionaries();
static char activeNameSpace[16] = "storage";
static const char *TAG = "NVS";
static nvs_type_t confStr2Type(const char *type) {
if (auto search = StrTypeMap.find(type); search != StrTypeMap.end()) {
return search->second;
}
ESP_LOGW(TAG, "type '%s' not found", type);
return NVS_TYPE_ANY;
}
static const char *confType2Str(nvs_type_t type) {
if (auto search = TypeStrMap.find(type); search != TypeStrMap.end()) {
return search->second;
}
ESP_LOGW(TAG, "type %d not found", type);
return "Unknown";
}
struct SetArgs {
struct arg_str *key;
struct arg_str *type;
struct arg_str *value;
struct arg_end *end;
};
struct GetArgs {
struct arg_str *key;
struct arg_str *type;
struct arg_end *end;
};
struct EraseArgs {
struct arg_str *key;
struct arg_end *end;
};
struct EraseNameSpaceArgs {
struct arg_str *nameSpace;
struct arg_end *end;
};
struct NameSpaceArgs {
struct arg_str *nameSpace;
struct arg_end *end;
};
struct ListArgs {
struct arg_str *partition;
struct arg_str *nameSpace;
struct arg_str *type;
struct arg_end *end;
};
static esp_err_t setValueInNvs(const char *key, const char *strType, const char *strValue) {
nvs_type_t type = confStr2Type(strType);
if (type == NVS_TYPE_ANY) {
ESP_LOGE(TAG, "Type '%s' is undefined", strType);
return ESP_ERR_NVS_TYPE_MISMATCH;
}
try {
NvsIo nvs(activeNameSpace, NVS_READWRITE);
esp_err_t err = ESP_FAIL;
if (type == NVS_TYPE_I8) {
err = nvs.setValueByStr<int8_t>(key, strValue);
} else if (type == NVS_TYPE_U8) {
err = nvs.setValueByStr<uint8_t>(key, strValue);
} else if (type == NVS_TYPE_I16) {
err = nvs.setValueByStr<int16_t>(key, strValue);
} else if (type == NVS_TYPE_U16) {
err = nvs.setValueByStr<uint16_t>(key, strValue);
} else if (type == NVS_TYPE_I32) {
err = nvs.setValueByStr<int32_t>(key, strValue);
} else if (type == NVS_TYPE_U32) {
err = nvs.setValueByStr<uint32_t>(key, strValue);
} else if (type == NVS_TYPE_I64) {
err = nvs.setValueByStr<int64_t>(key, strValue);
} else if (type == NVS_TYPE_U64) {
err = nvs.setValueByStr<uint64_t>(key, strValue);
} else if (type == NVS_TYPE_STR) {
err = nvs.setString(key, strValue);
} else if (type == NVS_TYPE_BLOB) {
err = nvs.setBlob(key, strValue);
}
if (err != ESP_OK) {
return err;
}
err = nvs.commit();
if (err == ESP_OK) {
ESP_LOGI(TAG, "Value stored under key '%s'", key);
}
return ESP_OK;
} catch (const std::exception &e) {
ESP_LOGE(TAG, "%s", e.what());
}
return ESP_FAIL;
}
void NvsApi::setValue(const std::string &key, const std::string &value) {
if (setValueInNvs(key.c_str(), "str", value.c_str()) != ESP_OK) {
ESP_LOGE(TAG, "setValue failed");
}
}
std::string NvsApi::getValue(const std::string &key) {
try {
NvsIo nvs(activeNameSpace, NVS_READONLY);
auto opt = nvs.getString(key.c_str());
auto value = opt.value();
return value;
} catch (const std::bad_optional_access &e) {
ESP_LOGE(TAG, "%s", "Value not defined");
} catch (const std::exception &e) {
ESP_LOGE(TAG, "%s", e.what());
}
return "";
}
static esp_err_t showValueFromNvs(const char *key, const char *strType) {
nvs_type_t type = confStr2Type(strType);
if (type == NVS_TYPE_ANY) {
ESP_LOGE(TAG, "Type '%s' is undefined", strType);
return ESP_ERR_NVS_TYPE_MISMATCH;
}
try {
NvsIo nvs(activeNameSpace, NVS_READONLY);
if (type == NVS_TYPE_I8) {
auto opt = nvs.getInt8(key);
printf("%d\n", opt.value());
} else if (type == NVS_TYPE_U8) {
auto opt = nvs.getUint8(key);
printf("%u\n", opt.value());
} else if (type == NVS_TYPE_I16) {
auto opt = nvs.getInt16(key);
printf("%u\n", opt.value());
} else if (type == NVS_TYPE_U16) {
auto opt = nvs.getUint16(key);
printf("%u\n", opt.value());
} else if (type == NVS_TYPE_I32) {
auto opt = nvs.getInt32(key);
printf("%" PRIi32 "\n", opt.value());
} else if (type == NVS_TYPE_U32) {
auto opt = nvs.getUint32(key);
printf("%" PRIu32 "\n", opt.value());
} else if (type == NVS_TYPE_I64) {
auto opt = nvs.getInt64(key);
printf("%lld\n", opt.value());
} else if (type == NVS_TYPE_U64) {
auto opt = nvs.getUint64(key);
printf("%llu\n", opt.value());
} else if (type == NVS_TYPE_STR) {
auto opt = nvs.getString(key);
printf("%s\n", opt.value().c_str());
} else if (type == NVS_TYPE_BLOB) {
auto opt = nvs.getBlob(key);
auto value = opt.value();
for (int i = 0; i < value.size(); i++) {
printf("%02x", value[i]);
}
printf("\n");
}
return ESP_OK;
} catch (const std::bad_optional_access &e) {
ESP_LOGE(TAG, "%s", "Value not defined");
} catch (const std::exception &e) {
ESP_LOGE(TAG, "%s", e.what());
}
return ESP_FAIL;
}
static esp_err_t erase(const char *key) {
try {
NvsIo nvs(activeNameSpace, NVS_READWRITE);
esp_err_t err = nvs.erase(key);
if (err != ESP_OK) {
return err;
}
err = nvs.commit();
if (err != ESP_OK) {
return err;
}
ESP_LOGI(TAG, "Value with key '%s' erased", key);
return ESP_OK;
} catch (const std::exception &e) {
ESP_LOGE(TAG, "%s", e.what());
}
return ESP_FAIL;
}
static esp_err_t eraseAllIn(const char *name) {
try {
NvsIo nvs(name, NVS_READWRITE);
esp_err_t err = nvs.clear();
if (err != ESP_OK) {
return err;
}
err = nvs.commit();
if (err != ESP_OK) {
return err;
}
ESP_LOGI(TAG, "Namespace '%s' was %s erased", name, (err == ESP_OK) ? "" : "not");
return ESP_OK;
} catch (const std::exception &e) {
ESP_LOGE(TAG, "%s", e.what());
}
return ESP_FAIL;
}
static int list(const char *part, const char *name, const char *strType) {
nvs_type_t type = confStr2Type(strType);
nvs_iterator_t it = NULL;
esp_err_t result = nvs_entry_find(part, NULL, type, &it);
if (result == ESP_ERR_NVS_NOT_FOUND) {
ESP_LOGE(TAG, "No such entry was found");
return 1;
}
if (result != ESP_OK) {
ESP_LOGE(TAG, "NVS error: %s", esp_err_to_name(result));
return 1;
}
do {
nvs_entry_info_t info;
nvs_entry_info(it, &info);
result = nvs_entry_next(&it);
if ((strlen(name) > 0) && (strcmp(info.namespace_name, name) != 0)) {
continue;
}
printf("namespace '%s', key '%s', type '%s' \n",
info.namespace_name, info.key, confType2Str(info.type));
} while (result == ESP_OK);
if (result != ESP_ERR_NVS_NOT_FOUND) { // the last iteration ran into an internal error
ESP_LOGE(TAG, "NVS error %s at current iteration, stopping.", esp_err_to_name(result));
return 1;
}
return 0;
}
+167
View File
@@ -0,0 +1,167 @@
/**
* @file nvsIo.cpp
* @author Gustice
* @brief Read-Write access to specific NVS partition
*
* @copyright Copyright (c) 2024
*/
#include "nvsIo.hpp"
#include "esp_err.h"
#include "esp_log.h"
#include <cstring>
#include <memory>
static const char *TAG = "NVS";
static esp_err_t storeBlob(nvs_handle_t nvs, const char *key, const char *str_values) {
uint8_t value;
size_t str_len = strlen(str_values);
size_t blob_len = str_len / 2;
if (str_len % 2) {
ESP_LOGE(TAG, "Blob data must contain even number of characters");
return ESP_ERR_NVS_TYPE_MISMATCH;
}
char *blob = (char *)malloc(blob_len);
if (blob == NULL) {
return ESP_ERR_NO_MEM;
}
for (int i = 0, j = 0; i < str_len; i++) {
char ch = str_values[i];
if (ch >= '0' && ch <= '9') {
value = ch - '0';
} else if (ch >= 'A' && ch <= 'F') {
value = ch - 'A' + 10;
} else if (ch >= 'a' && ch <= 'f') {
value = ch - 'a' + 10;
} else {
ESP_LOGE(TAG, "Blob data contain invalid character");
free(blob);
return ESP_ERR_NVS_TYPE_MISMATCH;
}
if (i & 1) {
blob[j++] += value;
} else {
blob[j] = value << 4;
}
}
esp_err_t err = nvs_set_blob(nvs, key, blob, blob_len);
free(blob);
if (err == ESP_OK) {
err = nvs_commit(nvs);
}
return err;
}
template <>
esp_err_t NvsIo::setValueByStr<int8_t>(const char *key, const char *strValue) {
int32_t value = strtol(strValue, NULL, 0);
if (value < INT8_MIN || value > INT8_MAX || errno == ERANGE) {
throw CoreException(ErrMsg_TooLong);
}
return setInt8(key, (int8_t)value);
}
template <>
esp_err_t NvsIo::setValueByStr<uint8_t>(const char *key, const char *strValue) {
uint32_t value = strtoul(strValue, NULL, 0);
if (value > UINT8_MAX || errno == ERANGE) {
throw CoreException(ErrMsg_TooLong);
}
return setUint8(key, (uint8_t)value);
}
template <>
esp_err_t NvsIo::setValueByStr<int16_t>(const char *key, const char *strValue) {
int32_t value = strtol(strValue, NULL, 0);
if (value < INT16_MIN || value > INT16_MAX || errno == ERANGE) {
throw CoreException(ErrMsg_TooLong);
}
return setInt16(key, (int16_t)value);
}
template <>
esp_err_t NvsIo::setValueByStr<uint16_t>(const char *key, const char *strValue) {
uint32_t value = strtoul(strValue, NULL, 0);
if (value > UINT16_MAX || errno == ERANGE) {
throw CoreException(ErrMsg_TooLong);
}
return setUint16(key, (uint16_t)value);
}
template <>
esp_err_t NvsIo::setValueByStr<int32_t>(const char *key, const char *strValue) {
int32_t value = strtol(strValue, NULL, 0);
if (errno == ERANGE) {
throw CoreException(ErrMsg_TooLong);
}
return setInt32(key, value);
}
template <>
esp_err_t NvsIo::setValueByStr<uint32_t>(const char *key, const char *strValue) {
uint32_t value = strtoul(strValue, NULL, 0);
if (errno == ERANGE) {
throw CoreException(ErrMsg_TooLong);
}
return setUint32(key, value);
}
template <>
esp_err_t NvsIo::setValueByStr<int64_t>(const char *key, const char *strValue) {
int64_t value = strtoll(strValue, NULL, 0);
if (errno == ERANGE) {
throw CoreException(ErrMsg_TooLong);
}
return setInt64(key, value);
}
template <>
esp_err_t NvsIo::setValueByStr<uint64_t>(const char *key, const char *strValue) {
uint64_t value = strtoull(strValue, NULL, 0);
if (errno == ERANGE) {
throw CoreException(ErrMsg_TooLong);
}
return setUint64(key, value);
}
esp_err_t NvsIo::setString(const char *key, const char *strValue) {
return nvs_set_str(_nvs, key, strValue);
}
esp_err_t NvsIo::setBlob(const char *key, const char *strValue) {
return storeBlob(_nvs, key, strValue);
}
std::optional<std::string> NvsIo::getString(const char *key) {
size_t len;
if (nvs_get_str(_nvs, key, NULL, &len) != ESP_OK) {
return {std::nullopt};
}
auto str = std::make_unique<char[]>(len);
if ((nvs_get_str(_nvs, key, str.get(), &len)) != ESP_OK) {
return {std::nullopt};
}
return {str.get()};
}
std::optional<std::vector<char>> NvsIo::getBlob(const char *key) {
size_t len;
if (nvs_get_blob(_nvs, key, NULL, &len) != ESP_OK) {
return {std::nullopt};
}
auto blob = std::make_unique<char[]>(len);
if (nvs_get_blob(_nvs, key, blob.get(), &len) != ESP_OK) {
return {std::nullopt};
}
std::vector<char> vec;
vec.reserve(len);
vec.insert(vec.end(), blob.get(), blob.get() + len);
return {vec};
}
+149
View File
@@ -0,0 +1,149 @@
/**
* @file nvsIo.hpp
* @author Gustice
* @brief Read-Write access to specific NVS partition
*
* @copyright Copyright (c) 2024
*/
#pragma once
#include "nvs.h"
#include "coreExcept.hpp"
#include <optional>
#include <string>
#include <vector>
class NvsIo {
const char *ErrMsg_TooLong = "Value is too long";
public:
NvsIo(const char *nameSpace, nvs_open_mode_t mode) {
if (nvs_open(nameSpace, mode, &_nvs) != ESP_OK) {
throw CoreException("Unable to open NVS");
}
}
~NvsIo() {
nvs_close(_nvs);
}
esp_err_t commit() {
return nvs_commit(_nvs);
}
template <typename T>
esp_err_t setValueByStr(const char *key, const char *strValue);
esp_err_t setInt8(const char *key, int8_t value) {
return nvs_set_i8(_nvs, key, value);
}
esp_err_t setUint8(const char *key, uint8_t value) {
return nvs_set_u8(_nvs, key, value);
}
esp_err_t setInt16(const char *key, int16_t value) {
return nvs_set_i16(_nvs, key, value);
}
esp_err_t setUint16(const char *key, uint16_t value) {
return nvs_set_u16(_nvs, key, value);
}
esp_err_t setInt32(const char *key, int32_t value) {
return nvs_set_i32(_nvs, key, value);
}
esp_err_t setUint32(const char *key, uint32_t value) {
return nvs_set_u32(_nvs, key, value);
}
esp_err_t setInt64(const char *key, int64_t value) {
return nvs_set_i64(_nvs, key, value);
}
esp_err_t setUint64(const char *key, uint64_t value) {
return nvs_set_u64(_nvs, key, value);
}
esp_err_t setString(const char *key, const char *strValue);
esp_err_t setBlob(const char *key, const char *strValue);
std::optional<int8_t> getInt8(const char *key) {
int8_t value;
if (nvs_get_i8(_nvs, key, &value) != ESP_OK) {
return {std::nullopt};
}
return {value};
}
std::optional<uint8_t> getUint8(const char *key) {
uint8_t value;
if (nvs_get_u8(_nvs, key, &value) != ESP_OK) {
return {std::nullopt};
}
return {value};
}
std::optional<int16_t> getInt16(const char *key) {
int16_t value;
if (nvs_get_i16(_nvs, key, &value) != ESP_OK) {
return {std::nullopt};
}
return {value};
}
std::optional<uint16_t> getUint16(const char *key) {
uint16_t value;
if (nvs_get_u16(_nvs, key, &value) != ESP_OK) {
return {std::nullopt};
}
return {value};
}
std::optional<int32_t> getInt32(const char *key) {
int32_t value;
if (nvs_get_i32(_nvs, key, &value) != ESP_OK) {
return {std::nullopt};
}
return {value};
}
std::optional<uint32_t> getUint32(const char *key) {
uint32_t value;
if (nvs_get_u32(_nvs, key, &value) != ESP_OK) {
return {std::nullopt};
}
return {value};
}
std::optional<int64_t> getInt64(const char *key) {
int64_t value;
if (nvs_get_i64(_nvs, key, &value) != ESP_OK) {
return {std::nullopt};
}
return {value};
}
std::optional<uint64_t> getUint64(const char *key) {
uint64_t value;
if (nvs_get_u64(_nvs, key, &value) != ESP_OK) {
return {std::nullopt};
}
return {value};
}
std::optional<std::string> getString(const char *key);
std::optional<std::vector<char>> getBlob(const char *key);
esp_err_t erase(const char *key) {
return nvs_erase_key(_nvs, key);
}
/// @brief Clear all entries in given namespace
esp_err_t clear() {
return nvs_erase_all(_nvs);
}
private:
nvs_handle_t _nvs;
};
template <>
esp_err_t NvsIo::setValueByStr<int8_t>(const char *key, const char *strValue);
template <>
esp_err_t NvsIo::setValueByStr<uint8_t>(const char *key, const char *strValue);
template <>
esp_err_t NvsIo::setValueByStr<int16_t>(const char *key, const char *strValue);
template <>
esp_err_t NvsIo::setValueByStr<uint16_t>(const char *key, const char *strValue);
template <>
esp_err_t NvsIo::setValueByStr<int32_t>(const char *key, const char *strValue);
template <>
esp_err_t NvsIo::setValueByStr<uint32_t>(const char *key, const char *strValue);
template <>
esp_err_t NvsIo::setValueByStr<int64_t>(const char *key, const char *strValue);
template <>
esp_err_t NvsIo::setValueByStr<uint64_t>(const char *key, const char *strValue);
+1 -1
View File
@@ -1,4 +1,4 @@
idf_component_register(
SRC_DIRS "src"
INCLUDE_DIRS "include"
INCLUDE_DIRS "include" "defines"
)
@@ -0,0 +1,43 @@
/**
* @file utils.hpp
* @author Gustice
* @brief Template
*
* @copyright Copyright (c) 2024
*/
#pragma once
#include <cassert>
#include <exception>
#include <cstdint>
/**
* @brief Base for constructs that allow only one concurrently active instance
*
* @tparam T
* @note needs a `T * T::SingleActive<T>::active{};` definition in source
*/
template <typename T>
class SingleActive {
static bool active;
public:
/// @brief Constructor, memorizes if already on instance was successfully build
SingleActive() {
if (active) {
throw "Instance already active";
}
assert(active == false && "Constructor my only be run if no instance active");
active = true;
}
/// @brief Destructor, clears memory of existing instance
~SingleActive() {
assert(active == true && "Destructor my only be run on active instance");
active = false;
}
// Disable move and assignment
SingleActive(SingleActive &other) = delete;
void operator=(const SingleActive &) = delete;
};
@@ -0,0 +1,25 @@
/**
* @file coreExcept.hpp
* @author Gustice
* @brief Template
*
* @copyright Copyright (c) 2024
*/
#pragma once
#include <exception>
/**
* @brief Simple exception
*/
class CoreException : public std::exception {
char const *Text;
public:
/// @brief Constructor with simple pointer to text
CoreException(char const *text) : Text(text) {
}
/// @brief error message getter
char const *what() const throw() override { return Text; }
};
@@ -13,21 +13,6 @@
#include <vector>
#include <cstdint>
/**
* @brief Simple exception
*/
class CoreException : public std::exception {
char const *Text;
public:
/// @brief Constructor with simple pointer to text
CoreException(char const *text) : Text(text) {
}
/// @brief error message getter
char const *what() const throw() override { return Text; }
};
/**
* @brief Common interface for character streams
*/
+9
View File
@@ -0,0 +1,9 @@
/**
* @file dummy.cpp
* @author Gustice
* @brief Silence toolchain
*
* @copyright Copyright (c) 2024
*/
#include "portBase.hpp"
-9
View File
@@ -1,9 +0,0 @@
/**
* @file utils.cpp
* @author Gustice
* @brief Implementation of utilities
*
* @copyright Copyright (c) 2024
*/
#include "utils.hpp"
+3 -1
View File
@@ -10,9 +10,11 @@
#include "esp_log.h"
#include "etherCommon.hpp"
#include "utils.hpp"
#include "coreExcept.hpp"
#include <functional>
#include <iostream>
#include <vector>
#include "simpleStreams.hpp"
/**
* @brief TCP-Socket wrapper for ESP-IDF socket implementation
+2 -1
View File
@@ -10,10 +10,11 @@
#include "Task.hpp"
#include "esp_log.h"
#include "etherCommon.hpp"
#include "utils.hpp"
#include "coreExcept.hpp"
#include <cstdarg>
#include <iostream>
#include <string>
#include "simpleStreams.hpp"
constexpr bool UDP_WITH_TIMEOUT = false;
+1 -1
View File
@@ -14,7 +14,7 @@
#include <esp_log.h>
#include <functional>
#include <memory>
#include "utils.hpp"
#include "simpleStreams.hpp"
/* Module configuration */
static constexpr int CLI_RX_BUFFER_SIZE = 64;
+4
View File
@@ -0,0 +1,4 @@
idf_component_register(
SRC_DIRS "src"
INCLUDE_DIRS "include"
)
+8
View File
@@ -0,0 +1,8 @@
/**
* @file dummy.cpp
* @author Gustice
* @brief Silence toolchain
*
* @copyright Copyright (c) 2024
*/