Skip to content

Commit

Permalink
Use statically allocated file buffer
Browse files Browse the repository at this point in the history
The normal lfs_file_open() uses malloc() to allocate the file buffer.
Since we do not want to use the heap, we use lfs_file_opencfg() and
provide a statically allocated buffer instead.
  • Loading branch information
PatrickKa committed Jun 20, 2024
1 parent a09c317 commit 83f4d0d
Show file tree
Hide file tree
Showing 6 changed files with 36 additions and 14 deletions.
5 changes: 3 additions & 2 deletions Sts1CobcSw/FileSystem/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
target_sources(Sts1CobcSw_FileSystem PRIVATE LfsWrapper.cpp)
target_link_libraries(Sts1CobcSw_FileSystem PUBLIC littlefs::littlefs etl::etl Sts1CobcSw_Outcome)
target_link_libraries(Sts1CobcSw_FileSystem PRIVATE Sts1CobcSw_Serial)
target_link_libraries(
Sts1CobcSw_FileSystem PUBLIC littlefs::littlefs etl::etl Sts1CobcSw_Outcome Sts1CobcSw_Serial
)

if(CMAKE_SYSTEM_NAME STREQUAL Generic)
target_sources(Sts1CobcSw_FileSystem PRIVATE FileSystem.cpp LfsFlash.cpp)
Expand Down
10 changes: 8 additions & 2 deletions Sts1CobcSw/FileSystem/LfsFlash.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include <rodos_no_using_namespace.h>

#include <algorithm>
#include <array>
#include <span>


Expand All @@ -27,9 +28,14 @@ auto Erase(lfs_config const * config, lfs_block_t blockNo) -> int;
auto Sync(lfs_config const * config) -> int;


auto readBuffer = flash::Page{};
auto readBuffer = std::array<Byte, lfsCacheSize>{};
auto programBuffer = decltype(readBuffer){};
auto lookaheadBuffer = flash::Page{};
auto lookaheadBuffer = std::array<Byte, 64>{}; // NOLINT(*magic-numbers)

// littlefs requires the lookaheadBuffer size to be a multiple of 8
static_assert(lookaheadBuffer.size() % 8 == 0); // NOLINT(*magic-numbers)
// littlefs requires the cacheSize to be a multiple of the read_size and prog_size, i.e., pageSize
static_assert(lfsCacheSize % flash::pageSize == 0);

lfs_config const lfsConfig = lfs_config{.context = nullptr,
.read = &Read,
Expand Down
9 changes: 7 additions & 2 deletions Sts1CobcSw/FileSystem/LfsRam.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,14 @@ constexpr auto sectorSize = 4 * 1024;
constexpr auto storageSize = 128 * 1024 * 1024;

auto storage = std::vector<Byte>();
auto readBuffer = std::array<Byte, pageSize>{};
auto readBuffer = std::array<Byte, lfsCacheSize>{};
auto programBuffer = decltype(readBuffer){};
auto lookaheadBuffer = std::array<Byte, pageSize>{};
auto lookaheadBuffer = std::array<Byte, 64>{}; // NOLINT(*magic-numbers)

// littlefs requires the lookaheadBuffer size to be a multiple of 8
static_assert(lookaheadBuffer.size() % 8 == 0); // NOLINT(*magic-numbers)
// littlefs requires the cacheSize to be a multiple of the read_size and prog_size, i.e., pageSize
static_assert(lfsCacheSize % pageSize == 0);

lfs_config const lfsConfig = lfs_config{.context = nullptr,
.read = &Read,
Expand Down
1 change: 1 addition & 0 deletions Sts1CobcSw/FileSystem/LfsStorageDevice.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

namespace sts1cobcsw::fs
{
inline constexpr auto lfsCacheSize = 256;
extern lfs_config const lfsConfig;


Expand Down
12 changes: 5 additions & 7 deletions Sts1CobcSw/FileSystem/LfsWrapper.cpp
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#include <Sts1CobcSw/FileSystem/LfsStorageDevice.hpp>
#include <Sts1CobcSw/FileSystem/LfsWrapper.hpp>
#include <Sts1CobcSw/Outcome/Outcome.hpp>

Expand Down Expand Up @@ -47,8 +46,7 @@ lfs_t lfs{};
auto Open(std::string_view path, int flags) -> Result<File>
{
auto file = File();
// TODO: Use lfs_file_opencfg() instead
auto error = lfs_file_open(&lfs, &file.lfsFile_, path.data(), flags);
auto error = lfs_file_opencfg(&lfs, &file.lfsFile_, path.data(), flags, &file.lfsFileConfig_);
if(error == 0)
{
file.path_ = Path(path.data(), path.size());
Expand All @@ -66,8 +64,8 @@ File::File(File && other) noexcept
{
return;
}
// TODO: Use lfs_file_opencfg() instead
auto error = lfs_file_open(&lfs, &lfsFile_, other.path_.c_str(), other.openFlags_);
auto error =
lfs_file_opencfg(&lfs, &lfsFile_, other.path_.c_str(), other.openFlags_, &lfsFileConfig_);
if(error == 0)
{
path_ = other.path_;
Expand All @@ -86,8 +84,8 @@ auto File::operator=(File && other) noexcept -> File &
// TODO: Use copy and swap idiom to prevent code duplication
if(this != &other and not other.path_.empty())
{
// TODO: Use lfs_file_opencfg() instead
auto error = lfs_file_open(&lfs, &lfsFile_, other.path_.c_str(), other.openFlags_);
auto error = lfs_file_opencfg(
&lfs, &lfsFile_, other.path_.c_str(), other.openFlags_, &lfsFileConfig_);
if(error == 0)
{
path_ = other.path_;
Expand Down
13 changes: 12 additions & 1 deletion Sts1CobcSw/FileSystem/LfsWrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,27 @@


#include <Sts1CobcSw/FileSystem/ErrorsAndResult.hpp>
#include <Sts1CobcSw/FileSystem/LfsStorageDevice.hpp>
#include <Sts1CobcSw/Serial/Byte.hpp>

#include <littlefs/lfs.h>

#include <etl/string.h>

#include <array>
#include <string_view>


namespace sts1cobcsw::fs
{
// TODO: Consider reducing this to a bit more than 20 = strlen("/programs/65536.zip") to save RAM
using Path = etl::string<LFS_NAME_MAX>;


// TODO: Get rid of this global variable or at least hide it in an internal namespace
extern lfs_t lfs;


class File;

[[nodiscard]] auto Mount() -> Result<void>;
Expand All @@ -33,6 +39,9 @@ class File
auto operator=(File && other) noexcept -> File &;
~File();

// TODO: Read() and Write() should be implemented like ReadFrom() and WriteTo() in Fram.hpp,
// including forwarding to functions in an internal namespace. This way we can move lfs back
// into the .cpp file.
template<typename T>
[[nodiscard]] auto Read(T * t) -> Result<int>;
template<typename T>
Expand All @@ -49,9 +58,11 @@ class File
Path path_ = "";
int openFlags_ = 0;
bool isOpen_ = false;
std::array<Byte, lfsCacheSize> buffer_ = {};
lfs_file_t lfsFile_ = {};
lfs_file_config lfsFileConfig_ = {.buffer = buffer_.data()};
};
}


#include <Sts1CobcSw/FileSystem/LfsWrapper.ipp> // IWYU pragma: keep
#include <Sts1CobcSw/FileSystem/LfsWrapper.ipp> // IWYU pragma: keep

0 comments on commit 83f4d0d

Please sign in to comment.