Skip to content

Commit 9a45139

Browse files
authored
Merge pull request #1 from 107-systems/reg-storage
Support permanent register value storage/retrieval via littlefs.
2 parents 963d95a + 7887259 commit 9a45139

File tree

10 files changed

+223
-10
lines changed

10 files changed

+223
-10
lines changed

.codespellrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
# See: https://github.com/codespell-project/codespell#using-a-config-file
33
[codespell]
44
# In the event of a false positive, add the problematic word, in all lowercase, to a comma-separated list here:
5-
ignore-words-list = wan,
5+
ignore-words-list = wan,wronly,
66
skip = ./.git,./.licenses,__pycache__,node_modules,./go.mod,./go.sum,./package-lock.json,./poetry.lock,./yarn.lock
77
builtin = clear,informal,en-GB_to_en-US
88
check-filenames =

.github/workflows/compile-examples.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ jobs:
2222
# Install the library from the local path.
2323
- source-path: ./
2424
- name: 107-Arduino-UniqueId
25+
- name: 107-Arduino-Cyphal
26+
- name: 107-Arduino-littlefs
2527
2628
strategy:
2729
fail-fast: false

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,3 @@
11
.idea/
2+
reg/
3+
uavcan/

keywords.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,20 @@
88

99
cyphal KEYWORD1
1010
support KEYWORD1
11+
platform KEYWORD1
12+
storage KEYWORD1
1113
UniqueId KEYWORD1
14+
KeyValueStorage_littlefs KEYWORD1
1215

1316
#######################################
1417
# Methods and Functions (KEYWORD2)
1518
#######################################
1619

1720
instance KEYWORD2
1821
value KEYWORD2
22+
get KEYWORD2
23+
put KEYWORD2
24+
drop KEYWORD2
1925

2026
#######################################
2127
# Constants (LITERAL1)

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ category=Other
88
url=https://github.com/107-systems/107-Arduino-Cyphal-Support
99
architectures=rp2040
1010
includes=107-Arduino-Cyphal-Support.h
11-
depends=107-Arduino-UniqueId
11+
depends=107-Arduino-UniqueId,107-Arduino-Cyphal,107-Arduino-littlefs

src/107-Arduino-Cyphal-Support.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,11 @@
55
* Contributors: https://github.com/107-systems/107-Arduino-Cyphal-Support/graphs/contributors.
66
*/
77

8-
#ifndef INC_107_ARDUINO_CYPHAL_SUPPORT_H_
9-
#define INC_107_ARDUINO_CYPHAL_SUPPORT_H_
8+
#pragma once
109

1110
/**************************************************************************************
1211
* INCLUDE
1312
**************************************************************************************/
1413

