Skip to content

Commit

Permalink
Merge pull request #1 from 107-systems/reg-storage
Browse files Browse the repository at this point in the history
Support permanent register value storage/retrieval via littlefs.
  • Loading branch information
aentinger authored Apr 13, 2023
2 parents 963d95a + 7887259 commit 9a45139
Show file tree
Hide file tree
Showing 10 changed files with 223 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .codespellrc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# See: https://github.com/codespell-project/codespell#using-a-config-file
[codespell]
# In the event of a false positive, add the problematic word, in all lowercase, to a comma-separated list here:
ignore-words-list = wan,
ignore-words-list = wan,wronly,
skip = ./.git,./.licenses,__pycache__,node_modules,./go.mod,./go.sum,./package-lock.json,./poetry.lock,./yarn.lock
builtin = clear,informal,en-GB_to_en-US
check-filenames =
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/compile-examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ jobs:
# Install the library from the local path.
- source-path: ./
- name: 107-Arduino-UniqueId
- name: 107-Arduino-Cyphal
- name: 107-Arduino-littlefs
strategy:
fail-fast: false
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
.idea/
reg/
uavcan/
6 changes: 6 additions & 0 deletions keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,20 @@

cyphal KEYWORD1
support KEYWORD1
platform KEYWORD1
storage KEYWORD1
UniqueId KEYWORD1
KeyValueStorage_littlefs KEYWORD1

#######################################
# Methods and Functions (KEYWORD2)
#######################################

instance KEYWORD2
value KEYWORD2
get KEYWORD2
put KEYWORD2
drop KEYWORD2

#######################################
# Constants (LITERAL1)
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ category=Other
url=https://github.com/107-systems/107-Arduino-Cyphal-Support
architectures=rp2040
includes=107-Arduino-Cyphal-Support.h
depends=107-Arduino-UniqueId
depends=107-Arduino-UniqueId,107-Arduino-Cyphal,107-Arduino-littlefs
6 changes: 2 additions & 4 deletions src/107-Arduino-Cyphal-Support.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,11 @@
* Contributors: https://github.com/107-systems/107-Arduino-Cyphal-Support/graphs/contributors.
*/

#ifndef INC_107_ARDUINO_CYPHAL_SUPPORT_H_
#define INC_107_ARDUINO_CYPHAL_SUPPORT_H_
#pragma once

/**************************************************************************************
* INCLUDE
**************************************************************************************/

#include "storage/storage.h"
#include "uniqueid/uniqueid.h"

#endif /* INC_107_ARDUINO_CYPHAL_SUPPORT_H_ */
136 changes: 136 additions & 0 deletions src/storage/kv_storage/littlefs/kv_littlefs.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
/**
* This software is distributed under the terms of the MIT License.
* Copyright (c) 2023 LXRobotics.
* Author: Alexander Entinger <[email protected]>
* Contributors: https://github.com/107-systems/107-Arduino-Cyphal-Support/graphs/contributors.
*/

/**************************************************************************************
* INCLUDE
**************************************************************************************/

#include "kv_littlefs.h"

#if __GNUC__ >= 11

#include <map>
#include <string>
#include <variant>
#include <sstream>

/**************************************************************************************
* NAMESPACE
**************************************************************************************/

