SatNOGS-COMMS  4.1.0
A COMMS subsystem for CubeSats
Loading...
Searching...
No Matches
storage.hpp
Go to the documentation of this file.
1/*
2 * SatNOGS-COMMS MCU software
3 *
4 * Copyright (C) 2025, Libre Space Foundation <http://libre.space>
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * SPDX-License-Identifier: GNU General Public License v3.0 or later
20 */
21
22#pragma once
23
24#include <etl/string.h>
27#include <zephyr/fs/fs.h>
28#include <zephyr/kernel.h>
29
30namespace satnogs::comms
31{
32
34{
35public:
36 static constexpr size_t SECTOR_SIZE = CONFIG_EMMC_SECTOR_SIZE;
37
38 class file
39 {
40 public:
41 friend storage;
42 file(const etl::istring &path) : m_file{}
43 {
44 if (path.size() >= CONFIG_STORAGE_MAX_PATH_LEN) {
45 throw max_path_exception(__FILE__, __LINE__);
46 }
47
48 struct fs_dirent entry;
49
50 int rc = fs_stat(path.c_str(), &entry);
51 if (rc < 0 || entry.type != FS_DIR_ENTRY_FILE) {
52 throw read_exception(__FILE__, __LINE__);
53 }
54
55 fs_file_t_init(&m_file);
56
57 rc = fs_open(&m_file, path.c_str(), FS_O_READ);
58 if (rc < 0) {
59 throw fs_exception(__FILE__, __LINE__);
60 }
61 }
62
63 ~file() { fs_close(&m_file); }
64
65 private:
66 struct fs_file_t m_file;
67 };
68
70 {
71 public:
72 friend storage;
73 directory(const etl::istring &path)
74 {
75 fs_dir_t_init(&m_dir);
76
77 if (path.size() >= CONFIG_STORAGE_MAX_PATH_LEN) {
78 throw max_path_exception(__FILE__, __LINE__);
79 }
80
81 int rc = fs_opendir(&m_dir, path.c_str());
82 if (rc) {
83 throw open_dir_exception(__FILE__, __LINE__);
84 }
85 }
86
87 ~directory() { fs_closedir(&m_dir); }
88
89 private:
90 struct fs_dir_t m_dir;
91 };
92
93 static storage &
95 {
96 static storage instance;
97 return instance;
98 }
99
100 storage(storage const &) = delete;
101
102 void
103 operator=(storage const &) = delete;
104
105 void
106 enable(bool en);
107
108 bool
109 enabled() const;
110
111 bool
112 mounted() const;
113
114 void
116
118 get_dir() const;
119
120 bool
121 ready() const;
122
123 void
124 truncate(const etl::istring &path, size_t len);
125
126 void
127 mkdir(const etl::istring &path);
128
129 void
130 rm(const etl::istring &path);
131
132 void
133 rmdir(const etl::istring &path);
134
135 size_t
136 write(const etl::istring &path, const uint8_t *b, size_t len);
137
138 size_t
139 write(const etl::istring &path, const uint8_t *b, size_t len, size_t offset);
140
141 void
142 ls(const etl::istring &path, etl::istring &res);
143
144 bool
145 ls(directory &dir, fs_dirent &entry);
146
147 bool
148 is_file(const etl::istring &path);
149
150 bool
151 is_dir(const etl::istring &path);
152
153 uint64_t
154 du(const etl::istring &path);
155
156 size_t
157 read(const etl::istring &path, uint8_t *b, size_t len, size_t offset);
158
159 size_t
160 read(file &f, uint8_t *b, size_t len, size_t offset);
161
162 size_t
163 read(file &f, uint8_t *b, size_t len);
164
165 size_t
166 write_raw(const uint8_t *b, size_t start_sector, size_t len);
167
168 size_t
169 read_raw(uint8_t *b, size_t start_sector, size_t sectors);
170
171 void
172 erase_sectors(size_t start_sector, size_t sectors);
173
174 size_t
175 sectors_num() const;
176
177 float
178 utilization();
179
181 {
182 public:
183 open_dir_exception(const char *file_name, int line)
184 : exception(
185 exception::severity::MINOR, file_name, line,
186 error_msg{"Failed to open directory", "strgopend", ESTORAGE})
187 {
188 }
189 };
190
192 {
193 public:
194 delete_dir_exception(const char *file_name, int line)
195 : exception(exception::severity::MINOR, file_name, line,
196 error_msg{"Directory deletion did not complete", "strgdeld",
197 ESTORAGE})
198 {
199 }
200 };
201
203 {
204 public:
205 delete_file_exception(const char *file_name, int line)
206 : exception(
207 exception::severity::MINOR, file_name, line,
208 error_msg{"File deletion did not complete", "strgdelf", ESTORAGE})
209 {
210 }
211 };
212
214 {
215 public:
216 max_path_exception(const char *file_name, int line)
217 : exception(exception::severity::MINOR, file_name, line,
218 error_msg{"File path is too big", "strgpath", ESTORAGE})
219 {
220 }
221 };
222
224 {
225 public:
226 mount_exception(const char *file_name, int line, int err)
227 : exception(
228 exception::severity::MAJOR, file_name, line,
229 error_msg{"Failed to (un)mount storage device", "strgmnt", err})
230 {
231 }
232 };
233
235 {
236 public:
237 not_ready_exception(const char *file_name, int line)
238 : exception(
239 exception::severity::MINOR, file_name, line,
240 error_msg{"Storage device is not ready", "strgnotrdy", ESTORAGE})
241 {
242 }
243 };
244
246 {
247 public:
248 read_exception(const char *file_name, int line)
249 : exception(exception::severity::MINOR, file_name, line,
250 error_msg{"Read exception", "strgrd", ESTORAGE})
251 {
252 }
253 };
254
256 {
257 public:
258 fs_exception(const char *file_name, int line)
259 : exception(
260 exception::severity::MINOR, file_name, line,
261 error_msg{"Filesystem operation failed", "strgfs", ESTORAGE})
262 {
263 }
264 };
265
266private:
267 bool m_enabled;
268 bool m_mounted;
269 etl::string<CONFIG_STORAGE_MAX_PATH_LEN> m_pname;
270 mutable struct k_mutex m_mtx;
271
272 storage();
273
274 void
275 set_dir_priv(lib::emmc::dir d, bool mnt = false);
276
277 int
278 rm_priv(const etl::istring &path);
279
280 bool
281 ready_raw() const;
282};
283} // namespace satnogs::comms
A class representing error messages in the SatNOGS-COMMS system.
Definition exception.hpp:83
Exception base class.
Definition exception.hpp:63
severity
Severity levels of exceptions.
Definition exception.hpp:71
@ MINOR
Failure having minimal impact.
Definition exception.hpp:75
@ MAJOR
Failure causing minor mission degradation.
Definition exception.hpp:74
exception(severity sev, const char *file, int lineno, const error_msg &err_msg)
Constructor for the exception class.
delete_dir_exception(const char *file_name, int line)
Definition storage.hpp:194
delete_file_exception(const char *file_name, int line)
Definition storage.hpp:205
directory(const etl::istring &path)
Definition storage.hpp:73
file(const etl::istring &path)
Definition storage.hpp:42
fs_exception(const char *file_name, int line)
Definition storage.hpp:258
max_path_exception(const char *file_name, int line)
Definition storage.hpp:216
mount_exception(const char *file_name, int line, int err)
Definition storage.hpp:226
not_ready_exception(const char *file_name, int line)
Definition storage.hpp:237
open_dir_exception(const char *file_name, int line)
Definition storage.hpp:183
read_exception(const char *file_name, int line)
Definition storage.hpp:248
size_t read(const etl::istring &path, uint8_t *b, size_t len, size_t offset)
Reads from a file starting from specific offset.
Definition storage.cpp:730
void ls(const etl::istring &path, etl::istring &res)
Lists the contents of a directory.
Definition storage.cpp:624
void truncate(const etl::istring &path, size_t len)
Truncate a file by removing bytes from its end.
Definition storage.cpp:445
uint64_t du(const etl::istring &path)
Calculate the disk usage of a file or directory likewise the 'du' command of Linux.
Definition storage.cpp:562
size_t read_raw(uint8_t *b, size_t start_sector, size_t sectors)
Reads directly raw sectors from the eMMC, bypassing any filesystem.
Definition storage.cpp:855
bool enabled() const
Checks if the storage subsystem is enabled.
Definition storage.cpp:183
void rmdir(const etl::istring &path)
Removes a directory and all its contents.
Definition storage.cpp:329
float utilization()
Get eMMC storage utilization of the partition used by the MCU.
Definition storage.cpp:80
void mkdir(const etl::istring &path)
Creates a directory at the specified path.
Definition storage.cpp:248
bool ready() const
Checks if the storage subsystem is ready to accept filesystem operations for the MCU side.
Definition storage.cpp:234
void operator=(storage const &)=delete
size_t write_raw(const uint8_t *b, size_t start_sector, size_t len)
Writes raw bytes on the eMMC.
Definition storage.cpp:796
static storage & get_instance()
Definition storage.hpp:94
lib::emmc::dir get_dir() const
Get the direction of the eMMC.
Definition storage.cpp:218
size_t write(const etl::istring &path, const uint8_t *b, size_t len)
Writes data to a file.
Definition storage.cpp:395
size_t sectors_num() const
Returns the number of total sectors of the eMMC.
Definition storage.cpp:906
void erase_sectors(size_t start_sector, size_t sectors)
Erase a specific number of sectors.
Definition storage.cpp:887
void enable(bool en)
Enable or disable the storage subsystem.
Definition storage.cpp:125
bool is_file(const etl::istring &path)
Check if a path is a file.
Definition storage.cpp:692
bool mounted() const
Checks if the storage subsystem is mounted.
Definition storage.cpp:195
void rm(const etl::istring &path)
Removes a file from the filesystem.
Definition storage.cpp:295
bool is_dir(const etl::istring &path)
Check if a path is a directory.
Definition storage.cpp:714
static constexpr size_t SECTOR_SIZE
Definition storage.hpp:36
void set_dir(lib::emmc::dir d)
Set the direction of the eMMC.
Definition storage.cpp:206
storage(storage const &)=delete
#define ESTORAGE
Error on storage.
constexpr off_t offset
Definition settings.cpp:34