14+
#include "storage/storage.h"
1515
#include "uniqueid/uniqueid.h"
16-
17-
#endif /* INC_107_ARDUINO_CYPHAL_SUPPORT_H_ */
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
/**
2+
* This software is distributed under the terms of the MIT License.
3+
* Copyright (c) 2023 LXRobotics.
4+
* Author: Alexander Entinger <[email protected]>
5+
* Contributors: https://github.com/107-systems/107-Arduino-Cyphal-Support/graphs/contributors.
6+
*/
7+
8+
/**************************************************************************************
9+
* INCLUDE
10+
**************************************************************************************/
11+
12+
#include "kv_littlefs.h"
13+
14+
#if __GNUC__ >= 11
15+
16+
#include <map>
17+
#include <string>
18+
#include <variant>
19+
#include <sstream>
20+
21+
/**************************************************************************************
22+
* NAMESPACE
23+
**************************************************************************************/
24+
25+
namespace cyphal::support::platform::storage::littlefs
26+
{
27+
28+
/**************************************************************************************
29+
* PRIVATE FREE FUNCTIONS
30+
**************************************************************************************/
31+
32+
[[nodiscard]] static inline std::string toFilename(std::string_view const key)
33+
{
34+
auto const key_hash = std::hash<std::string_view>{}(key);
35+
std::stringstream key_filename;
36+
key_filename << key_hash;
37+
return key_filename.str();
38+
}
39+
40+
[[nodiscard]] static inline Error toError(::littlefs::Error const err)
41+
{
42+
static std::map<::littlefs::Error, Error> const LITTLEFS_TO_STORAGE_ERROR_MAP =
43+
{
44+
{::littlefs::Error::IO , Error::IO},
45+
{::littlefs::Error::CORRUPT , Error::Internal},
46+
{::littlefs::Error::NOENT , Error::Existence},
47+
{::littlefs::Error::EXIST , Error::Existence},
48+
{::littlefs::Error::NOTDIR , Error::Existence},
49+
{::littlefs::Error::ISDIR , Error::Existence},
50+
{::littlefs::Error::NOTEMPTY , Error::Existence},
51+
{::littlefs::Error::BADF , Error::Internal},
52+
{::littlefs::Error::FBIG , Error::Capacity},
53+
{::littlefs::Error::INVAL , Error::API},
54+
{::littlefs::Error::NOSPC , Error::Capacity},
55+
{::littlefs::Error::NOMEM , Error::Internal},
56+
{::littlefs::Error::NOATTR , Error::API},
57+
{::littlefs::Error::NAMETOOLONG , Error::API},
58+
{::littlefs::Error::NO_FD_ENTRY , Error::API},
59+
};
60+
61+
return LITTLEFS_TO_STORAGE_ERROR_MAP.at(err);
62+
}
63+
64+
/**************************************************************************************
65+
* CTOR/DTOR
66+
**************************************************************************************/
67+
68+
KeyValueStorage::KeyValueStorage(::littlefs::Filesystem & filesystem)
69+
: _filesystem{filesystem}
70+
{ }
71+
72+
/**************************************************************************************
73+
* PUBLIC MEMBER FUNCTIONS
74+
**************************************************************************************/
75+
76+
auto KeyValueStorage::get(const std::string_view key, const std::size_t size, void* const data) const
77+
-> std::variant<Error, std::size_t>
78+
{
79+
auto const rc_open = _filesystem.open(toFilename(key), ::littlefs::OpenFlag::RDONLY);
80+
if (const auto * const err = std::get_if<::littlefs::Error>(&rc_open))
81+
return toError(*err);
82+
83+
auto const file_hdl = std::get<::littlefs::FileHandle>(rc_open);
84+
85+
auto const rc_read = _filesystem.read(file_hdl, data, size);
86+
if (const auto * const err = std::get_if<::littlefs::Error>(&rc_read))
87+
{
88+
(void)_filesystem.close(file_hdl);
89+
return toError(*err);
90+
}
91+
92+
(void)_filesystem.close(file_hdl);
93+
94+
return std::get<size_t>(rc_read);
95+
}
96+
97+
auto KeyValueStorage::put(const std::string_view key, const std::size_t size, const void* const data)
98+
-> std::optional<Error>
99+
{
100+
auto const rc_open = _filesystem.open(toFilename(key), ::littlefs::OpenFlag::WRONLY | ::littlefs::OpenFlag::CREAT | ::littlefs::OpenFlag::TRUNC);
101+
if (const auto * const err = std::get_if<::littlefs::Error>(&rc_open))
102+
return toError(*err);
103+
104+
auto const file_hdl = std::get<::littlefs::FileHandle>(rc_open);
105+
106+
auto const rc_write = _filesystem.write(file_hdl, data, size);
107+
if (const auto * const err = std::get_if<::littlefs::Error>(&rc_write))
108+
{
109+
(void)_filesystem.close(file_hdl);
110+
return toError(*err);
111+
}
112+
113+
(void)_filesystem.close(file_hdl);
114+
115+
size_t const bytes_written = std::get<size_t>(rc_write);
116+
if (bytes_written != size)
117+
return Error::Capacity;
118+
119+
return std::nullopt;
120+
}
121+
122+
auto KeyValueStorage::drop(const std::string_view key) -> std::optional<Error>
123+
{
124+
if (auto const opt_err = _filesystem.remove(toFilename(key)); opt_err.has_value())
125+
return toError(opt_err.value());
126+
127+
return std::nullopt;
128+
}
129+
130+
/**************************************************************************************
131+
* NAMESPACE
132+
**************************************************************************************/
133+
134+
} /* cyphal::support::platform::storage::littlefs */
135+
136+
#endif /* __GNUC__ >= 11 */
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/**
2+
* This software is distributed under the terms of the MIT License.
3+
* Copyright (c) 2023 LXRobotics.
4+
* Author: Alexander Entinger <[email protected]>
5+
* Contributors: https://github.com/107-systems/107-Arduino-Cyphal-Support/graphs/contributors.
6+
*/
7+
8+
#pragma once
9+
10+
/**************************************************************************************
11+
* INCLUDE
12+
**************************************************************************************/
13+
14+
#include <107-Arduino-Cyphal.h>
15+
#include <107-Arduino-littlefs.h>
16+
17+
#if __GNUC__ >= 11
18+
19+
/**************************************************************************************
20+
* NAMESPACE
21+
**************************************************************************************/
22+
23+
namespace cyphal::support::platform::storage::littlefs
24+
{
25+
26+
/**************************************************************************************
27+
* CLASS DECLARATION
28+
**************************************************************************************/
29+
30+
class KeyValueStorage final : public interface::KeyValueStorage
31+
{
32+
private:
33+
::littlefs::Filesystem & _filesystem;
34+
35+
public:
36+
KeyValueStorage(::littlefs::Filesystem & filesystem);
37+
virtual ~KeyValueStorage() { }
38+
39+
/// The return value is the number of bytes read into the buffer or the error.
40+
[[nodiscard]] virtual auto get(const std::string_view key, const std::size_t size, void* const data) const
41+
-> std::variant<Error, std::size_t> override;
42+
43+
/// Existing data, if any, is replaced entirely. New file and its parent directories created implicitly.
44+
/// Either all or none of the data bytes are written.
45+
[[nodiscard]] virtual auto put(const std::string_view key, const std::size_t size, const void* const data)
46+
-> std::optional<Error> override;
47+
48+
/// Remove key. If the key does not exist, the existence error is returned.
49+
[[nodiscard]] virtual auto drop(const std::string_view key) -> std::optional<Error> override;
50+
};
51+
52+
/**************************************************************************************
53+
* NAMESPACE
54+
**************************************************************************************/
55+
56+
} /* cyphal::support::platform::storage::littlefs */
57+
58+
#endif /* __GNUC__ >= 11 */