namespace cyphal::support::platform::storage::littlefs
{

/**************************************************************************************
* PRIVATE FREE FUNCTIONS
**************************************************************************************/

[[nodiscard]] static inline std::string toFilename(std::string_view const key)
{
auto const key_hash = std::hash<std::string_view>{}(key);
std::stringstream key_filename;
key_filename << key_hash;
return key_filename.str();
}

[[nodiscard]] static inline Error toError(::littlefs::Error const err)
{
static std::map<::littlefs::Error, Error> const LITTLEFS_TO_STORAGE_ERROR_MAP =
{
{::littlefs::Error::IO , Error::IO},
{::littlefs::Error::CORRUPT , Error::Internal},
{::littlefs::Error::NOENT , Error::Existence},
{::littlefs::Error::EXIST , Error::Existence},
{::littlefs::Error::NOTDIR , Error::Existence},
{::littlefs::Error::ISDIR , Error::Existence},
{::littlefs::Error::NOTEMPTY , Error::Existence},
{::littlefs::Error::BADF , Error::Internal},
{::littlefs::Error::FBIG , Error::Capacity},
{::littlefs::Error::INVAL , Error::API},
{::littlefs::Error::NOSPC , Error::Capacity},
{::littlefs::Error::NOMEM , Error::Internal},
{::littlefs::Error::NOATTR , Error::API},
{::littlefs::Error::NAMETOOLONG , Error::API},
{::littlefs::Error::NO_FD_ENTRY , Error::API},
};

return LITTLEFS_TO_STORAGE_ERROR_MAP.at(err);
}

/**************************************************************************************
* CTOR/DTOR
**************************************************************************************/

KeyValueStorage::KeyValueStorage(::littlefs::Filesystem & filesystem)
: _filesystem{filesystem}
{ }

/**************************************************************************************
* PUBLIC MEMBER FUNCTIONS
**************************************************************************************/

auto KeyValueStorage::get(const std::string_view key, const std::size_t size, void* const data) const
-> std::variant<Error, std::size_t>
{
auto const rc_open = _filesystem.open(toFilename(key), ::littlefs::OpenFlag::RDONLY);
if (const auto * const err = std::get_if<::littlefs::Error>(&rc_open))
return toError(*err);

auto const file_hdl = std::get<::littlefs::FileHandle>(rc_open);

auto const rc_read = _filesystem.read(file_hdl, data, size);
if (const auto * const err = std::get_if<::littlefs::Error>(&rc_read))
{
(void)_filesystem.close(file_hdl);
return toError(*err);
}

(void)_filesystem.close(file_hdl);

return std::get<size_t>(rc_read);
}

auto KeyValueStorage::put(const std::string_view key, const std::size_t size, const void* const data)
-> std::optional<Error>
{
auto const rc_open = _filesystem.open(toFilename(key), ::littlefs::OpenFlag::WRONLY | ::littlefs::OpenFlag::CREAT | ::littlefs::OpenFlag::TRUNC);
if (const auto * const err = std::get_if<::littlefs::Error>(&rc_open))
return toError(*err);

auto const file_hdl = std::get<::littlefs::FileHandle>(rc_open);

auto const rc_write = _filesystem.write(file_hdl, data, size);
if (const auto * const err = std::get_if<::littlefs::Error>(&rc_write))
{
(void)_filesystem.close(file_hdl);
return toError(*err);
}

(void)_filesystem.close(file_hdl);

size_t const bytes_written = std::get<size_t>(rc_write);
if (bytes_written != size)
return Error::Capacity;

return std::nullopt;
}

auto KeyValueStorage::drop(const std::string_view key) -> std::optional<Error>
{
if (auto const opt_err = _filesystem.remove(toFilename(key)); opt_err.has_value())
return toError(opt_err.value());

return std::nullopt;
}

/**************************************************************************************
* NAMESPACE
**************************************************************************************/

} /* cyphal::support::platform::storage::littlefs */

#endif /* __GNUC__ >= 11 */
58 changes: 58 additions & 0 deletions src/storage/kv_storage/littlefs/kv_littlefs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/**
* This software is distributed under the terms of the MIT License.
* Copyright (c) 2023 LXRobotics.
* Author: Alexander Entinger <[email protected]>
* Contributors: https://github.com/107-systems/107-Arduino-Cyphal-Support/graphs/contributors.
*/

#pragma once

/**************************************************************************************
* INCLUDE
**************************************************************************************/

#include <107-Arduino-Cyphal.h>
#include <107-Arduino-littlefs.h>

#if __GNUC__ >= 11

/**************************************************************************************
* NAMESPACE
**************************************************************************************/

namespace cyphal::support::platform::storage::littlefs
{

/**************************************************************************************
* CLASS DECLARATION
**************************************************************************************/

class KeyValueStorage final : public interface::KeyValueStorage
{
private:
::littlefs::Filesystem & _filesystem;

public:
KeyValueStorage(::littlefs::Filesystem & filesystem);
virtual ~KeyValueStorage() { }

/// The return value is the number of bytes read into the buffer or the error.
[[nodiscard]] virtual auto get(const std::string_view key, const std::size_t size, void* const data) const
-> std::variant<Error, std::size_t> override;

/// Existing data, if any, is replaced entirely. New file and its parent directories created implicitly.
/// Either all or none of the data bytes are written.
[[nodiscard]] virtual auto put(const std::string_view key, const std::size_t size, const void* const data)
-> std::optional<Error> override;

/// Remove key. If the key does not exist, the existence error is returned.
[[nodiscard]] virtual auto drop(const std::string_view key) -> std::optional<Error> override;
};

/**************************************************************************************
* NAMESPACE
**************************************************************************************/

} /* cyphal::support::platform::storage::littlefs */

#endif /* __GNUC__ >= 11 */
14 changes: 14 additions & 0 deletions src/storage/storage.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/**
* This software is distributed under the terms of the MIT License.
* Copyright (c) 2023 LXRobotics.
* Author: Alexander Entinger <[email protected]>
* Contributors: https://github.com/107-systems/107-Arduino-Cyphal-Support/graphs/contributors.
*/

#pragma once

/**************************************************************************************
* INCLUDE
**************************************************************************************/

#include "kv_storage/littlefs/kv_littlefs.h"
5 changes: 1 addition & 4 deletions src/uniqueid/uniqueid.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@
* Contributors: https://github.com/107-systems/107-Arduino-Cyphal-Support/graphs/contributors.
*/

#ifndef INC_107_ARDUINO_CYPHAL_SUPPORT_UNIQUEID_H
#define INC_107_ARDUINO_CYPHAL_SUPPORT_UNIQUEID_H
#pragma once

/**************************************************************************************
* INCLUDE
Expand All @@ -32,5 +31,3 @@ class UniqueId : public impl::UniqueId16 { };
**************************************************************************************/

} /* cyphal::support */

#endif /* INC_107_ARDUINO_CYPHAL_SUPPORT_UNIQUEID_H */

0 comments on commit 9a45139

Please sign in to comment.