-
Notifications
You must be signed in to change notification settings - Fork 8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mmyster/feature/config kit #598
Changes from all commits
6b13e6e
a865c4d
8e1ecbb
b48cae8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
# Leka - LekaOS | ||
# Copyright 2022 APF France handicap | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
add_library(ConfigKit STATIC) | ||
|
||
target_include_directories(ConfigKit | ||
PUBLIC | ||
include | ||
) | ||
|
||
target_sources(ConfigKit | ||
PRIVATE | ||
source/Config.cpp | ||
) | ||
|
||
target_link_libraries(ConfigKit | ||
mbed-os | ||
FileManagerKit | ||
) | ||
|
||
if (${CMAKE_PROJECT_NAME} STREQUAL "LekaOSUnitTests") | ||
|
||
leka_unit_tests_sources( | ||
tests/Config_test.cpp | ||
) | ||
|
||
endif() |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// Leka - LekaOS | ||
// Copyright 2022 APF France handicap | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#pragma once | ||
|
||
#include <filesystem> | ||
|
||
namespace leka { | ||
|
||
struct Config { | ||
public: | ||
explicit Config(const std::filesystem::path &path, uint8_t default_value = 0xFF) | ||
: _path(_default_parent_path / path), _default_value(default_value) | ||
{ | ||
// nothing to do | ||
} | ||
|
||
[[nodiscard]] auto path() const -> std::filesystem::path { return _path; } | ||
[[nodiscard]] auto default_value() const -> uint8_t { return _default_value; } | ||
|
||
private: | ||
const std::filesystem::path _default_parent_path = "/fs/conf"; | ||
const std::filesystem::path _path; | ||
const uint8_t _default_value; | ||
}; | ||
|
||
} // namespace leka |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// Leka - LekaOS | ||
// Copyright 2022 APF France handicap | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#pragma once | ||
|
||
#include <filesystem> | ||
|
||
#include "Config.h" | ||
|
||
namespace leka { | ||
|
||
class ConfigKit | ||
{ | ||
public: | ||
explicit ConfigKit() = default; | ||
[[nodiscard]] auto read(Config const &config) const -> uint8_t; | ||
[[nodiscard]] auto write(Config const &config, uint8_t data) const -> bool; | ||
}; | ||
|
||
} // namespace leka |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
// Leka - LekaOS | ||
// Copyright 2022 APF France handicap | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#pragma once | ||
|
||
#include <filesystem> | ||
|
||
#include "ConfigKit.h" | ||
|
||
namespace leka::config::bootloader { | ||
|
||
inline const auto battery_level_hysteresis = Config {"bootloader_battery_level_hysteresis", 42}; | ||
|
||
} // namespace leka::config::bootloader |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
// Leka - LekaOS | ||
// Copyright 2022 APF France handicap | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#include "ConfigKit.h" | ||
#include "FileManagerKit.h" | ||
|
||
using namespace leka; | ||
|
||
auto ConfigKit::read(Config const &config) const -> uint8_t | ||
{ | ||
FileManagerKit::File file {config.path(), "r"}; | ||
|
||
if (!file.is_open()) { | ||
return config.default_value(); | ||
} | ||
|
||
auto data = std::array<uint8_t, 1> {}; | ||
file.read(data); | ||
|
||
return data.front(); | ||
} | ||
|
||
auto ConfigKit::write(Config const &config, uint8_t data) const -> bool | ||
{ | ||
FileManagerKit::File file {config.path(), "r+"}; | ||
|
||
if (!file.is_open()) { | ||
return false; | ||
} | ||
|
||
auto output = std::to_array<uint8_t>({data}); | ||
file.write(output); | ||
|
||
return true; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
// Leka - LekaOS | ||
// Copyright 2021 APF France handicap | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#include <array> | ||
#include <fstream> | ||
#include <iostream> | ||
#include <span> | ||
#include <string> | ||
|
||
#include "ConfigKit.h" | ||
#include "FileManagerKit.h" | ||
#include "LogKit.h" | ||
#include "gtest/gtest.h" | ||
#include "mocks/leka/File.h" | ||
|
||
using namespace leka; | ||
|
||
class ConfigTest : public ::testing::Test | ||
{ | ||
protected: | ||
// void SetUp() override {} | ||
// void TearDown() override {} | ||
|
||
auto spy_readConfigValue() -> uint8_t | ||
{ | ||
auto input_data = std::array<uint8_t, 1> {}; | ||
FileManagerKit::File file {config_path.c_str()}; | ||
file.read(input_data); | ||
file.close(); | ||
return input_data.front(); | ||
} | ||
|
||
void spy_writeConfigValue(uint8_t data) | ||
{ | ||
auto output_data = std::array<uint8_t, 1> {data}; | ||
FileManagerKit::File file {config_path.c_str(), "r+"}; | ||
file.write(output_data); | ||
file.close(); | ||
} | ||
|
||
void spy_touchConfigFile() | ||
{ | ||
FileManagerKit::File file {config_path.c_str(), "w"}; | ||
file.close(); | ||
} | ||
void spy_removeConfigFile() { std::remove(config_path.c_str()); } | ||
|
||
const std::filesystem::path config_path = "/tmp/test_config.conf"; | ||
}; | ||
|
||
TEST_F(ConfigTest, initializationConfigFullPath) | ||
{ | ||
const std::filesystem::path custom_full_path = "/tmp/test_config.conf"; | ||
Config config {custom_full_path}; | ||
ASSERT_NE(nullptr, &config); | ||
const std::filesystem::path expected_path = "/tmp/test_config.conf"; | ||
ASSERT_EQ(expected_path, config.path()); | ||
} | ||
|
||
TEST_F(ConfigTest, initializationWithDefaultParentPathConfig) | ||
{ | ||
const std::filesystem::path custom_filename = "test_config.conf"; | ||
Config config {custom_filename}; | ||
ASSERT_NE(nullptr, &config); | ||
const std::filesystem::path expected_path = "/fs/conf/test_config.conf"; | ||
ASSERT_EQ(expected_path, config.path()); | ||
} | ||
|
||
TEST_F(ConfigTest, initializationConfigKit) | ||
{ | ||
auto configkit = ConfigKit(); | ||
ASSERT_NE(nullptr, &configkit); | ||
} | ||
|
||
TEST_F(ConfigTest, readNotOpenFile) | ||
{ | ||
Config config {config_path}; | ||
auto configkit = ConfigKit(); | ||
spy_removeConfigFile(); | ||
auto data = configkit.read(config); | ||
ASSERT_EQ(config.default_value(), data); | ||
} | ||
|
||
TEST_F(ConfigTest, readEmptyFile) | ||
{ | ||
Config config {config_path}; | ||
auto configkit = ConfigKit(); | ||
spy_removeConfigFile(); | ||
spy_touchConfigFile(); | ||
auto data = configkit.read(config); | ||
ASSERT_EQ(0, data); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Si le fichier ne contient aucun byte de donnée, c'est There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. c'est une bonne question ! est-ce que pas de valeur == 0 ou == default_value. je pencherai pour default_value puisque pas de fichier ou rien dedans c'est un peu la même chose --> la config n'existe pas vraiment There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Valeur = 0 Rien n'est lue effectivement mais la variable |
||
} | ||
|
||
TEST_F(ConfigTest, read) | ||
{ | ||
Config config {config_path}; | ||
auto configkit = ConfigKit(); | ||
spy_writeConfigValue(5); | ||
auto data = configkit.read(config); | ||
ASSERT_EQ(5, data); | ||
} | ||
|
||
TEST_F(ConfigTest, writeNotOpenFile) | ||
{ | ||
Config config {config_path}; | ||
auto configkit = ConfigKit(); | ||
spy_removeConfigFile(); | ||
auto write = configkit.write(config, 5); | ||
ASSERT_FALSE(write); | ||
} | ||
|
||
TEST_F(ConfigTest, write) | ||
{ | ||
Config config {config_path}; | ||
auto configkit = ConfigKit(); | ||
spy_touchConfigFile(); | ||
auto write = configkit.write(config, 5); | ||
ASSERT_TRUE(write); | ||
auto data = spy_readConfigValue(); | ||
ASSERT_EQ(5, data); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
# Leka - LekaOS | ||
# Copyright 2022 APF France handicap | ||
# SPDX-License-Identifier: Apache-2.0 | ||
|
||
add_mbed_executable(spike_lk_config_kit) | ||
|
||
target_include_directories(spike_lk_config_kit | ||
PRIVATE | ||
. | ||
) | ||
|
||
target_sources(spike_lk_config_kit | ||
PRIVATE | ||
main.cpp | ||
) | ||
|
||
target_link_libraries(spike_lk_config_kit | ||
FileManagerKit | ||
ConfigKit | ||
) | ||
|
||
target_link_custom_leka_targets(spike_lk_config_kit) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
// Leka - LekaOS | ||
// Copyright 2022 APF France handicap | ||
// SPDX-License-Identifier: Apache-2.0 | ||
|
||
#include <cstddef> | ||
#include <filesystem> | ||
|
||
#include "drivers/BufferedSerial.h" | ||
#include "rtos/ThisThread.h" | ||
|
||
#include "ConfigKit.h" | ||
#include "ConfigList.h" | ||
#include "FATFileSystem.h" | ||
#include "FileManagerKit.h" | ||
#include "HelloWorld.h" | ||
#include "LogKit.h" | ||
#include "SDBlockDevice.h" | ||
|
||
using namespace leka; | ||
using namespace std::chrono_literals; | ||
|
||
SDBlockDevice sd_blockdevice(SD_SPI_MOSI, SD_SPI_MISO, SD_SPI_SCK); | ||
FATFileSystem fatfs("fs"); | ||
|
||
auto configkit = ConfigKit(); | ||
|
||
void initializeSD() | ||
{ | ||
constexpr auto default_sd_blockdevice_frequency = uint64_t {25'000'000}; | ||
|
||
sd_blockdevice.init(); | ||
sd_blockdevice.frequency(default_sd_blockdevice_frequency); | ||
|
||
fatfs.mount(&sd_blockdevice); | ||
} | ||
|
||
auto main() -> int | ||
{ | ||
logger::init(); | ||
|
||
log_info("Hello, World!\n\n"); | ||
|
||
auto start = rtos::Kernel::Clock::now(); | ||
|
||
auto hello = HelloWorld(); | ||
|
||
rtos::ThisThread::sleep_for(1s); | ||
|
||
hello.start(); | ||
|
||
initializeSD(); | ||
|
||
auto custom_data = uint8_t {0}; | ||
|
||
rtos::ThisThread::sleep_for(1s); | ||
|
||
while (true) { | ||
auto t = rtos::Kernel::Clock::now() - start; | ||
log_info("A message from your board %s --> \"%s\" at %i s", MBED_CONF_APP_TARGET_NAME, hello.world, | ||
int(t.count() / 1000)); | ||
|
||
++custom_data; | ||
if (auto write = configkit.write(config::bootloader::battery_level_hysteresis, custom_data); !write) { | ||
log_error("Fail to write in hysteresis config file"); | ||
return EXIT_FAILURE; | ||
} | ||
auto battery_level_hysteresis = configkit.read(config::bootloader::battery_level_hysteresis); | ||
log_info("Battery level hysteresis : %d", battery_level_hysteresis); | ||
rtos::ThisThread::sleep_for(10s); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pourquoi
touch
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
touch filename
c'est la commande pour créer un fichier sur unix