src/storage/storage.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/**
2+
* This software is distributed under the terms of the MIT License.
3+
* Copyright (c) 2023 LXRobotics.
4+
* Author: Alexander Entinger <[email protected]>
5+
* Contributors: https://github.com/107-systems/107-Arduino-Cyphal-Support/graphs/contributors.
6+
*/
7+
8+
#pragma once
9+
10+
/**************************************************************************************
11+
* INCLUDE
12+
**************************************************************************************/
13+
14+
#include "kv_storage/littlefs/kv_littlefs.h"

src/uniqueid/uniqueid.h

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@
55
* Contributors: https://github.com/107-systems/107-Arduino-Cyphal-Support/graphs/contributors.
66
*/
77

8-
#ifndef INC_107_ARDUINO_CYPHAL_SUPPORT_UNIQUEID_H
9-
#define INC_107_ARDUINO_CYPHAL_SUPPORT_UNIQUEID_H
8+
#pragma once
109

1110
/**************************************************************************************
1211
* INCLUDE
@@ -32,5 +31,3 @@ class UniqueId : public impl::UniqueId16 { };
3231
**************************************************************************************/
3332

3433
} /* cyphal::support */
35-
36-
#endif /* INC_107_ARDUINO_CYPHAL_SUPPORT_UNIQUEID_H */

0 commit comments

Comments
 (0)