Skip to content

Commit

Permalink
Merge pull request #12 from SpaceTeam/cobc-fs
Browse files Browse the repository at this point in the history
COBC File System
  • Loading branch information
PatrickKa authored Nov 13, 2022
2 parents 9e63efb + 2ca5161 commit 7b333ce
Show file tree
Hide file tree
Showing 10 changed files with 400 additions and 9 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ include(cmake/custom-commands.cmake)
find_package_and_notify(etl)
find_package_and_notify(type_safe)
find_rodos()
if(CMAKE_SYSTEM_NAME STREQUAL Generic)
find_package_and_notify(littlefs)
endif()

# ---- Declare targets ----

Expand All @@ -30,6 +33,7 @@ add_program(HelloDummy)
#add_program(Heartbeat)

if(CMAKE_SYSTEM_NAME STREQUAL Generic)
add_library(Sts1CobcSw_FileSystem OBJECT)
add_library(Sts1CobcSw_Hal INTERFACE)
add_program(CobcSw)
endif()
Expand Down
1 change: 1 addition & 0 deletions Sts1CobcSw/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# TODO: Is this not redondant with the top level cmake that does not build libarrie depending on
# target system
if(CMAKE_SYSTEM_NAME STREQUAL Generic)
add_subdirectory(FileSystem)
add_subdirectory(Hal)
endif()
add_subdirectory(Periphery)
Expand Down
3 changes: 3 additions & 0 deletions Sts1CobcSw/FileSystem/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
target_sources(Sts1CobcSw_FileSystem PRIVATE FileSystem.cpp)
target_link_libraries(Sts1CobcSw_FileSystem PUBLIC littlefs::littlefs)
target_link_libraries(Sts1CobcSw_FileSystem PRIVATE Sts1CobcSw_Periphery Sts1CobcSw_Serial)
234 changes: 234 additions & 0 deletions Sts1CobcSw/FileSystem/FileSystem.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,234 @@
#include <Sts1CobcSw/FileSystem/FileSystem.hpp>
#include <Sts1CobcSw/Periphery/Flash.hpp>
#include <Sts1CobcSw/Serial/Byte.hpp>

#include <rodos_no_using_namespace.h>

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


namespace sts1cobcsw::fs
{
using periphery::flash::pageSize;
using serial::Byte;


// --- Private function declarations

auto Read(lfs_config const * config,
lfs_block_t blockNo,
lfs_off_t offset,
void * buffer,
lfs_size_t size) -> int;
auto Program(lfs_config const * config,
lfs_block_t blockNo,
lfs_off_t offset,
void const * buffer,
lfs_size_t size) -> int;
auto Erase(lfs_config const * config, lfs_block_t blockNo) -> int;
auto Sync(lfs_config const * config) -> int;


// --- Globals ---

auto readBuffer = std::array<serial::Byte, pageSize>{};
auto programBuffer = std::array<serial::Byte, pageSize>{};
auto lookaheadBuffer = std::array<serial::Byte, pageSize>{};

// TODO: Check if they need to be global
lfs_t lfs{};
lfs_file_t lfsFile{};
// TODO: Maybe add a conifg header to set things like NAME_MAX or whatever. That could safe a bit of
// RAM.
const lfs_config lfsConfig{.read = &Read,
.prog = &Program,
.erase = &Erase,
.sync = &Sync,

.read_size = pageSize,
.prog_size = pageSize,
.block_size = periphery::flash::sectorSize,
.block_count = periphery::flash::nSectors,
.block_cycles = 200,
.cache_size = pageSize,
.lookahead_size = pageSize,

.read_buffer = data(readBuffer),
.prog_buffer = data(programBuffer),
.lookahead_buffer = data(lookaheadBuffer)};


// --- Public function definitions

auto Initialize() -> void
{
[[maybe_unused]] auto errorCode = periphery::flash::Initialize();
}


auto Format() -> int
{
return lfs_format(&lfs, &lfsConfig);
}


// Must be called before using the file system
auto Mount() -> int
{
return lfs_mount(&lfs, &lfsConfig);
}


// TODO: This begs for a destructor
// Must be called to release all the resources of the file system
auto Unmount() -> int
{
return lfs_unmount(&lfs);
}


auto OpenFile(char const * path, int flags) -> int
{
return lfs_file_open(&lfs, &lfsFile, path, flags);
}


auto CloseFile() -> int
{
return lfs_file_close(&lfs, &lfsFile);
}


//! @brief Return the size of the currently open file.
auto FileSize() -> int
{
return lfs_file_size(&lfs, &lfsFile);
}


auto CreateDirectory(char const * path) -> int
{
return lfs_mkdir(&lfs, path);
}


//! @brief Remove a file or an empty directory.
auto Remove(char const * path) -> int
{
return lfs_remove(&lfs, path);
}


//! @brief List information (type, size, name) about the files under the given path.
auto Ls(char const * path) -> int
{
using RODOS::PRINTF;

PRINTF("$ ls %s\n", path);

auto directory = lfs_dir_t{};
int errorCode = lfs_dir_open(&lfs, &directory, path);
if(errorCode != 0)
{
return errorCode;
}

auto info = lfs_info{};
while(true)
{
int result = lfs_dir_read(&lfs, &directory, &info);
if(result < 0)
{
// An error occurred
return result;
}
if(result == 0)
{
// We are at the end of the directory
break;
}

switch(info.type)
{
case LFS_TYPE_REG:
{
PRINTF(" reg ");
break;
}
case LFS_TYPE_DIR:
{
PRINTF(" dir ");
break;
}
default:
{
PRINTF(" ? ");
break;
}
}

PRINTF(" %8d B %s\n", static_cast<int>(info.size), &(info.name[0]));
}

return lfs_dir_close(&lfs, &directory);
}


// --- Private function definitions

auto Read(lfs_config const * config,
lfs_block_t blockNo,
lfs_off_t offset,
void * buffer,
lfs_size_t size) -> int
{
// The following only works if read_size == pageSize
auto startAddress = blockNo * config->block_size + offset;
for(auto i = 0U; i < size; i += config->read_size)
{
auto page = periphery::flash::ReadPage(startAddress + i);
// NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-pointer-arithmetic)
std::copy(begin(page), end(page), (static_cast<Byte *>(buffer) + i));
}

return 0;
}


auto Program(lfs_config const * config,
lfs_block_t blockNo,
lfs_off_t offset,
void const * buffer,
lfs_size_t size) -> int
{
// The following only works if prog_size == pageSize
auto startAddress = blockNo * config->block_size + offset;
for(auto i = 0U; i < size; i += config->prog_size)
{
auto page = periphery::flash::Page{};
std::copy((static_cast<Byte const *>(buffer) + i), // NOLINT
(static_cast<Byte const *>(buffer) + i + config->prog_size), // NOLINT
begin(page));
periphery::flash::ProgramPage(startAddress + i, std::span(page));
periphery::flash::WaitWhileBusy();
}
return 0;
}


auto Erase(lfs_config const * config, lfs_block_t blockNo) -> int
{
periphery::flash::EraseSector(blockNo * config->block_size);
periphery::flash::WaitWhileBusy();
return 0;
}


auto Sync([[maybe_unused]] lfs_config const * config) -> int
{
periphery::flash::WaitWhileBusy();
return 0;
}
}
52 changes: 52 additions & 0 deletions Sts1CobcSw/FileSystem/FileSystem.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#pragma once


#include <littlefs/lfs.h>


namespace sts1cobcsw::fs
{
extern lfs_t lfs;
extern lfs_file_t lfsFile;
extern const lfs_config lfsConfig;

// Must be called once in a thread's init() function
auto Initialize() -> void;
auto Format() -> int;
auto Mount() -> int;
auto Unmount() -> int;

// File stuff
auto OpenFile(char const * path, int flags) -> int;
auto CloseFile() -> int;
auto FileSize() -> int;
template<typename T>
auto ReadFromFile(T * t) -> int;
template<typename T>
auto WriteToFile(T const & t) -> int;

// Directory stuff
auto CreateDirectory(char const * path) -> int;

// Other stuff
auto Remove(char const * path) -> int;
auto Ls(char const * path) -> int;
// TODO: Implement cat
// TODO: Implement simple hexdump


// --- Function template definitions ---

template<typename T>
inline auto ReadFromFile(T * t) -> int
{
return lfs_file_read(&lfs, &lfsFile, t, sizeof(T));
}


template<typename T>
inline auto WriteToFile(T const & t) -> int
{
return lfs_file_write(&lfs, &lfsFile, &t, sizeof(T));
}
}
12 changes: 8 additions & 4 deletions Sts1CobcSw/Periphery/Flash.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,14 @@

namespace sts1cobcsw::periphery::flash
{
[[maybe_unused]] constexpr std::size_t pageSize = 256; // bytes
[[maybe_unused]] constexpr std::size_t sectorSize = 4 * 1024; // bytes
[[maybe_unused]] constexpr std::size_t smallBlockSize = 32 * 1024; // bytes
[[maybe_unused]] constexpr std::size_t largeBlockSize = 64 * 1024; // bytes
[[maybe_unused]] constexpr std::size_t pageSize = 256; // bytes
[[maybe_unused]] constexpr std::size_t sectorSize = 4 * 1024; // bytes
[[maybe_unused]] constexpr std::size_t smallBlockSize = 32 * 1024; // bytes
[[maybe_unused]] constexpr std::size_t largeBlockSize = 64 * 1024; // bytes
[[maybe_unused]] constexpr std::size_t flashSize = 128 * 1024 * 1024; // bytes
[[maybe_unused]] constexpr std::size_t nSectors = flashSize / sectorSize;
[[maybe_unused]] constexpr std::size_t nSmallBlocks = flashSize / smallBlockSize;
[[maybe_unused]] constexpr std::size_t nLargeBlocks = flashSize / largeBlockSize;


using serial::Byte;
Expand Down
6 changes: 2 additions & 4 deletions Sts1CobcSw/Serial/Serial.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,7 @@ template<typename T>
using SerialBuffer = std::array<Byte, serialSize<T>>;


// Function declarations
// ---------------------
// --- Function declarations ---

// TODO: Rename data -> t or variable
// Must be overloaded for user-defined types to be serializable
Expand All @@ -81,8 +80,7 @@ template<typename T>
[[nodiscard]] constexpr auto Deserialize(std::span<Byte, serialSize<T>> source) -> T;


// Function template definitions
// -----------------------------
// --- Function template definitions ---

template<TriviallySerializable T>
inline constexpr auto SerializeTo(Byte * destination, T const & data) -> Byte *
Expand Down
6 changes: 6 additions & 0 deletions Tests/HardwareTests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,12 @@ add_subdirectory(ThreadTests)
add_program(Crc32 Crc32.test.cpp)
target_link_libraries(Sts1CobcSwTests_Crc32 PRIVATE rodos::rodos)

add_program(FileSystem FileSystem.test.cpp)
target_link_libraries(
Sts1CobcSwTests_FileSystem PRIVATE rodos::rodos littlefs::littlefs Sts1CobcSw_FileSystem
Sts1CobcSw_Periphery
)

add_program(Flash Flash.test.cpp)
target_link_libraries(
Sts1CobcSwTests_Flash PRIVATE rodos::rodos Sts1CobcSw_Periphery Sts1CobcSw_Serial
Expand Down
Loading

0 comments on commit 7b333ce

Please sign in to comment.