From 333a0ad1057ce607c0916b229072e0c144c91dde Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Fri, 19 Nov 2021 16:33:53 +0200 Subject: [PATCH 01/54] Added draft of the littlefs system [FS] #17 --- .gitmodules | 3 + Firmware/3rdparty/CMakeLists.txt | 5 +- Firmware/3rdparty/littlefs_lib/littlefs | 1 + .../firmware_tests/coroutine/CMakeLists.txt | 1 + .../coroutine/coroutine_thoughts.cpp | 104 ++++++++++++++++++ 5 files changed, 112 insertions(+), 2 deletions(-) create mode 160000 Firmware/3rdparty/littlefs_lib/littlefs diff --git a/.gitmodules b/.gitmodules index 638fd596..336b6dad 100644 --- a/.gitmodules +++ b/.gitmodules @@ -13,3 +13,6 @@ [submodule "Firmware/3rdparty/cppcoro_lib/cppcoro"] path = Firmware/3rdparty/cppcoro_lib/cppcoro url = https://github.com/lewissbaker/cppcoro.git +[submodule "Firmware/3rdparty/littlefs_lib/littlefs"] + path = Firmware/3rdparty/littlefs_lib/littlefs + url = https://github.com/littlefs-project/littlefs.git diff --git a/Firmware/3rdparty/CMakeLists.txt b/Firmware/3rdparty/CMakeLists.txt index 5ec4309d..7ea5e51a 100644 --- a/Firmware/3rdparty/CMakeLists.txt +++ b/Firmware/3rdparty/CMakeLists.txt @@ -10,8 +10,9 @@ endif() set(CMAKE_CXX_STANDARD_REQUIRED ON) set( 3RD_PARTY_DIR CACHE STRING ${CMAKE_CURRENT_SOURCE_DIR} )# Libs root path -add_subdirectory( etl ) -add_subdirectory( fmt ) +add_subdirectory(etl) +add_subdirectory(fmt) +add_subdirectory(littlefs_lib) target_compile_definitions(fmt PUBLIC diff --git a/Firmware/3rdparty/littlefs_lib/littlefs b/Firmware/3rdparty/littlefs_lib/littlefs new file mode 160000 index 00000000..ead50807 --- /dev/null +++ b/Firmware/3rdparty/littlefs_lib/littlefs @@ -0,0 +1 @@ +Subproject commit ead50807f1ca3fdf2da00b77a0ce02651ded2d13 diff --git a/Firmware/firmware_tests/coroutine/CMakeLists.txt b/Firmware/firmware_tests/coroutine/CMakeLists.txt index f3dd090c..8c2a0cfa 100644 --- a/Firmware/firmware_tests/coroutine/CMakeLists.txt +++ b/Firmware/firmware_tests/coroutine/CMakeLists.txt @@ -37,6 +37,7 @@ target_link_libraries( watch_display UtilsLibrary logger_service + littlefs ) if(UNIX) target_link_libraries( coroutine_experiments_app PUBLIC Threads::Threads) diff --git a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp index b6fe4d01..6e70911c 100644 --- a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp +++ b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp @@ -12,12 +12,15 @@ #include #include #include +#include #include #include #include "st7789_draft.hpp" +#include + CoroUtils::Task coroutineTask() { int b = 32; @@ -31,6 +34,106 @@ void showFlashDeviceId() int testValue = co_await task; } +namespace Internals::Fs +{ + +class FilesystemPasskey +{ + friend class File; + friend class Holder; + +private: + FilesystemPasskey() + { + } + FilesystemPasskey(const FilesystemPasskey&) = default; + FilesystemPasskey& operator=(const FilesystemPasskey&) = delete; +}; + +class File +{ +public: + explicit File(lfs_file_t fileHandle) : m_pFileHandle{fileHandle} + { + } + ~File() + { + Holder::Instance().close(this); + } + CoroUtils::VoidTask write(std::span dataHolder) + { + co_return; + } + + CoroUtils::Task> read(std::size_t dataSize) + { + co_return {}; + } + + lfs_file_t nativeHandle(const FilesystemPasskey& passkey) + { + Meta::UnuseVar(passkey); + return m_pFileHandle; + } + +private: + lfs_file_t m_pFileHandle; +}; +class Holder +{ +public: + static Holder& Instance() + { + static Holder fsHolder{}; + return fsHolder; + } + + CoroUtils::Task openFile(std::string_view path) + { + lfs_file_t file{}; + lfs_file_open(&m_fsInstance, &file, "boot_count", LFS_O_RDWR | LFS_O_CREAT); + co_return File{file}; + } + + void close(File* pFile) + { + assert(pFile); + if (!pFile) + return; + auto nativeHandle = pFile->nativeHandle(FilesystemPasskey{}); + lfs_file_close(&m_fsInstance, &nativeHandle); + } + +private: + static constexpr inline lfs_config fsConfig{}; + +private: + Holder() + { + auto error = lfs_mount(&m_fsInstance, &fsConfig); + if (error) + { + lfs_format(&m_fsInstance, &fsConfig); + lfs_mount(&m_fsInstance, &fsConfig); + } + } + +private: + lfs_t m_fsInstance; +}; +} // namespace Internals::Fs + +CoroUtils::VoidTask fileTest() +{ + auto file = co_await Internals::Fs::Holder::Instance().openFile("test.txt"); + constexpr auto kFileData = std::string_view("Hello world!"); + co_await file.write( + {reinterpret_cast(kFileData.data()), kFileData.size()}); + auto data = co_await file.read(kFileData.size()); + + std::cout << std::string_view(reinterpret_cast(data.data()), data.size()); +} + int main() { using TSpiBus = Interface::SpiTemplated::SpiBus; @@ -42,6 +145,7 @@ int main() TDisplayDriver compactGc9A01; compactGc9A01.fillRectangle(0, 0, 0, 0, nullptr); compactGc9A01.initialize(); + // ST7789Coroutine displayCoro{ // Interface::Spi::createSpiBusAsync() // , 240 From 00d7e1958655b8ca68ea43990f0d43ac43c32789 Mon Sep 17 00:00:00 2001 From: VKorniienko Date: Mon, 22 Nov 2021 22:47:13 +0200 Subject: [PATCH 02/54] Draft wrapper over littlefs types --- .gitignore | 6 +- .../firmware_tests/coroutine/CMakeLists.txt | 11 ++- .../coroutine/coroutine_thoughts.cpp | 97 +------------------ .../coroutine/fs_ideas/file_handle.hpp | 47 +++++++++ .../coroutine/fs_ideas/filesystem_holder.cpp | 54 +++++++++++ .../coroutine/fs_ideas/filesystem_holder.hpp | 29 ++++++ .../coroutine/fs_ideas/fs_common.hpp | 20 ++++ .../fs_ideas/platform_filesystem.hpp | 3 + .../coroutine/wrapper/ih_block_device.hpp | 12 +++ 9 files changed, 184 insertions(+), 95 deletions(-) create mode 100644 Firmware/firmware_tests/coroutine/fs_ideas/file_handle.hpp create mode 100644 Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.cpp create mode 100644 Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp create mode 100644 Firmware/firmware_tests/coroutine/fs_ideas/fs_common.hpp create mode 100644 Firmware/firmware_tests/coroutine/fs_ideas/platform_filesystem.hpp create mode 100644 Firmware/firmware_tests/coroutine/wrapper/ih_block_device.hpp diff --git a/.gitignore b/.gitignore index dc41d0d8..9abef84a 100644 --- a/.gitignore +++ b/.gitignore @@ -32,6 +32,8 @@ _deps build/ out/ build_simulator/ - +Firmware/build_firmware #ignore vs temp folders -.vs/ \ No newline at end of file +.vs/ +#Ignore kicad backups +*.sch-bak \ No newline at end of file diff --git a/Firmware/firmware_tests/coroutine/CMakeLists.txt b/Firmware/firmware_tests/coroutine/CMakeLists.txt index 8c2a0cfa..c0bac930 100644 --- a/Firmware/firmware_tests/coroutine/CMakeLists.txt +++ b/Firmware/firmware_tests/coroutine/CMakeLists.txt @@ -14,8 +14,17 @@ target_sources( coroutine_thoughts.cpp thoughts.hpp st7789_draft.hpp -) + fs_ideas/file_handle.hpp + fs_ideas/filesystem_holder.hpp + fs_ideas/filesystem_holder.cpp + fs_ideas/platform_filesystem.hpp "wrapper/ih_block_device.hpp") +target_include_directories( + coroutine_experiments_app + PRIVATE + fs_ideas + wrapper +) target_compile_features( coroutine_experiments_app PRIVATE diff --git a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp index 6e70911c..430e5b61 100644 --- a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp +++ b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp @@ -19,7 +19,7 @@ #include "st7789_draft.hpp" -#include +#include "fs_ideas/platform_filesystem.hpp" CoroUtils::Task coroutineTask() { @@ -34,98 +34,9 @@ void showFlashDeviceId() int testValue = co_await task; } -namespace Internals::Fs +void fileTest() { - -class FilesystemPasskey -{ - friend class File; - friend class Holder; - -private: - FilesystemPasskey() - { - } - FilesystemPasskey(const FilesystemPasskey&) = default; - FilesystemPasskey& operator=(const FilesystemPasskey&) = delete; -}; - -class File -{ -public: - explicit File(lfs_file_t fileHandle) : m_pFileHandle{fileHandle} - { - } - ~File() - { - Holder::Instance().close(this); - } - CoroUtils::VoidTask write(std::span dataHolder) - { - co_return; - } - - CoroUtils::Task> read(std::size_t dataSize) - { - co_return {}; - } - - lfs_file_t nativeHandle(const FilesystemPasskey& passkey) - { - Meta::UnuseVar(passkey); - return m_pFileHandle; - } - -private: - lfs_file_t m_pFileHandle; -}; -class Holder -{ -public: - static Holder& Instance() - { - static Holder fsHolder{}; - return fsHolder; - } - - CoroUtils::Task openFile(std::string_view path) - { - lfs_file_t file{}; - lfs_file_open(&m_fsInstance, &file, "boot_count", LFS_O_RDWR | LFS_O_CREAT); - co_return File{file}; - } - - void close(File* pFile) - { - assert(pFile); - if (!pFile) - return; - auto nativeHandle = pFile->nativeHandle(FilesystemPasskey{}); - lfs_file_close(&m_fsInstance, &nativeHandle); - } - -private: - static constexpr inline lfs_config fsConfig{}; - -private: - Holder() - { - auto error = lfs_mount(&m_fsInstance, &fsConfig); - if (error) - { - lfs_format(&m_fsInstance, &fsConfig); - lfs_mount(&m_fsInstance, &fsConfig); - } - } - -private: - lfs_t m_fsInstance; -}; -} // namespace Internals::Fs - -CoroUtils::VoidTask fileTest() -{ - auto file = co_await Internals::Fs::Holder::Instance().openFile("test.txt"); + auto file = co_await Platform::Fs::Holder::Instance().openFile("test.txt"); constexpr auto kFileData = std::string_view("Hello world!"); co_await file.write( {reinterpret_cast(kFileData.data()), kFileData.size()}); @@ -136,6 +47,8 @@ CoroUtils::VoidTask fileTest() int main() { + + fileTest(); using TSpiBus = Interface::SpiTemplated::SpiBus; using TDisplayDriver = DisplayDriver::GC9A01Compact; diff --git a/Firmware/firmware_tests/coroutine/fs_ideas/file_handle.hpp b/Firmware/firmware_tests/coroutine/fs_ideas/file_handle.hpp new file mode 100644 index 00000000..8ac94efe --- /dev/null +++ b/Firmware/firmware_tests/coroutine/fs_ideas/file_handle.hpp @@ -0,0 +1,47 @@ + +#include "filesystem_holder.hpp" +#include "fs_common.hpp" +#include +#include +#include +#include +#include +#include + +namespace Platform::Fs +{ +class File +{ +public: + explicit File() = default; + explicit File(lfs_file_t fileHandle, Platform::Fs::Holder* pFsHolder) + : m_pFileHandle{fileHandle}, m_pFsHolder{pFsHolder} + { + } + ~File() + { + if (m_pFsHolder) + m_pFsHolder->close(this); + } + CoroUtils::VoidTask write(std::span dataHolder) + { + co_return; + } + + CoroUtils::Task> read(std::size_t dataSize) + { + co_return {}; + } + + lfs_file_t nativeHandle(const FilesystemPasskey& passkey) + { + Meta::UnuseVar(passkey); + return m_pFileHandle; + } + +private: + lfs_file_t m_pFileHandle; + Platform::Fs::Holder* m_pFsHolder; +}; + +} // namespace Platform::Fs \ No newline at end of file diff --git a/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.cpp b/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.cpp new file mode 100644 index 00000000..386133e9 --- /dev/null +++ b/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.cpp @@ -0,0 +1,54 @@ +#include "filesystem_holder.hpp" +#include "file_handle.hpp" + +namespace Platform::Fs +{ + +Holder::Holder(std::unique_ptr&& blockDeviceEntity) + : m_fsInstance{}, m_blockDeviceHolder{std::move(blockDeviceEntity)} +{ + auto fsConfig{ createLfsConfig() }; + auto error = lfs_mount(&m_fsInstance, &fsConfig); + if (error) + { + lfs_format(&m_fsInstance, &fsConfig); + lfs_mount(&m_fsInstance, &fsConfig); + } +} +CoroUtils::Task Holder::openFile(std::string_view path) +{ + lfs_file_t file{}; + lfs_file_open(&m_fsInstance, &file, path.data(), LFS_O_RDWR | LFS_O_CREAT); + co_return File{file, this}; +} +void Holder::close(File* pFile) +{ + assert(pFile); + if (!pFile) + return; + auto nativeHandle = pFile->nativeHandle(FilesystemPasskey{}); + lfs_file_close(&m_fsInstance, &nativeHandle); +} +lfs_config Holder::createLfsConfig() +{ + constexpr std::size_t kBufferDefaultSize = 16; + constexpr std::size_t kBlockCycles = 500; + return lfs_config + { + .read = m_blockDeviceHolder->readCallback(), + .prog = m_blockDeviceHolder->progCallback(), + .erase = m_blockDeviceHolder->eraseCallback(), + .sync = m_blockDeviceHolder->syncCallback(), + + .read_size = kBufferDefaultSize, + .prog_size = kBufferDefaultSize, + + .block_size = m_blockDeviceHolder->getBlockSize(), + .block_count = m_blockDeviceHolder->getBlocksCount(), + + .block_cycles = kBlockCycles, + .cache_size = kBufferDefaultSize, + .lookahead_size = kBufferDefaultSize, + }; +} +} // namespace Platform::Fs \ No newline at end of file diff --git a/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp b/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp new file mode 100644 index 00000000..0e59633c --- /dev/null +++ b/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp @@ -0,0 +1,29 @@ +#pragma once +#include "fs_common.hpp" +#include +#include +#include +#include +#include "ih_block_device.hpp" + +namespace Platform::Fs +{ +class Holder +{ +public: + Holder(std::unique_ptr&& platformBlockDevice); + CoroUtils::Task openFile(std::string_view path); + + void close(File* pFile); + +private: + lfs_config createLfsConfig(); + +private: + Holder(); + +private: + lfs_t m_fsInstance; + std::unique_ptr m_blockDeviceHolder; +}; +} // namespace Platform::Fs diff --git a/Firmware/firmware_tests/coroutine/fs_ideas/fs_common.hpp b/Firmware/firmware_tests/coroutine/fs_ideas/fs_common.hpp new file mode 100644 index 00000000..55cfe515 --- /dev/null +++ b/Firmware/firmware_tests/coroutine/fs_ideas/fs_common.hpp @@ -0,0 +1,20 @@ +#pragma once +namespace Platform::Fs +{ +class File; +class Holder; + +class FilesystemPasskey +{ + friend class File; + friend class Holder; + +private: + FilesystemPasskey() + { + } + FilesystemPasskey(const FilesystemPasskey&) = default; + FilesystemPasskey& operator=(const FilesystemPasskey&) = delete; +}; + +} // namespace Platform::Fs \ No newline at end of file diff --git a/Firmware/firmware_tests/coroutine/fs_ideas/platform_filesystem.hpp b/Firmware/firmware_tests/coroutine/fs_ideas/platform_filesystem.hpp new file mode 100644 index 00000000..148e9755 --- /dev/null +++ b/Firmware/firmware_tests/coroutine/fs_ideas/platform_filesystem.hpp @@ -0,0 +1,3 @@ +#pragma once +#include "filesystem_holder.hpp" +#include "file_handle.hpp" \ No newline at end of file diff --git a/Firmware/firmware_tests/coroutine/wrapper/ih_block_device.hpp b/Firmware/firmware_tests/coroutine/wrapper/ih_block_device.hpp new file mode 100644 index 00000000..c1afa6c9 --- /dev/null +++ b/Firmware/firmware_tests/coroutine/wrapper/ih_block_device.hpp @@ -0,0 +1,12 @@ +#pragma once +#include + +namespace Wrapper +{ +class IBlockDeviceEntity +{ +public: + virtual std::uint32_t getBlockSize() const noexcept = 0; + virtual std::uint32_t getBlocksCount() const noexcept = 0; +}; +} // namespace Wrapper \ No newline at end of file From 3801c971d1802bda6da6865a76b4c6237b8c8b91 Mon Sep 17 00:00:00 2001 From: VKorniienko Date: Mon, 22 Nov 2021 23:02:54 +0200 Subject: [PATCH 03/54] Added missed CMakeLists for littlefs --- Firmware/3rdparty/littlefs_lib/CMakeLists.txt | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 Firmware/3rdparty/littlefs_lib/CMakeLists.txt diff --git a/Firmware/3rdparty/littlefs_lib/CMakeLists.txt b/Firmware/3rdparty/littlefs_lib/CMakeLists.txt new file mode 100644 index 00000000..98174ed0 --- /dev/null +++ b/Firmware/3rdparty/littlefs_lib/CMakeLists.txt @@ -0,0 +1,17 @@ +cmake_minimum_required(VERSION 3.14) +project(cppcoro LANGUAGES CXX) + +set(CMAKE_CXX_EXTENSIONS OFF) + +add_library(littlefs) + +target_sources(littlefs PRIVATE + "littlefs/lfs.c" + "littlefs/lfs_util.c" +) + +target_include_directories(littlefs PUBLIC + $ +) + +target_compile_definitions(littlefs PUBLIC LFS_YES_TRACE) \ No newline at end of file From 5a82a49ac35c20d82ec210ac046020d616c856a7 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Tue, 23 Nov 2021 00:06:57 +0200 Subject: [PATCH 04/54] Implemented draft of heap block device --- .../firmware_tests/coroutine/CMakeLists.txt | 8 +- .../coroutine/coroutine_thoughts.cpp | 6 +- .../coroutine/fs_ideas/file_handle.hpp | 47 ------ .../coroutine/fs_ideas/filesystem_holder.cpp | 54 ------- .../coroutine/fs_ideas/filesystem_holder.hpp | 151 ++++++++++++++++-- .../coroutine/fs_ideas/fs_common.hpp | 20 --- .../fs_ideas/platform_filesystem.hpp | 3 +- .../coroutine/wrapper/heap_block_device.hpp | 28 ++++ .../coroutine/wrapper/ih_block_device.hpp | 18 ++- 9 files changed, 195 insertions(+), 140 deletions(-) delete mode 100644 Firmware/firmware_tests/coroutine/fs_ideas/file_handle.hpp delete mode 100644 Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.cpp delete mode 100644 Firmware/firmware_tests/coroutine/fs_ideas/fs_common.hpp create mode 100644 Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp diff --git a/Firmware/firmware_tests/coroutine/CMakeLists.txt b/Firmware/firmware_tests/coroutine/CMakeLists.txt index c0bac930..736fe386 100644 --- a/Firmware/firmware_tests/coroutine/CMakeLists.txt +++ b/Firmware/firmware_tests/coroutine/CMakeLists.txt @@ -14,10 +14,12 @@ target_sources( coroutine_thoughts.cpp thoughts.hpp st7789_draft.hpp - fs_ideas/file_handle.hpp fs_ideas/filesystem_holder.hpp - fs_ideas/filesystem_holder.cpp - fs_ideas/platform_filesystem.hpp "wrapper/ih_block_device.hpp") + + fs_ideas/platform_filesystem.hpp + wrapper/ih_block_device.hpp + wrapper/heap_block_device.hpp +) target_include_directories( coroutine_experiments_app diff --git a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp index 430e5b61..0991063c 100644 --- a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp +++ b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp @@ -20,6 +20,7 @@ #include "st7789_draft.hpp" #include "fs_ideas/platform_filesystem.hpp" +#include "wrapper/heap_block_device.hpp" CoroUtils::Task coroutineTask() { @@ -36,7 +37,10 @@ void showFlashDeviceId() void fileTest() { - auto file = co_await Platform::Fs::Holder::Instance().openFile("test.txt"); + using TFilesystem = Platform::Fs::Holder>; + TFilesystem platformFilesystem; + + auto file = co_await platformFilesystem.openFile("test.txt"); constexpr auto kFileData = std::string_view("Hello world!"); co_await file.write( {reinterpret_cast(kFileData.data()), kFileData.size()}); diff --git a/Firmware/firmware_tests/coroutine/fs_ideas/file_handle.hpp b/Firmware/firmware_tests/coroutine/fs_ideas/file_handle.hpp deleted file mode 100644 index 8ac94efe..00000000 --- a/Firmware/firmware_tests/coroutine/fs_ideas/file_handle.hpp +++ /dev/null @@ -1,47 +0,0 @@ - -#include "filesystem_holder.hpp" -#include "fs_common.hpp" -#include -#include -#include -#include -#include -#include - -namespace Platform::Fs -{ -class File -{ -public: - explicit File() = default; - explicit File(lfs_file_t fileHandle, Platform::Fs::Holder* pFsHolder) - : m_pFileHandle{fileHandle}, m_pFsHolder{pFsHolder} - { - } - ~File() - { - if (m_pFsHolder) - m_pFsHolder->close(this); - } - CoroUtils::VoidTask write(std::span dataHolder) - { - co_return; - } - - CoroUtils::Task> read(std::size_t dataSize) - { - co_return {}; - } - - lfs_file_t nativeHandle(const FilesystemPasskey& passkey) - { - Meta::UnuseVar(passkey); - return m_pFileHandle; - } - -private: - lfs_file_t m_pFileHandle; - Platform::Fs::Holder* m_pFsHolder; -}; - -} // namespace Platform::Fs \ No newline at end of file diff --git a/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.cpp b/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.cpp deleted file mode 100644 index 386133e9..00000000 --- a/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.cpp +++ /dev/null @@ -1,54 +0,0 @@ -#include "filesystem_holder.hpp" -#include "file_handle.hpp" - -namespace Platform::Fs -{ - -Holder::Holder(std::unique_ptr&& blockDeviceEntity) - : m_fsInstance{}, m_blockDeviceHolder{std::move(blockDeviceEntity)} -{ - auto fsConfig{ createLfsConfig() }; - auto error = lfs_mount(&m_fsInstance, &fsConfig); - if (error) - { - lfs_format(&m_fsInstance, &fsConfig); - lfs_mount(&m_fsInstance, &fsConfig); - } -} -CoroUtils::Task Holder::openFile(std::string_view path) -{ - lfs_file_t file{}; - lfs_file_open(&m_fsInstance, &file, path.data(), LFS_O_RDWR | LFS_O_CREAT); - co_return File{file, this}; -} -void Holder::close(File* pFile) -{ - assert(pFile); - if (!pFile) - return; - auto nativeHandle = pFile->nativeHandle(FilesystemPasskey{}); - lfs_file_close(&m_fsInstance, &nativeHandle); -} -lfs_config Holder::createLfsConfig() -{ - constexpr std::size_t kBufferDefaultSize = 16; - constexpr std::size_t kBlockCycles = 500; - return lfs_config - { - .read = m_blockDeviceHolder->readCallback(), - .prog = m_blockDeviceHolder->progCallback(), - .erase = m_blockDeviceHolder->eraseCallback(), - .sync = m_blockDeviceHolder->syncCallback(), - - .read_size = kBufferDefaultSize, - .prog_size = kBufferDefaultSize, - - .block_size = m_blockDeviceHolder->getBlockSize(), - .block_count = m_blockDeviceHolder->getBlocksCount(), - - .block_cycles = kBlockCycles, - .cache_size = kBufferDefaultSize, - .lookahead_size = kBufferDefaultSize, - }; -} -} // namespace Platform::Fs \ No newline at end of file diff --git a/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp b/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp index 0e59633c..e8c5cc21 100644 --- a/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp +++ b/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp @@ -1,29 +1,160 @@ #pragma once -#include "fs_common.hpp" +#include "ih_block_device.hpp" #include +#include #include #include -#include -#include "ih_block_device.hpp" + +#include +#include +#include namespace Platform::Fs { -class Holder +template +class File; + +template +class Holder; + +class FilesystemPasskey +{ + template + friend class File; + + template + friend class Holder; + +private: + FilesystemPasskey() + { + } + FilesystemPasskey(const FilesystemPasskey&) = default; + FilesystemPasskey& operator=(const FilesystemPasskey&) = delete; +}; +template class Holder { public: - Holder(std::unique_ptr&& platformBlockDevice); - CoroUtils::Task openFile(std::string_view path); + using This_t = Holder; +public: + constexpr Holder() + { + auto fsConfig{createLfsConfig()}; + auto error = lfs_mount(&m_fsInstance, &fsConfig); + if (error) + { + lfs_format(&m_fsInstance, &fsConfig); + lfs_mount(&m_fsInstance, &fsConfig); + } + } + CoroUtils::Task> openFile(std::string_view path) + { + lfs_file_t file{}; + lfs_file_open(&m_fsInstance, &file, path.data(), LFS_O_RDWR | LFS_O_CREAT); + co_return File{file, this}; + } - void close(File* pFile); + void close(File* pFile) + { + assert(pFile); + if (!pFile) + return; + auto nativeHandle = pFile->nativeHandle(FilesystemPasskey{}); + lfs_file_close(&m_fsInstance, &nativeHandle); + } private: - lfs_config createLfsConfig(); private: - Holder(); + static int readCall( + const struct lfs_config* c, + lfs_block_t block, + lfs_off_t off, + void* buffer, + lfs_size_t size) + { + auto pThis = reinterpret_cast(c->context); + return LFS_ERR_OK; + } + + static int progCall(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, + lfs_size_t size) + { + auto pThis = reinterpret_cast(c->context); + return LFS_ERR_OK; + } + + static int eraseCall(const struct lfs_config* c, lfs_block_t block) + { + auto pThis = reinterpret_cast(c->context); + return LFS_ERR_OK; + } + + static int syncCall(const struct lfs_config* c) + { + auto pThis = reinterpret_cast(c->context); + return LFS_ERR_OK; + } + +private : + lfs_config createLfsConfig() + { + constexpr std::size_t kBufferDefaultSize = 16; + constexpr std::size_t kBlockCycles = 500; + return lfs_config + { + .context = this, + .read = readCall, + .prog = progCall, + .erase = eraseCall, + .sync = syncCall, + + .read_size = kBufferDefaultSize, .prog_size = kBufferDefaultSize, + + .block_size = m_blockDeviceHolder.getBlockSize(), + .block_count = m_blockDeviceHolder.getBlocksCount(), + + .block_cycles = kBlockCycles, .cache_size = kBufferDefaultSize, + .lookahead_size = kBufferDefaultSize, + }; + } private: lfs_t m_fsInstance; - std::unique_ptr m_blockDeviceHolder; + TBlockDeviceEntity m_blockDeviceHolder; +}; + +template class File +{ +public: + explicit File() = default; + explicit File(lfs_file_t fileHandle, TFilesystemHolder* pFsHolder) + : m_pFileHandle{fileHandle}, m_pFsHolder{pFsHolder} + { + } + ~File() + { + if (m_pFsHolder) + m_pFsHolder->close(this); + } + CoroUtils::VoidTask write(std::span dataHolder) + { + co_return; + } + + CoroUtils::Task> read(std::size_t dataSize) + { + co_return {}; + } + + lfs_file_t nativeHandle(const FilesystemPasskey& passkey) + { + Meta::UnuseVar(passkey); + return m_pFileHandle; + } + +private: + lfs_file_t m_pFileHandle; + TFilesystemHolder* m_pFsHolder; }; } // namespace Platform::Fs diff --git a/Firmware/firmware_tests/coroutine/fs_ideas/fs_common.hpp b/Firmware/firmware_tests/coroutine/fs_ideas/fs_common.hpp deleted file mode 100644 index 55cfe515..00000000 --- a/Firmware/firmware_tests/coroutine/fs_ideas/fs_common.hpp +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once -namespace Platform::Fs -{ -class File; -class Holder; - -class FilesystemPasskey -{ - friend class File; - friend class Holder; - -private: - FilesystemPasskey() - { - } - FilesystemPasskey(const FilesystemPasskey&) = default; - FilesystemPasskey& operator=(const FilesystemPasskey&) = delete; -}; - -} // namespace Platform::Fs \ No newline at end of file diff --git a/Firmware/firmware_tests/coroutine/fs_ideas/platform_filesystem.hpp b/Firmware/firmware_tests/coroutine/fs_ideas/platform_filesystem.hpp index 148e9755..4da8628c 100644 --- a/Firmware/firmware_tests/coroutine/fs_ideas/platform_filesystem.hpp +++ b/Firmware/firmware_tests/coroutine/fs_ideas/platform_filesystem.hpp @@ -1,3 +1,2 @@ #pragma once -#include "filesystem_holder.hpp" -#include "file_handle.hpp" \ No newline at end of file +#include "filesystem_holder.hpp" \ No newline at end of file diff --git a/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp b/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp new file mode 100644 index 00000000..6bb1ea9e --- /dev/null +++ b/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include"ih_block_device.hpp" +#include + +namespace Wrapper +{ +inline constexpr std::size_t kBlockSize = 512; +inline constexpr std::size_t kSectorsCount = 64; + +template +class HeapBlockDevice : public BlockDeviceEntity> +{ +public: + constexpr std::uint32_t getBlockSize() const noexcept + { + return kBlockSize; + } + constexpr std::uint32_t getBlocksCount() const noexcept + { + return kSectorsCount; + } + +private: + using TBlocksStorage = etl::vector, SectorsCount>; + TBlocksStorage m_blockStorage; +}; +} \ No newline at end of file diff --git a/Firmware/firmware_tests/coroutine/wrapper/ih_block_device.hpp b/Firmware/firmware_tests/coroutine/wrapper/ih_block_device.hpp index c1afa6c9..1137d5ce 100644 --- a/Firmware/firmware_tests/coroutine/wrapper/ih_block_device.hpp +++ b/Firmware/firmware_tests/coroutine/wrapper/ih_block_device.hpp @@ -3,10 +3,22 @@ namespace Wrapper { -class IBlockDeviceEntity +template class BlockDeviceEntity { public: - virtual std::uint32_t getBlockSize() const noexcept = 0; - virtual std::uint32_t getBlocksCount() const noexcept = 0; + constexpr std::uint32_t getBlockSize() const noexcept + { + return offspring()->getBlockSize(); + } + constexpr std::uint32_t getBlocksCount() const noexcept + { + return offspring()->getBlocksCount(); + } + +private: + constexpr auto offspring() + { + return static_cast(this); + } }; } // namespace Wrapper \ No newline at end of file From ca42a8091192e0a5e889bc0b4e4c78b8cbe22cfb Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Tue, 23 Nov 2021 00:25:48 +0200 Subject: [PATCH 05/54] Draft of the write method for block device --- .../coroutine/fs_ideas/filesystem_holder.hpp | 9 +++++++++ .../coroutine/wrapper/heap_block_device.hpp | 13 +++++++++++-- .../coroutine/wrapper/ih_block_device.hpp | 5 +++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp b/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp index e8c5cc21..eff788fe 100644 --- a/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp +++ b/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp @@ -63,6 +63,11 @@ template class Holder lfs_file_close(&m_fsInstance, &nativeHandle); } + TBlockDeviceEntity& getBlockDevice() + { + return m_blockDeviceHolder; + } + private: private: @@ -81,6 +86,10 @@ template class Holder lfs_size_t size) { auto pThis = reinterpret_cast(c->context); + pThis->getBlockDevice().write( + (block * c->block_size + off), + std::span(reinterpret_cast(buffer), size)); + return LFS_ERR_OK; } diff --git a/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp b/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp index 6bb1ea9e..3c74b255 100644 --- a/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp +++ b/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp @@ -9,7 +9,7 @@ inline constexpr std::size_t kBlockSize = 512; inline constexpr std::size_t kSectorsCount = 64; template -class HeapBlockDevice : public BlockDeviceEntity> +class HeapBlockDevice : public BlockDeviceEntity> { public: constexpr std::uint32_t getBlockSize() const noexcept @@ -20,9 +20,18 @@ class HeapBlockDevice : public BlockDeviceEntity _blockData) noexcept + { + std::uint32_t highPart = _address / kBlockSize; + std::uint32_t lowPart = _address % kBlockSize; + auto& pBlock = m_blockStorage[highPart]; + memcpy(pBlock.data() + lowPart, _blockData.data(), _blockData.size()); + } private: - using TBlocksStorage = etl::vector, SectorsCount>; + using TBlocksStorage = etl::array, SectorsCount>; TBlocksStorage m_blockStorage; }; } \ No newline at end of file diff --git a/Firmware/firmware_tests/coroutine/wrapper/ih_block_device.hpp b/Firmware/firmware_tests/coroutine/wrapper/ih_block_device.hpp index 1137d5ce..98b9f0ac 100644 --- a/Firmware/firmware_tests/coroutine/wrapper/ih_block_device.hpp +++ b/Firmware/firmware_tests/coroutine/wrapper/ih_block_device.hpp @@ -15,6 +15,11 @@ template class BlockDeviceEntity return offspring()->getBlocksCount(); } + void write(const std::uint32_t _address, std::span _blockData) noexcept + { + return offspring()->write(_address, _blockData); + } + private: constexpr auto offspring() { From 6a7354736af8b8b1d12f7f6a2c14389c791beaff Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Sun, 5 Dec 2021 20:31:20 +0200 Subject: [PATCH 06/54] Working draft of the filesystem mounting --- .../coroutine/coroutine_thoughts.cpp | 14 +-- .../coroutine/fs_ideas/filesystem_holder.hpp | 98 +++++++++++-------- .../coroutine/wrapper/heap_block_device.hpp | 68 ++++++++++--- .../coroutine/wrapper/ih_block_device.hpp | 20 +++- 4 files changed, 141 insertions(+), 59 deletions(-) diff --git a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp index 0991063c..f40c44b7 100644 --- a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp +++ b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include @@ -34,13 +35,11 @@ void showFlashDeviceId() CoroUtils::Task task = coroutineTask(); int testValue = co_await task; } - -void fileTest() +using TFilesystem = Platform::Fs::Holder>; +CoroUtils::VoidTask fileTest(TFilesystem& filesystem) { - using TFilesystem = Platform::Fs::Holder>; - TFilesystem platformFilesystem; - auto file = co_await platformFilesystem.openFile("test.txt"); + auto file = filesystem.openFile("test.txt"); constexpr auto kFileData = std::string_view("Hello world!"); co_await file.write( {reinterpret_cast(kFileData.data()), kFileData.size()}); @@ -52,7 +51,10 @@ void fileTest() int main() { - fileTest(); + TFilesystem platformFilesystem; + + CoroUtils::syncWait(fileTest(platformFilesystem)); + using TSpiBus = Interface::SpiTemplated::SpiBus; using TDisplayDriver = DisplayDriver::GC9A01Compact; diff --git a/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp b/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp index eff788fe..0669bb9f 100644 --- a/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp +++ b/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp @@ -11,19 +11,15 @@ namespace Platform::Fs { -template -class File; +template class File; -template -class Holder; +template class Holder; class FilesystemPasskey { - template - friend class File; + template friend class File; - template - friend class Holder; + template friend class Holder; private: FilesystemPasskey() @@ -36,25 +32,30 @@ template class Holder { public: using This_t = Holder; + public: - constexpr Holder() + constexpr Holder()noexcept { - auto fsConfig{createLfsConfig()}; - auto error = lfs_mount(&m_fsInstance, &fsConfig); + m_fsConfig = createLfsConfig(); + auto error = lfs_mount(&m_fsInstance, &m_fsConfig); if (error) { - lfs_format(&m_fsInstance, &fsConfig); - lfs_mount(&m_fsInstance, &fsConfig); + lfs_format(&m_fsInstance, &m_fsConfig); + lfs_mount(&m_fsInstance, &m_fsConfig); } } - CoroUtils::Task> openFile(std::string_view path) + constexpr auto fsInstance() noexcept + { + return m_fsInstance; + } + File openFile(std::string_view path)noexcept { lfs_file_t file{}; lfs_file_open(&m_fsInstance, &file, path.data(), LFS_O_RDWR | LFS_O_CREAT); - co_return File{file, this}; + return File{file, this}; } - void close(File* pFile) + void close(File* pFile)noexcept { assert(pFile); if (!pFile) @@ -63,81 +64,96 @@ template class Holder lfs_file_close(&m_fsInstance, &nativeHandle); } - TBlockDeviceEntity& getBlockDevice() + constexpr TBlockDeviceEntity& getBlockDevice()noexcept { return m_blockDeviceHolder; } private: - private: - static int readCall( + constexpr static int readCall( const struct lfs_config* c, lfs_block_t block, lfs_off_t off, void* buffer, - lfs_size_t size) + lfs_size_t size)noexcept { auto pThis = reinterpret_cast(c->context); + pThis->getBlockDevice().read( + static_cast(buffer), block * c->block_size + off, size); return LFS_ERR_OK; } - static int progCall(const struct lfs_config *c, lfs_block_t block, lfs_off_t off, const void *buffer, - lfs_size_t size) + constexpr static int progCall( + const struct lfs_config* c, + lfs_block_t block, + lfs_off_t off, + const void* buffer, + lfs_size_t size)noexcept { auto pThis = reinterpret_cast(c->context); pThis->getBlockDevice().write( - (block * c->block_size + off), - std::span(reinterpret_cast(buffer), size)); + (block * c->block_size + off), reinterpret_cast(buffer), size); return LFS_ERR_OK; } - static int eraseCall(const struct lfs_config* c, lfs_block_t block) + constexpr static int eraseCall(const struct lfs_config* c, lfs_block_t block)noexcept { auto pThis = reinterpret_cast(c->context); return LFS_ERR_OK; } - static int syncCall(const struct lfs_config* c) + constexpr static int syncCall(const struct lfs_config* c)noexcept { auto pThis = reinterpret_cast(c->context); return LFS_ERR_OK; } -private : - lfs_config createLfsConfig() +private: + constexpr lfs_config createLfsConfig() noexcept { - constexpr std::size_t kBufferDefaultSize = 16; constexpr std::size_t kBlockCycles = 500; - return lfs_config - { + return lfs_config{ .context = this, .read = readCall, .prog = progCall, .erase = eraseCall, .sync = syncCall, - .read_size = kBufferDefaultSize, .prog_size = kBufferDefaultSize, + .read_size = m_blockDeviceHolder.getReadSize(), + .prog_size = m_blockDeviceHolder.getProgSize(), .block_size = m_blockDeviceHolder.getBlockSize(), .block_count = m_blockDeviceHolder.getBlocksCount(), - .block_cycles = kBlockCycles, .cache_size = kBufferDefaultSize, - .lookahead_size = kBufferDefaultSize, - }; + .block_cycles = kBlockCycles, + .cache_size = m_blockDeviceHolder.getBlockSize(), + .lookahead_size = m_blockDeviceHolder.getBlockSize(), + + .read_buffer = readBuffer.data(), + .prog_buffer = writeBuffer.data(), + .lookahead_buffer = lookaheadBuffer.data()}; } private: + static constexpr inline std::size_t FsArraySize = 512; + using TDataHolder = std::array; + +private: + lfs_config m_fsConfig; lfs_t m_fsInstance; TBlockDeviceEntity m_blockDeviceHolder; + TDataHolder readBuffer; + TDataHolder writeBuffer; + TDataHolder lookaheadBuffer; }; template class File { public: - explicit File() = default; - explicit File(lfs_file_t fileHandle, TFilesystemHolder* pFsHolder) + explicit constexpr File()noexcept = default; + explicit constexpr File(lfs_file_t fileHandle, TFilesystemHolder* pFsHolder)noexcept : m_pFileHandle{fileHandle}, m_pFsHolder{pFsHolder} { } @@ -146,17 +162,19 @@ template class File if (m_pFsHolder) m_pFsHolder->close(this); } - CoroUtils::VoidTask write(std::span dataHolder) + CoroUtils::VoidTask write(std::span dataHolder)noexcept { + auto fsInstance = m_pFsHolder->fsInstance(); + lfs_file_write(&fsInstance, &m_pFileHandle, dataHolder.data(), static_cast(dataHolder.size())); co_return; } - CoroUtils::Task> read(std::size_t dataSize) + CoroUtils::Task> read(std::size_t dataSize)noexcept { co_return {}; } - lfs_file_t nativeHandle(const FilesystemPasskey& passkey) + lfs_file_t nativeHandle(const FilesystemPasskey& passkey)noexcept { Meta::UnuseVar(passkey); return m_pFileHandle; diff --git a/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp b/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp index 3c74b255..65542f51 100644 --- a/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp +++ b/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp @@ -1,17 +1,24 @@ #pragma once -#include"ih_block_device.hpp" -#include +#include "ih_block_device.hpp" +#include namespace Wrapper { inline constexpr std::size_t kBlockSize = 512; inline constexpr std::size_t kSectorsCount = 64; -template +template class HeapBlockDevice : public BlockDeviceEntity> { public: + + HeapBlockDevice() + { + m_blockStorage.resize(SectorsCount); + std::ranges::for_each(m_blockStorage, [](auto& storageBlock) { std::ranges::fill(storageBlock, 0xFF); }); + } + constexpr std::uint32_t getBlockSize() const noexcept { return kBlockSize; @@ -20,18 +27,57 @@ class HeapBlockDevice : public BlockDeviceEntity _blockData) noexcept + std::uint32_t _address, + const std::uint8_t* _blockData, std::size_t _blockSize) noexcept + { + std::size_t requestSize = _blockSize; + const std::uint8_t* pBlockRequest = static_cast(_blockData); + while(requestSize>0) + { + std::uint32_t highPart = _address / getEraseSize(); + std::uint32_t lowPart = _address % getEraseSize(); + auto& pBlock = m_blockStorage[highPart]; + memcpy(pBlock.data() + lowPart, pBlockRequest, getProgSize()); + + pBlockRequest += getProgSize(); + _address += getProgSize(); + requestSize -= getProgSize(); + } + } + void read(std::uint8_t* _pBlockOut, std::uint32_t _address, std::uint32_t _blockSize) noexcept { - std::uint32_t highPart = _address / kBlockSize; - std::uint32_t lowPart = _address % kBlockSize; - auto& pBlock = m_blockStorage[highPart]; - memcpy(pBlock.data() + lowPart, _blockData.data(), _blockData.size()); + while (_blockSize > 0) + { + std::uint32_t hi = _address / getEraseSize(); + std::uint32_t lo = _address % getEraseSize(); + + memcpy(_pBlockOut, m_blockStorage[hi].data() + lo, getReadSize()); + + _pBlockOut += getReadSize(); + _address += getReadSize(); + _blockSize -= getReadSize(); + } } private: - using TBlocksStorage = etl::array, SectorsCount>; + static constexpr std::uint32_t kDefRequestSize = 1; + +private: + using TBlocksStorage = std::vector>; TBlocksStorage m_blockStorage; }; -} \ No newline at end of file +} // namespace Wrapper \ No newline at end of file diff --git a/Firmware/firmware_tests/coroutine/wrapper/ih_block_device.hpp b/Firmware/firmware_tests/coroutine/wrapper/ih_block_device.hpp index 98b9f0ac..592d8f42 100644 --- a/Firmware/firmware_tests/coroutine/wrapper/ih_block_device.hpp +++ b/Firmware/firmware_tests/coroutine/wrapper/ih_block_device.hpp @@ -14,10 +14,26 @@ template class BlockDeviceEntity { return offspring()->getBlocksCount(); } + constexpr std::uint32_t getReadSize() const noexcept + { + return offspring()->getReadSize(); + } + constexpr std::uint32_t getProgSize() const noexcept + { + return offspring()->getProgSize(); + } + constexpr std::uint32_t getEraseSize() const noexcept + { + return offspring()->getEraseSize(); + } - void write(const std::uint32_t _address, std::span _blockData) noexcept + constexpr void write(std::uint32_t _address, const std::uint8_t* _blockData, std::size_t _blockSize) noexcept + { + offspring()->write(_address, _blockData, _blockSize); + } + constexpr void read(std::uint8_t* pblockOut, std::uint32_t _address, std::uint32_t _blockSize) noexcept { - return offspring()->write(_address, _blockData); + offspring()->read(pblockOut, _address, _blockSize); } private: From 5c232f9fb461f4288e26aa89027ab66b8c09a8f4 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Mon, 6 Dec 2021 17:20:43 +0200 Subject: [PATCH 07/54] Corrected template arguments for the heap block device [HEAP][BLOCKDEV] --- .../coroutine/coroutine_thoughts.cpp | 7 ++++++- .../coroutine/wrapper/heap_block_device.hpp | 18 ++++++++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp index f40c44b7..bc1bf896 100644 --- a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp +++ b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp @@ -35,7 +35,12 @@ void showFlashDeviceId() CoroUtils::Task task = coroutineTask(); int testValue = co_await task; } -using TFilesystem = Platform::Fs::Holder>; +using TFilesystem = Platform::Fs::Holder>; + CoroUtils::VoidTask fileTest(TFilesystem& filesystem) { diff --git a/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp b/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp index 65542f51..eae1887c 100644 --- a/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp +++ b/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp @@ -5,10 +5,12 @@ namespace Wrapper { -inline constexpr std::size_t kBlockSize = 512; -inline constexpr std::size_t kSectorsCount = 64; +inline constexpr std::size_t kBlockSize = 256; +inline constexpr std::size_t kSectorsCount = 65'536; +inline constexpr std::size_t kReadSize = 256; +inline constexpr std::size_t kEraseSize = 4096; -template +template class HeapBlockDevice : public BlockDeviceEntity> { public: @@ -21,23 +23,23 @@ class HeapBlockDevice : public BlockDeviceEntity Date: Wed, 8 Dec 2021 15:22:55 +0200 Subject: [PATCH 08/54] Implemented working draft of FS driver and heap-block-device --- Firmware/CMakeLists.txt | 4 +- Firmware/firmware_tests/CMakeLists.txt | 1 - .../firmware_tests/coroutine/CMakeLists.txt | 3 + .../coroutine/coroutine_thoughts.cpp | 63 +++++++++++++++++-- .../coroutine/wrapper/heap_block_device.hpp | 50 ++++++++------- 5 files changed, 90 insertions(+), 31 deletions(-) diff --git a/Firmware/CMakeLists.txt b/Firmware/CMakeLists.txt index 8fae51f7..16135e98 100644 --- a/Firmware/CMakeLists.txt +++ b/Firmware/CMakeLists.txt @@ -43,12 +43,12 @@ elseif(${TARGET_PLATFORM} STREQUAL "FIRMWARE_SIMULATOR") include(${CMAKE_BINARY_DIR}/conan.cmake) - conan_cmake_configure(REQUIRES sdl/2.0.16 gtest/1.11.0 + conan_cmake_configure(REQUIRES sdl/2.0.16 gtest/1.11.0 spdlog/1.9.2 GENERATORS cmake_find_package IMPORTS "bin, *.dll -> ${CMAKE_CURRENT_BINARY_DIR}" IMPORTS "lib, *.dylib* -> ${CMAKE_CURRENT_BINARY_DIR}" OPTIONS sdl:shared=True - OPTIONS fmt:shared=True + OPTIONS spdlog:header_only=True ) conan_cmake_autodetect(settings) diff --git a/Firmware/firmware_tests/CMakeLists.txt b/Firmware/firmware_tests/CMakeLists.txt index 1d52f398..b13b7531 100644 --- a/Firmware/firmware_tests/CMakeLists.txt +++ b/Firmware/firmware_tests/CMakeLists.txt @@ -10,7 +10,6 @@ set (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}) enable_testing() -set (3RDPARTY_DIR "../3rdparty") find_package(GTest REQUIRED) add_subdirectory(coroutine) add_subdirectory(article_example) diff --git a/Firmware/firmware_tests/coroutine/CMakeLists.txt b/Firmware/firmware_tests/coroutine/CMakeLists.txt index 736fe386..bf43c426 100644 --- a/Firmware/firmware_tests/coroutine/CMakeLists.txt +++ b/Firmware/firmware_tests/coroutine/CMakeLists.txt @@ -6,6 +6,8 @@ if( UNIX ) find_package(Threads REQUIRED) endif() +find_package(spdlog REQUIRED) + add_executable(coroutine_experiments_app ${PROJECT_SOURCES}) target_sources( @@ -49,6 +51,7 @@ target_link_libraries( UtilsLibrary logger_service littlefs + spdlog::spdlog ) if(UNIX) target_link_libraries( coroutine_experiments_app PUBLIC Threads::Threads) diff --git a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp index bc1bf896..d56a7e3c 100644 --- a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp +++ b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp @@ -41,16 +41,71 @@ using TFilesystem = Platform::Fs::Holder>; +void simpleRwTest(TFilesystem& filesystem, std::string_view fileName, std::string_view fileData) +{ + auto lfs = filesystem.fsInstance(); + auto file = lfs_file_t{}; + + lfs_file_open(&lfs, &file, fileName.data(), LFS_O_RDWR | LFS_O_CREAT); + lfs_file_write(&lfs, &file, fileData.data(), fileData.size()); + lfs_file_close(&lfs, &file); + std::vector readFrom; + readFrom.resize(fileData.size()); + + lfs_file_open(&lfs, &file, fileName.data(), LFS_O_RDWR | LFS_O_CREAT); + lfs_file_read(&lfs, &file, readFrom.data(), fileData.size()); + lfs_file_close(&lfs, &file); + + auto kCompareStringView{std::string_view{readFrom.data(), readFrom.size()}}; + assert(fileData == kCompareStringView); +} CoroUtils::VoidTask fileTest(TFilesystem& filesystem) { - auto file = filesystem.openFile("test.txt"); + auto fileWrapped = filesystem.openFile("test"); constexpr auto kFileData = std::string_view("Hello world!"); - co_await file.write( + simpleRwTest(filesystem, "helloworld.txt", kFileData); + + auto kNmeaDataExample = std::string_view{ + "$GPGSA,A,1,,,,,,,,,,,,,,,* 1E\n" + "$GPGSV,1,1,0,,,,,,,,,,,,,,,,* 49\n" + "$GPRMC,114811.00,A,5548.2054190,N,03732.8518300,E,0.22,0.00,210618,0.0,E,A * 30\n" + "$GPGGA,114811.00,5548.2054190,N,03732.8518300,E,1,06,1.0,179.534,M,14.753,M,0.0,* 45\n" + "$GPGSA,A,3,02,21,25,26,31,,,,,,,,5.4,1.2,5.3,1 * 2B\n" + "$GAGSA,A,3,30,,,,,,,,,,,,0.0,0.0,0.0,3 * 3F\n" + "$GPGSV,2,1,05,02,23,059,28,21,30,222,32,25,41,166,35,26,36,303,34,1 * 67\n" + "$GPGSV,2,2,05,31,27,254,34,,,,,,,,,,,,,1 * 52\n" + "$GAGSV,1,1,01,30,23,183,33,,,,,,,,,,,,,7 * 4A\n" + "$GPRMC,114812.00,A,5548.2052305,N,03732.8513810,E,0.17,0.00,210618,0.0,E,A * 3C\n" + "$GPGGA,114812.00,5548.2052305,N,03732.8513810,E,1,06,1.0,178.149,M,14.753,M,0.0,* 40\n" + "$GPGSA,A,3,02,21,25,26,31,,,,,,,,5.4,1.2,5.3,1 * 2B\n" + "$GAGSA,A,3,30,,,,,,,,,,,,0.0,0.0,0.0,3 * 3F\n" + "$GPGSV,2,1,05,02,23,059,28,21,30,222,31,25,41,166,36,26,36,303,34,1 * 67\n" + "$GPGSV,2,2,05,31,27,254,34,,,,,,,,,,,,,1 * 52\n" + "$GAGSV,1,1,01,30,23,183,32,,,,,,,,,,,,,7 * 4B\n" + "$GPRMC,114813.00,A,5548.2048307,N,03732.8514121,E,0.28,0.00,210618,0.0,E,A * 34\n" + "$GPGGA,114813.00,5548.2048307,N,03732.8514121,E,1,06,1.0,172.326,M,14.753,M,0.0,* 45\n" + "$GPGSA,A,3,02,21,25,26,31,,,,,,,,5.4,1.2,5.3,1 * 2B\n" + "$GAGSA,A,3,30,,,,,,,,,,,,0.0,0.0,0.0,3 * 3F\n" + "$GPGSV,2,1,05,02,23,059,28,21,31,222,32,25,41,166,36,26,36,303,34,1 * 65\n" + "$GPGSV,2,2,05,31,27,254,34,,,,,,,,,,,,,1 * 52\n" + "$GAGSV,1,1,01,30,23,183,32,,,,,,,,,,,,,7 * 4B\n" + "$GPRMC,114814.00,A,5548.2047440,N,03732.8516481,E,0.19,0.00,210618,0.0,E,A * 37\n" + "$GPGGA,114814.00,5548.2047440,N,03732.8516481,E,1,06,1.0,172.488,M,14.753,M,0.0,* 47\n" + "$GPGSA,A,3,02,21,25,26,31,,,,,,,,5.4,1.2,5.3,1 * 2B\n" + "$GAGSA,A,3,30,,,,,,,,,,,,0.0,0.0,0.0,3 * 3F\n" + "$GPGSV,2,1,05,02,23,059,28,21,31,222,32,25,41,166,35,26,36,303,34,1 * 66\n" + "$GPGSV,2,2,05,31,27,254,34,,,,,,,,,,,,,1 * 52\n" + "$GAGSV,1,1,01,30,23,183,32,,,,,,,,,,,,,7 * 4B\n" + + }; + simpleRwTest(filesystem, "nmeaData.txt", kNmeaDataExample); + + /*co_await file.write( {reinterpret_cast(kFileData.data()), kFileData.size()}); - auto data = co_await file.read(kFileData.size()); + auto data = co_await file.read(kFileData.size());*/ - std::cout << std::string_view(reinterpret_cast(data.data()), data.size()); + co_return; } int main() diff --git a/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp b/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp index eae1887c..29928912 100644 --- a/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp +++ b/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp @@ -3,6 +3,8 @@ #include "ih_block_device.hpp" #include +#include + namespace Wrapper { inline constexpr std::size_t kBlockSize = 256; @@ -10,15 +12,19 @@ inline constexpr std::size_t kSectorsCount = 65'536; inline constexpr std::size_t kReadSize = 256; inline constexpr std::size_t kEraseSize = 4096; -template +template < + std::size_t BlockSize = kBlockSize, + std::size_t SectorsCount = kSectorsCount, + std::size_t ReadSize = kReadSize, + std::size_t EraseSize = kEraseSize> class HeapBlockDevice : public BlockDeviceEntity> { public: - HeapBlockDevice() { m_blockStorage.resize(SectorsCount); - std::ranges::for_each(m_blockStorage, [](auto& storageBlock) { std::ranges::fill(storageBlock, 0xFF); }); + std::ranges::for_each( + m_blockStorage, [](auto& storageBlock) { std::ranges::fill(storageBlock, 0xFF); }); } constexpr std::uint32_t getBlockSize() const noexcept @@ -44,35 +50,31 @@ class HeapBlockDevice : public BlockDeviceEntity(_blockData); - while(requestSize>0) - { - std::uint32_t highPart = _address / getEraseSize(); - std::uint32_t lowPart = _address % getEraseSize(); - auto& pBlock = m_blockStorage[highPart]; - memcpy(pBlock.data() + lowPart, pBlockRequest, getProgSize()); - - pBlockRequest += getProgSize(); - _address += getProgSize(); - requestSize -= getProgSize(); - } + + std::uint32_t highPart = _address / getBlockSize(); + std::uint32_t lowPart = _address % getBlockSize(); + + auto& pBlock = m_blockStorage[highPart]; + memcpy(pBlock.data() + lowPart, pBlockRequest, _blockSize); } void read(std::uint8_t* _pBlockOut, std::uint32_t _address, std::uint32_t _blockSize) noexcept { - while (_blockSize > 0) - { - std::uint32_t hi = _address / getEraseSize(); - std::uint32_t lo = _address % getEraseSize(); + spdlog::info("HeapBlockDevice::READ to: address:{0} blockSize: {1}", _address, _blockSize); - memcpy(_pBlockOut, m_blockStorage[hi].data() + lo, getReadSize()); + std::uint32_t hi = _address / getBlockSize(); + std::uint32_t lo = _address % getBlockSize(); - _pBlockOut += getReadSize(); - _address += getReadSize(); - _blockSize -= getReadSize(); - } + memcpy(_pBlockOut, m_blockStorage[hi].data() + lo, _blockSize); } private: From a8a1323e9bf8712a9053d22bbe4ef90def96cbe8 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Wed, 8 Dec 2021 15:28:27 +0200 Subject: [PATCH 09/54] Fixed startup buffer crash --- Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp index d56a7e3c..8fd273ac 100644 --- a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp +++ b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp @@ -62,7 +62,7 @@ void simpleRwTest(TFilesystem& filesystem, std::string_view fileName, std::strin CoroUtils::VoidTask fileTest(TFilesystem& filesystem) { - auto fileWrapped = filesystem.openFile("test"); + /* auto fileWrapped = filesystem.openFile("test");*/ constexpr auto kFileData = std::string_view("Hello world!"); simpleRwTest(filesystem, "helloworld.txt", kFileData); From fb05ca943903176a9049b3238efbde516ac24c41 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Fri, 10 Dec 2021 12:59:58 +0200 Subject: [PATCH 10/54] Impleemnted support of the small chunks reading [FILESYTEM] --- .../coroutine/wrapper/heap_block_device.hpp | 41 ++++++++++++++----- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp b/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp index 29928912..5cd55908 100644 --- a/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp +++ b/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp @@ -16,7 +16,8 @@ template < std::size_t BlockSize = kBlockSize, std::size_t SectorsCount = kSectorsCount, std::size_t ReadSize = kReadSize, - std::size_t EraseSize = kEraseSize> + std::size_t EraseSize = kEraseSize, + std::size_t ProgSize = kReadSize> class HeapBlockDevice : public BlockDeviceEntity> { public: @@ -41,7 +42,7 @@ class HeapBlockDevice : public BlockDeviceEntity(_blockData); - std::uint32_t highPart = _address / getBlockSize(); - std::uint32_t lowPart = _address % getBlockSize(); + std::uint32_t requestSize = _blockSize; + const std::uint8_t* pBlockRequest = _blockData; + std::uint32_t blockAddress{ _address }; + while (requestSize > 0) + { + std::uint32_t highPart = blockAddress / getBlockSize(); + std::uint32_t lowPart = blockAddress % getBlockSize(); + + auto& pBlock = m_blockStorage[highPart]; + memcpy(pBlock.data() + lowPart, pBlockRequest, getProgSize()); - auto& pBlock = m_blockStorage[highPart]; - memcpy(pBlock.data() + lowPart, pBlockRequest, _blockSize); + blockAddress += getProgSize(); + pBlockRequest += getProgSize(); + requestSize -= getProgSize(); + } } void read(std::uint8_t* _pBlockOut, std::uint32_t _address, std::uint32_t _blockSize) noexcept { spdlog::info("HeapBlockDevice::READ to: address:{0} blockSize: {1}", _address, _blockSize); - std::uint32_t hi = _address / getBlockSize(); - std::uint32_t lo = _address % getBlockSize(); + std::uint32_t blockSize{ _blockSize }; + std::uint8_t* pReadBuffer{ _pBlockOut }; + std::uint32_t blockAddress{ _address }; + + while (blockSize > 0) + { + std::uint32_t hi = blockAddress / getBlockSize(); + std::uint32_t lo = blockAddress % getBlockSize(); - memcpy(_pBlockOut, m_blockStorage[hi].data() + lo, _blockSize); + memcpy(pReadBuffer, m_blockStorage[hi].data() + lo, getReadSize()); + blockAddress += getReadSize(); + pReadBuffer += getReadSize(); + blockSize -= getReadSize(); + } } private: From c5b365e8ccec1d7ca7ad5235ebf8b6d301f06be0 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Fri, 10 Dec 2021 13:25:31 +0200 Subject: [PATCH 11/54] Corrected template parameters for CRTP[FILESYTEM] --- .../firmware_tests/coroutine/wrapper/heap_block_device.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp b/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp index 5cd55908..e2357922 100644 --- a/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp +++ b/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp @@ -18,10 +18,10 @@ template < std::size_t ReadSize = kReadSize, std::size_t EraseSize = kEraseSize, std::size_t ProgSize = kReadSize> -class HeapBlockDevice : public BlockDeviceEntity> +class HeapBlockDevice : public BlockDeviceEntity> { public: - HeapBlockDevice() + constexpr HeapBlockDevice() { m_blockStorage.resize(SectorsCount); std::ranges::for_each( @@ -76,7 +76,7 @@ class HeapBlockDevice : public BlockDeviceEntity Date: Sat, 11 Dec 2021 15:59:14 +0200 Subject: [PATCH 12/54] An attempt to add coroutines support to the FS driver [FILESYSTEM] --- .../coroutine/coroutine_thoughts.cpp | 30 ++++++++++------- .../coroutine/fs_ideas/filesystem_holder.hpp | 32 ++++++++----------- 2 files changed, 32 insertions(+), 30 deletions(-) diff --git a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp index 8fd273ac..9867df19 100644 --- a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp +++ b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp @@ -22,6 +22,7 @@ #include "fs_ideas/platform_filesystem.hpp" #include "wrapper/heap_block_device.hpp" +#include CoroUtils::Task coroutineTask() { @@ -41,23 +42,30 @@ using TFilesystem = Platform::Fs::Holder>; -void simpleRwTest(TFilesystem& filesystem, std::string_view fileName, std::string_view fileData) +CoroUtils::VoidTask simpleRwTest(TFilesystem& filesystem, std::string_view fileName, std::string_view fileData) { + spdlog::warn("simpleRwTest begin"); auto lfs = filesystem.fsInstance(); - auto file = lfs_file_t{}; + { + spdlog::warn("FILE open begin"); + auto holdedFile = filesystem.openFile(fileName); + co_await holdedFile.write(std::span(reinterpret_cast(fileData.data()), fileData.size())); + spdlog::warn("FILE open finalize"); + } - lfs_file_open(&lfs, &file, fileName.data(), LFS_O_RDWR | LFS_O_CREAT); - lfs_file_write(&lfs, &file, fileData.data(), fileData.size()); - lfs_file_close(&lfs, &file); - std::vector readFrom; + std::vector readFrom; readFrom.resize(fileData.size()); - lfs_file_open(&lfs, &file, fileName.data(), LFS_O_RDWR | LFS_O_CREAT); - lfs_file_read(&lfs, &file, readFrom.data(), fileData.size()); - lfs_file_close(&lfs, &file); + { + spdlog::warn("FILE read begin"); + auto holdedFile = filesystem.openFile(fileName); + //co_await holdedFile.read(std::span(readFrom.data(), fileData.size())); + spdlog::warn("FILE read finalize"); + } - auto kCompareStringView{std::string_view{readFrom.data(), readFrom.size()}}; + auto kCompareStringView{std::string_view{reinterpret_cast(readFrom.data()), readFrom.size()}}; assert(fileData == kCompareStringView); + spdlog::warn("simpleRwTest finalize"); } CoroUtils::VoidTask fileTest(TFilesystem& filesystem) { @@ -99,7 +107,7 @@ CoroUtils::VoidTask fileTest(TFilesystem& filesystem) "$GAGSV,1,1,01,30,23,183,32,,,,,,,,,,,,,7 * 4B\n" }; - simpleRwTest(filesystem, "nmeaData.txt", kNmeaDataExample); + co_await simpleRwTest(filesystem, "nmeaData.txt", kNmeaDataExample); /*co_await file.write( {reinterpret_cast(kFileData.data()), kFileData.size()}); diff --git a/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp b/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp index 0669bb9f..d70ad4fd 100644 --- a/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp +++ b/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp @@ -9,6 +9,8 @@ #include #include +#include + namespace Platform::Fs { template class File; @@ -52,16 +54,7 @@ template class Holder { lfs_file_t file{}; lfs_file_open(&m_fsInstance, &file, path.data(), LFS_O_RDWR | LFS_O_CREAT); - return File{file, this}; - } - - void close(File* pFile)noexcept - { - assert(pFile); - if (!pFile) - return; - auto nativeHandle = pFile->nativeHandle(FilesystemPasskey{}); - lfs_file_close(&m_fsInstance, &nativeHandle); + return File{std::move(file), &m_fsInstance }; } constexpr TBlockDeviceEntity& getBlockDevice()noexcept @@ -153,25 +146,26 @@ template class File { public: explicit constexpr File()noexcept = default; - explicit constexpr File(lfs_file_t fileHandle, TFilesystemHolder* pFsHolder)noexcept - : m_pFileHandle{fileHandle}, m_pFsHolder{pFsHolder} + explicit constexpr File(lfs_file_t&& fileHandle, lfs_t* pFsHolder)noexcept + : m_pFileHandle{ std::move( fileHandle )}, m_pFsHolder{ pFsHolder } { + spdlog::warn("File::File()"); } ~File() { - if (m_pFsHolder) - m_pFsHolder->close(this); + lfs_file_close(m_pFsHolder, &m_pFileHandle); + spdlog::warn("~File::File()"); } CoroUtils::VoidTask write(std::span dataHolder)noexcept { - auto fsInstance = m_pFsHolder->fsInstance(); - lfs_file_write(&fsInstance, &m_pFileHandle, dataHolder.data(), static_cast(dataHolder.size())); + lfs_file_write(m_pFsHolder, &m_pFileHandle, dataHolder.data(), static_cast(dataHolder.size())); co_return; } - CoroUtils::Task> read(std::size_t dataSize)noexcept + CoroUtils::Task> read(std::span outBuffer)noexcept { - co_return {}; + lfs_file_read(m_pFsHolder, &m_pFileHandle, outBuffer.data(), static_cast(outBuffer.size())); + co_return outBuffer; } lfs_file_t nativeHandle(const FilesystemPasskey& passkey)noexcept @@ -182,6 +176,6 @@ template class File private: lfs_file_t m_pFileHandle; - TFilesystemHolder* m_pFsHolder; + lfs_t* m_pFsHolder; }; } // namespace Platform::Fs From 6182218e7f8f149cb46c0a420819110a960290de Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Tue, 4 Jan 2022 17:16:24 +0200 Subject: [PATCH 13/54] Fixed draft FS coroutines example #17 --- Firmware/3rdparty/littlefs_lib/CMakeLists.txt | 2 +- .../coroutine/coroutine_thoughts.cpp | 35 +++------ .../coroutine/fs_ideas/filesystem_holder.hpp | 71 ++++++++++++------- .../coroutine/wrapper/heap_block_device.hpp | 2 +- .../coroutine/wrapper/ih_block_device.hpp | 2 +- 5 files changed, 60 insertions(+), 52 deletions(-) diff --git a/Firmware/3rdparty/littlefs_lib/CMakeLists.txt b/Firmware/3rdparty/littlefs_lib/CMakeLists.txt index 98174ed0..1db572f8 100644 --- a/Firmware/3rdparty/littlefs_lib/CMakeLists.txt +++ b/Firmware/3rdparty/littlefs_lib/CMakeLists.txt @@ -14,4 +14,4 @@ target_include_directories(littlefs PUBLIC $ ) -target_compile_definitions(littlefs PUBLIC LFS_YES_TRACE) \ No newline at end of file +target_compile_definitions(littlefs PUBLIC LFS_YES_TRACE ) \ No newline at end of file diff --git a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp index 9867df19..29daa2bb 100644 --- a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp +++ b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp @@ -24,32 +24,24 @@ #include "wrapper/heap_block_device.hpp" #include -CoroUtils::Task coroutineTask() -{ - int b = 32; - - co_return b; -} - -void showFlashDeviceId() -{ - CoroUtils::Task task = coroutineTask(); - int testValue = co_await task; -} using TFilesystem = Platform::Fs::Holder>; -CoroUtils::VoidTask simpleRwTest(TFilesystem& filesystem, std::string_view fileName, std::string_view fileData) +CoroUtils::VoidTask simpleRwTest( + TFilesystem& filesystem, + std::string_view fileName, + std::string_view fileData) { spdlog::warn("simpleRwTest begin"); auto lfs = filesystem.fsInstance(); { spdlog::warn("FILE open begin"); - auto holdedFile = filesystem.openFile(fileName); - co_await holdedFile.write(std::span(reinterpret_cast(fileData.data()), fileData.size())); + auto filename{filesystem.openFile(fileName)}; + co_await filename.write( + std::span(reinterpret_cast(fileData.data()), fileData.size())); spdlog::warn("FILE open finalize"); } @@ -59,18 +51,17 @@ CoroUtils::VoidTask simpleRwTest(TFilesystem& filesystem, std::string_view fileN { spdlog::warn("FILE read begin"); auto holdedFile = filesystem.openFile(fileName); - //co_await holdedFile.read(std::span(readFrom.data(), fileData.size())); + co_await holdedFile.read(std::span(readFrom.data(), fileData.size())); spdlog::warn("FILE read finalize"); } - auto kCompareStringView{std::string_view{reinterpret_cast(readFrom.data()), readFrom.size()}}; + auto kCompareStringView{ + std::string_view{reinterpret_cast(readFrom.data()), readFrom.size()}}; assert(fileData == kCompareStringView); spdlog::warn("simpleRwTest finalize"); } CoroUtils::VoidTask fileTest(TFilesystem& filesystem) { - - /* auto fileWrapped = filesystem.openFile("test");*/ constexpr auto kFileData = std::string_view("Hello world!"); simpleRwTest(filesystem, "helloworld.txt", kFileData); @@ -109,10 +100,6 @@ CoroUtils::VoidTask fileTest(TFilesystem& filesystem) }; co_await simpleRwTest(filesystem, "nmeaData.txt", kNmeaDataExample); - /*co_await file.write( - {reinterpret_cast(kFileData.data()), kFileData.size()}); - auto data = co_await file.read(kFileData.size());*/ - co_return; } @@ -140,8 +127,6 @@ int main() //}; // displayCoro.fillRectangle(0, 0, 0, 0, nullptr); - showFlashDeviceId(); - while (true) { using namespace std::chrono_literals; diff --git a/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp b/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp index d70ad4fd..ff00d144 100644 --- a/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp +++ b/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp @@ -36,7 +36,7 @@ template class Holder using This_t = Holder; public: - constexpr Holder()noexcept + constexpr Holder() noexcept { m_fsConfig = createLfsConfig(); auto error = lfs_mount(&m_fsInstance, &m_fsConfig); @@ -46,18 +46,24 @@ template class Holder lfs_mount(&m_fsInstance, &m_fsConfig); } } - constexpr auto fsInstance() noexcept + + constexpr decltype(auto) fsInstance() noexcept { - return m_fsInstance; + return &m_fsInstance; } - File openFile(std::string_view path)noexcept + File openFile(std::string_view path) noexcept { - lfs_file_t file{}; - lfs_file_open(&m_fsInstance, &file, path.data(), LFS_O_RDWR | LFS_O_CREAT); - return File{std::move(file), &m_fsInstance }; + File retFile{&m_fsInstance}; + lfs_file_open( + &m_fsInstance, + retFile.nativeHandle(FilesystemPasskey{}), + path.data(), + LFS_O_RDWR | LFS_O_CREAT); + + return retFile; } - constexpr TBlockDeviceEntity& getBlockDevice()noexcept + constexpr TBlockDeviceEntity& getBlockDevice() noexcept { return m_blockDeviceHolder; } @@ -69,7 +75,7 @@ template class Holder lfs_block_t block, lfs_off_t off, void* buffer, - lfs_size_t size)noexcept + lfs_size_t size) noexcept { auto pThis = reinterpret_cast(c->context); pThis->getBlockDevice().read( @@ -82,7 +88,7 @@ template class Holder lfs_block_t block, lfs_off_t off, const void* buffer, - lfs_size_t size)noexcept + lfs_size_t size) noexcept { auto pThis = reinterpret_cast(c->context); pThis->getBlockDevice().write( @@ -91,13 +97,13 @@ template class Holder return LFS_ERR_OK; } - constexpr static int eraseCall(const struct lfs_config* c, lfs_block_t block)noexcept + constexpr static int eraseCall(const struct lfs_config* c, lfs_block_t block) noexcept { auto pThis = reinterpret_cast(c->context); return LFS_ERR_OK; } - constexpr static int syncCall(const struct lfs_config* c)noexcept + constexpr static int syncCall(const struct lfs_config* c) noexcept { auto pThis = reinterpret_cast(c->context); return LFS_ERR_OK; @@ -145,37 +151,54 @@ template class Holder template class File { public: - explicit constexpr File()noexcept = default; - explicit constexpr File(lfs_file_t&& fileHandle, lfs_t* pFsHolder)noexcept - : m_pFileHandle{ std::move( fileHandle )}, m_pFsHolder{ pFsHolder } + explicit constexpr File(lfs_t* pFsHolder) noexcept + : m_pFileHandle{std::make_unique()}, m_pFsHolder{pFsHolder} + { + } + + constexpr File(File&& otherHandle) noexcept + : m_pFileHandle{std::move(otherHandle.m_pFileHandle)} + , m_pFsHolder{std::exchange(otherHandle.m_pFsHolder, nullptr)} { - spdlog::warn("File::File()"); } + ~File() { - lfs_file_close(m_pFsHolder, &m_pFileHandle); + if (!m_pFsHolder) + return; + + lfs_file_close(m_pFsHolder, m_pFileHandle.get()); spdlog::warn("~File::File()"); } - CoroUtils::VoidTask write(std::span dataHolder)noexcept + + CoroUtils::VoidTask write(std::span dataHolder) noexcept { - lfs_file_write(m_pFsHolder, &m_pFileHandle, dataHolder.data(), static_cast(dataHolder.size())); + lfs_file_write( + m_pFsHolder, + m_pFileHandle.get(), + dataHolder.data(), + static_cast(dataHolder.size())); co_return; } - CoroUtils::Task> read(std::span outBuffer)noexcept + CoroUtils::Task> read(std::span outBuffer) noexcept { - lfs_file_read(m_pFsHolder, &m_pFileHandle, outBuffer.data(), static_cast(outBuffer.size())); + lfs_file_read( + m_pFsHolder, + m_pFileHandle.get(), + outBuffer.data(), + static_cast(outBuffer.size())); co_return outBuffer; } - lfs_file_t nativeHandle(const FilesystemPasskey& passkey)noexcept + lfs_file_t* nativeHandle(const FilesystemPasskey& passkey) noexcept { Meta::UnuseVar(passkey); - return m_pFileHandle; + return m_pFileHandle.get(); } private: - lfs_file_t m_pFileHandle; + std::unique_ptr m_pFileHandle; lfs_t* m_pFsHolder; }; } // namespace Platform::Fs diff --git a/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp b/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp index e2357922..68d07aaf 100644 --- a/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp +++ b/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp @@ -52,7 +52,7 @@ class HeapBlockDevice : public BlockDeviceEntity class BlockDeviceEntity return offspring()->getEraseSize(); } - constexpr void write(std::uint32_t _address, const std::uint8_t* _blockData, std::size_t _blockSize) noexcept + constexpr void write(std::uint32_t _address, const std::uint8_t* _blockData, std::uint32_t _blockSize) noexcept { offspring()->write(_address, _blockData, _blockSize); } From f1b2c46a59d83c5dfb9254af0bd336f8fbe95bfd Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Tue, 18 Jan 2022 20:42:25 +0200 Subject: [PATCH 14/54] Implemented littlefs MVP with coroutines support --- Firmware/3rdparty/littlefs_lib/CMakeLists.txt | 10 +- .../firmware_tests/coroutine/CMakeLists.txt | 4 +- .../coroutine/coroutine_thoughts.cpp | 14 ++- .../coroutine/fs_ideas/filesystem_holder.hpp | 53 ++++++----- .../wrapper/adaptor_block_device.hpp | 95 +++++++++++++++++++ .../coroutine/wrapper/heap_block_device.hpp | 31 +++--- .../coroutine/wrapper/ih_block_device.hpp | 9 +- Firmware/utils/inc/utils/coroutine/Task.hpp | 9 +- 8 files changed, 164 insertions(+), 61 deletions(-) create mode 100644 Firmware/firmware_tests/coroutine/wrapper/adaptor_block_device.hpp diff --git a/Firmware/3rdparty/littlefs_lib/CMakeLists.txt b/Firmware/3rdparty/littlefs_lib/CMakeLists.txt index 1db572f8..9f2307e0 100644 --- a/Firmware/3rdparty/littlefs_lib/CMakeLists.txt +++ b/Firmware/3rdparty/littlefs_lib/CMakeLists.txt @@ -1,17 +1,17 @@ cmake_minimum_required(VERSION 3.14) -project(cppcoro LANGUAGES CXX) set(CMAKE_CXX_EXTENSIONS OFF) add_library(littlefs) target_sources(littlefs PRIVATE - "littlefs/lfs.c" - "littlefs/lfs_util.c" + "littlefs/lfs.cpp" + "littlefs/lfs_util.cpp" ) -target_include_directories(littlefs PUBLIC - $ +target_include_directories(littlefs PUBLIC littlefs ) +target_link_libraries(littlefs PUBLIC UtilsLibrary ) + target_compile_definitions(littlefs PUBLIC LFS_YES_TRACE ) \ No newline at end of file diff --git a/Firmware/firmware_tests/coroutine/CMakeLists.txt b/Firmware/firmware_tests/coroutine/CMakeLists.txt index bf43c426..59a9bb10 100644 --- a/Firmware/firmware_tests/coroutine/CMakeLists.txt +++ b/Firmware/firmware_tests/coroutine/CMakeLists.txt @@ -21,7 +21,7 @@ target_sources( fs_ideas/platform_filesystem.hpp wrapper/ih_block_device.hpp wrapper/heap_block_device.hpp -) + wrapper/adaptor_block_device.hpp) target_include_directories( coroutine_experiments_app @@ -55,4 +55,4 @@ target_link_libraries( ) if(UNIX) target_link_libraries( coroutine_experiments_app PUBLIC Threads::Threads) -endif() +endif() \ No newline at end of file diff --git a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp index 29daa2bb..21938038 100644 --- a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp +++ b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp @@ -22,13 +22,16 @@ #include "fs_ideas/platform_filesystem.hpp" #include "wrapper/heap_block_device.hpp" +#include "wrapper/adaptor_block_device.hpp" #include -using TFilesystem = Platform::Fs::Holder>; + Wrapper::kEraseSize>>>; + +using TFile = Platform::Fs::File; CoroUtils::VoidTask simpleRwTest( TFilesystem& filesystem, @@ -39,7 +42,7 @@ CoroUtils::VoidTask simpleRwTest( auto lfs = filesystem.fsInstance(); { spdlog::warn("FILE open begin"); - auto filename{filesystem.openFile(fileName)}; + auto filename = std::move(co_await filesystem.openFile(fileName)); co_await filename.write( std::span(reinterpret_cast(fileData.data()), fileData.size())); spdlog::warn("FILE open finalize"); @@ -50,8 +53,8 @@ CoroUtils::VoidTask simpleRwTest( { spdlog::warn("FILE read begin"); - auto holdedFile = filesystem.openFile(fileName); - co_await holdedFile.read(std::span(readFrom.data(), fileData.size())); + auto holdedFile = std::move(co_await filesystem.openFile(fileName)); + auto resultRead = co_await holdedFile.read(std::span(readFrom.data(), fileData.size())); spdlog::warn("FILE read finalize"); } @@ -107,6 +110,7 @@ int main() { TFilesystem platformFilesystem; + CoroUtils::syncWait(platformFilesystem.initializeFs()); CoroUtils::syncWait(fileTest(platformFilesystem)); diff --git a/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp b/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp index ff00d144..a42c89e2 100644 --- a/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp +++ b/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp @@ -36,14 +36,18 @@ template class Holder using This_t = Holder; public: - constexpr Holder() noexcept + Holder() noexcept { m_fsConfig = createLfsConfig(); - auto error = lfs_mount(&m_fsInstance, &m_fsConfig); + } + + CoroUtils::VoidTask initializeFs() + { + auto error = co_await lfs_mount(&m_fsInstance, &m_fsConfig); if (error) { - lfs_format(&m_fsInstance, &m_fsConfig); - lfs_mount(&m_fsInstance, &m_fsConfig); + co_await lfs_format(&m_fsInstance, &m_fsConfig); + co_await lfs_mount(&m_fsInstance, &m_fsConfig); } } @@ -51,16 +55,16 @@ template class Holder { return &m_fsInstance; } - File openFile(std::string_view path) noexcept + CoroUtils::Task> openFile(std::string_view path) noexcept { File retFile{&m_fsInstance}; - lfs_file_open( + auto error = co_await lfs_file_open( &m_fsInstance, retFile.nativeHandle(FilesystemPasskey{}), path.data(), LFS_O_RDWR | LFS_O_CREAT); - return retFile; + co_return retFile; } constexpr TBlockDeviceEntity& getBlockDevice() noexcept @@ -70,43 +74,43 @@ template class Holder private: private: - constexpr static int readCall( - const struct lfs_config* c, + static CoroUtils::Task readCall( + const lfs_config* c, lfs_block_t block, lfs_off_t off, void* buffer, lfs_size_t size) noexcept { auto pThis = reinterpret_cast(c->context); - pThis->getBlockDevice().read( + co_await pThis->getBlockDevice().read( static_cast(buffer), block * c->block_size + off, size); - return LFS_ERR_OK; + co_return LFS_ERR_OK; } - constexpr static int progCall( - const struct lfs_config* c, + static CoroUtils::Task progCall( + const lfs_config* c, lfs_block_t block, lfs_off_t off, const void* buffer, lfs_size_t size) noexcept { auto pThis = reinterpret_cast(c->context); - pThis->getBlockDevice().write( + co_await pThis->getBlockDevice().write( (block * c->block_size + off), reinterpret_cast(buffer), size); - return LFS_ERR_OK; + co_return LFS_ERR_OK; } - constexpr static int eraseCall(const struct lfs_config* c, lfs_block_t block) noexcept + static CoroUtils::Task eraseCall(const lfs_config* c, lfs_block_t block) noexcept { auto pThis = reinterpret_cast(c->context); - return LFS_ERR_OK; + co_return LFS_ERR_OK; } - constexpr static int syncCall(const struct lfs_config* c) noexcept + static CoroUtils::Task syncCall(const lfs_config* c) noexcept { auto pThis = reinterpret_cast(c->context); - return LFS_ERR_OK; + co_return LFS_ERR_OK; } private: @@ -151,7 +155,8 @@ template class Holder template class File { public: - explicit constexpr File(lfs_t* pFsHolder) noexcept + + constexpr File(lfs_t* pFsHolder) noexcept : m_pFileHandle{std::make_unique()}, m_pFsHolder{pFsHolder} { } @@ -164,16 +169,16 @@ template class File ~File() { - if (!m_pFsHolder) + if (!m_pFsHolder && !m_pFileHandle) return; - lfs_file_close(m_pFsHolder, m_pFileHandle.get()); + CoroUtils::syncWait(lfs_file_close(m_pFsHolder, m_pFileHandle.get())); spdlog::warn("~File::File()"); } CoroUtils::VoidTask write(std::span dataHolder) noexcept { - lfs_file_write( + co_await lfs_file_write( m_pFsHolder, m_pFileHandle.get(), dataHolder.data(), @@ -183,7 +188,7 @@ template class File CoroUtils::Task> read(std::span outBuffer) noexcept { - lfs_file_read( + co_await lfs_file_read( m_pFsHolder, m_pFileHandle.get(), outBuffer.data(), diff --git a/Firmware/firmware_tests/coroutine/wrapper/adaptor_block_device.hpp b/Firmware/firmware_tests/coroutine/wrapper/adaptor_block_device.hpp new file mode 100644 index 00000000..a24928e7 --- /dev/null +++ b/Firmware/firmware_tests/coroutine/wrapper/adaptor_block_device.hpp @@ -0,0 +1,95 @@ +#pragma once + +#include "ih_block_device.hpp" +#include + +#include + +template <> struct fmt::formatter> +{ + + constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) + { + + auto it = ctx.begin(), end = ctx.end(); + + if (it != end && *it == 'f') + { + ++it; + if (it != end && *it != '}') + throw format_error("invalid format"); + } + return it; + } + + template + auto format(const std::span& p, FormatContext& ctx) -> decltype(ctx.out()) + { + + auto tempFormatHolder = std::string_view{ + reinterpret_cast(p.data()), + reinterpret_cast(p.data()) + p.size()}; + auto dataSize = tempFormatHolder.length(); + + return format_to(ctx.out(), "{}", tempFormatHolder); + } +}; + +namespace Wrapper +{ + +template +class LogAdaptorBlockDevice : public BlockDeviceEntity> +{ + +public: + constexpr std::uint32_t getBlockSize() const noexcept + { + return m_wrappedNode.getBlockSize(); + } + constexpr std::uint32_t getBlocksCount() const noexcept + { + return m_wrappedNode.getBlocksCount(); + } + constexpr std::uint32_t getReadSize() const noexcept + { + return m_wrappedNode.getReadSize(); + } + constexpr std::uint32_t getProgSize() const noexcept + { + return m_wrappedNode.getProgSize(); + } + constexpr std::uint32_t getEraseSize() const noexcept + { + return m_wrappedNode.getEraseSize(); + } + + CoroUtils::VoidTask write( + std::uint32_t _address, + const std::uint8_t* _blockData, + std::uint32_t _blockSize) noexcept + { + spdlog::info( + "Block Device WRITE to address: {address} blockData: {span_data:f} ", + fmt::arg("address", _address), + fmt::arg("span_data", std::span(_blockData, _blockSize))); + + co_await m_wrappedNode.write(_address, _blockData, _blockSize); + } + CoroUtils::VoidTask read( + std::uint8_t* _pBlockOut, + std::uint32_t _address, + std::uint32_t _blockSize) noexcept + { + co_await m_wrappedNode.read(_pBlockOut, _address, _blockSize); + + spdlog::info( + "Block Device READ from address: {address} blockData: {span_data:f} ", + fmt::arg("address", _address), + fmt::arg("span_data", std::span(static_cast(_pBlockOut), _blockSize))); + } + +private: + TWrappee m_wrappedNode; +}; +} // namespace Wrapper \ No newline at end of file diff --git a/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp b/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp index 68d07aaf..b2ad746f 100644 --- a/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp +++ b/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp @@ -3,8 +3,6 @@ #include "ih_block_device.hpp" #include -#include - namespace Wrapper { inline constexpr std::size_t kBlockSize = 256; @@ -18,7 +16,9 @@ template < std::size_t ReadSize = kReadSize, std::size_t EraseSize = kEraseSize, std::size_t ProgSize = kReadSize> -class HeapBlockDevice : public BlockDeviceEntity> +class HeapBlockDevice + : public BlockDeviceEntity< + HeapBlockDevice> { public: constexpr HeapBlockDevice() @@ -49,20 +49,14 @@ class HeapBlockDevice : public BlockDeviceEntity 0) { std::uint32_t highPart = blockAddress / getBlockSize(); @@ -75,14 +69,16 @@ class HeapBlockDevice : public BlockDeviceEntity 0) { @@ -94,6 +90,7 @@ class HeapBlockDevice : public BlockDeviceEntity +#include namespace Wrapper { @@ -27,13 +28,13 @@ template class BlockDeviceEntity return offspring()->getEraseSize(); } - constexpr void write(std::uint32_t _address, const std::uint8_t* _blockData, std::uint32_t _blockSize) noexcept + CoroUtils::VoidTask write(std::uint32_t _address, const std::uint8_t* _blockData, std::uint32_t _blockSize) noexcept { - offspring()->write(_address, _blockData, _blockSize); + co_await offspring()->write(_address, _blockData, _blockSize); } - constexpr void read(std::uint8_t* pblockOut, std::uint32_t _address, std::uint32_t _blockSize) noexcept + CoroUtils::VoidTask read(std::uint8_t* pblockOut, std::uint32_t _address, std::uint32_t _blockSize) noexcept { - offspring()->read(pblockOut, _address, _blockSize); + co_await offspring()->read(pblockOut, _address, _blockSize); } private: diff --git a/Firmware/utils/inc/utils/coroutine/Task.hpp b/Firmware/utils/inc/utils/coroutine/Task.hpp index 20451c15..68030f08 100644 --- a/Firmware/utils/inc/utils/coroutine/Task.hpp +++ b/Firmware/utils/inc/utils/coroutine/Task.hpp @@ -28,9 +28,10 @@ template struct Task return stdcoro::suspend_always{}; } - void return_value(const TResult& _value) noexcept + template + void return_value(TResult&& _value) noexcept { - m_coroutineResult = _value; + m_coroutineResult.emplace(std::forward(_value)); } void set_continuation(stdcoro::coroutine_handle<> continuation) @@ -40,7 +41,7 @@ template struct Task TResult& result() { - return m_coroutineResult; + return *m_coroutineResult; } struct final_awaitable @@ -67,7 +68,7 @@ template struct Task return final_awaitable{}; } - TResult m_coroutineResult; + std::optional m_coroutineResult; stdcoro::coroutine_handle<> m_continuation; }; From d703133f11db6b03e3bd8f6808b1c3753f852c9a Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Tue, 18 Jan 2022 20:49:01 +0200 Subject: [PATCH 15/54] Removed littlefs original submodule --- .gitmodules | 3 --- Firmware/3rdparty/littlefs_lib/littlefs | 1 - 2 files changed, 4 deletions(-) delete mode 160000 Firmware/3rdparty/littlefs_lib/littlefs diff --git a/.gitmodules b/.gitmodules index baf748a9..25d679c3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,6 +16,3 @@ [submodule "Schematic/KiCadLibrariesRoot"] path = Schematic/KiCadLibrariesRoot url = https://github.com/ValentiWorkLearning/KiCadLibrariesRoot.git -[submodule "Firmware/3rdparty/littlefs_lib/littlefs"] - path = Firmware/3rdparty/littlefs_lib/littlefs - url = https://github.com/littlefs-project/littlefs.git diff --git a/Firmware/3rdparty/littlefs_lib/littlefs b/Firmware/3rdparty/littlefs_lib/littlefs deleted file mode 160000 index ead50807..00000000 --- a/Firmware/3rdparty/littlefs_lib/littlefs +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ead50807f1ca3fdf2da00b77a0ce02651ded2d13 From 3df39a0489ddd331d8a2109985b7a4a384265172 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Tue, 18 Jan 2022 20:51:40 +0200 Subject: [PATCH 16/54] Switched to original coro-based littlefs submodule --- .gitmodules | 3 +++ Firmware/3rdparty/littlefs_lib/littlefs | 1 + 2 files changed, 4 insertions(+) create mode 160000 Firmware/3rdparty/littlefs_lib/littlefs diff --git a/.gitmodules b/.gitmodules index 25d679c3..9de77fe9 100644 --- a/.gitmodules +++ b/.gitmodules @@ -16,3 +16,6 @@ [submodule "Schematic/KiCadLibrariesRoot"] path = Schematic/KiCadLibrariesRoot url = https://github.com/ValentiWorkLearning/KiCadLibrariesRoot.git +[submodule "Firmware/3rdparty/littlefs_lib/littlefs"] + path = Firmware/3rdparty/littlefs_lib/littlefs + url = https://github.com/ValentiWorkLearning/littlefs.git diff --git a/Firmware/3rdparty/littlefs_lib/littlefs b/Firmware/3rdparty/littlefs_lib/littlefs new file mode 160000 index 00000000..7f6f27d5 --- /dev/null +++ b/Firmware/3rdparty/littlefs_lib/littlefs @@ -0,0 +1 @@ +Subproject commit 7f6f27d54393e53f606faeb97ea639a4c8ee663c From 5166f71526e426f64fae863c3f12cce2d00b0f14 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Tue, 18 Jan 2022 20:53:03 +0200 Subject: [PATCH 17/54] Added build triggers to littlefs branch --- .github/workflows/build.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 80ccb6c9..4713d119 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,7 +4,7 @@ name: CI # events but only for the master branch on: push: - branches: [ master,dev/develop,dev/migration_gcc_desktop_build] + branches: [ master,dev/develop,dev/littlefs_impl] pull_request: branches: [ master,dev/develop] @@ -173,4 +173,4 @@ jobs: - name : Run firmware testing run: | cd ${{ env.buildDir }} - ./FirmwareTesting \ No newline at end of file + ./FirmwareTesting From feccd0603a042390055377d1092040432145b2bc Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Tue, 18 Jan 2022 21:01:37 +0200 Subject: [PATCH 18/54] Fixed build on ARM with shadowed template parameter #17 --- Firmware/utils/inc/utils/coroutine/Task.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Firmware/utils/inc/utils/coroutine/Task.hpp b/Firmware/utils/inc/utils/coroutine/Task.hpp index 68030f08..1796660f 100644 --- a/Firmware/utils/inc/utils/coroutine/Task.hpp +++ b/Firmware/utils/inc/utils/coroutine/Task.hpp @@ -28,10 +28,10 @@ template struct Task return stdcoro::suspend_always{}; } - template - void return_value(TResult&& _value) noexcept + template + void return_value(TResultType&& _value) noexcept { - m_coroutineResult.emplace(std::forward(_value)); + m_coroutineResult.emplace(std::forward(_value)); } void set_continuation(stdcoro::coroutine_handle<> continuation) From a02d90508c4bab32ef0a3ae9313d4c38c69cd762 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Wed, 19 Jan 2022 12:09:32 +0200 Subject: [PATCH 19/54] Added gtest suite for the filesystem handling #17 --- Firmware/CMakeLists.txt | 1 + .../adaptor_block_device.hpp | 0 .../heap_block_device.hpp | 0 .../block_device_wrapper}/ih_block_device.hpp | 0 .../filesystem}/filesystem_holder.hpp | 5 +- .../filesystem}/platform_filesystem.hpp | 0 Firmware/firmware_tests/CMakeLists.txt | 6 +- .../firmware_tests/coroutine/CMakeLists.txt | 12 +-- .../coroutine/coroutine_thoughts.cpp | 6 +- .../filesystem/filesystem_fixture.hpp | 42 +++++++++++ .../filesystem/filesystem_in_memory_test.cpp | 74 +++++++++++++++++++ 11 files changed, 129 insertions(+), 17 deletions(-) rename Firmware/{firmware_tests/coroutine/wrapper => filesystem/filesystem/block_device_wrapper}/adaptor_block_device.hpp (100%) rename Firmware/{firmware_tests/coroutine/wrapper => filesystem/filesystem/block_device_wrapper}/heap_block_device.hpp (100%) rename Firmware/{firmware_tests/coroutine/wrapper => filesystem/filesystem/block_device_wrapper}/ih_block_device.hpp (100%) rename Firmware/{firmware_tests/coroutine/fs_ideas => filesystem/filesystem}/filesystem_holder.hpp (97%) rename Firmware/{firmware_tests/coroutine/fs_ideas => filesystem/filesystem}/platform_filesystem.hpp (100%) create mode 100644 Firmware/firmware_tests/filesystem/filesystem_fixture.hpp create mode 100644 Firmware/firmware_tests/filesystem/filesystem_in_memory_test.cpp diff --git a/Firmware/CMakeLists.txt b/Firmware/CMakeLists.txt index 16135e98..1faa160c 100644 --- a/Firmware/CMakeLists.txt +++ b/Firmware/CMakeLists.txt @@ -70,6 +70,7 @@ add_subdirectory(utils) add_subdirectory(logger) add_subdirectory(graphics) add_subdirectory(service_providers) +add_subdirectory(filesystem) set (NORDIC_TARGET theOpenWatch) add_executable(${NORDIC_TARGET} ${PROJECT_SOURCES}) diff --git a/Firmware/firmware_tests/coroutine/wrapper/adaptor_block_device.hpp b/Firmware/filesystem/filesystem/block_device_wrapper/adaptor_block_device.hpp similarity index 100% rename from Firmware/firmware_tests/coroutine/wrapper/adaptor_block_device.hpp rename to Firmware/filesystem/filesystem/block_device_wrapper/adaptor_block_device.hpp diff --git a/Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp b/Firmware/filesystem/filesystem/block_device_wrapper/heap_block_device.hpp similarity index 100% rename from Firmware/firmware_tests/coroutine/wrapper/heap_block_device.hpp rename to Firmware/filesystem/filesystem/block_device_wrapper/heap_block_device.hpp diff --git a/Firmware/firmware_tests/coroutine/wrapper/ih_block_device.hpp b/Firmware/filesystem/filesystem/block_device_wrapper/ih_block_device.hpp similarity index 100% rename from Firmware/firmware_tests/coroutine/wrapper/ih_block_device.hpp rename to Firmware/filesystem/filesystem/block_device_wrapper/ih_block_device.hpp diff --git a/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp b/Firmware/filesystem/filesystem/filesystem_holder.hpp similarity index 97% rename from Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp rename to Firmware/filesystem/filesystem/filesystem_holder.hpp index a42c89e2..3ee863df 100644 --- a/Firmware/firmware_tests/coroutine/fs_ideas/filesystem_holder.hpp +++ b/Firmware/filesystem/filesystem/filesystem_holder.hpp @@ -1,9 +1,10 @@ #pragma once -#include "ih_block_device.hpp" +#include "block_device_wrapper/ih_block_device.hpp" #include #include #include -#include +#include +#include #include #include diff --git a/Firmware/firmware_tests/coroutine/fs_ideas/platform_filesystem.hpp b/Firmware/filesystem/filesystem/platform_filesystem.hpp similarity index 100% rename from Firmware/firmware_tests/coroutine/fs_ideas/platform_filesystem.hpp rename to Firmware/filesystem/filesystem/platform_filesystem.hpp diff --git a/Firmware/firmware_tests/CMakeLists.txt b/Firmware/firmware_tests/CMakeLists.txt index b13b7531..5d6fdc31 100644 --- a/Firmware/firmware_tests/CMakeLists.txt +++ b/Firmware/firmware_tests/CMakeLists.txt @@ -34,7 +34,9 @@ add_executable( drivers/windond_flash/flash_fixture.hpp drivers/spi/mock_gpio.hpp drivers/spi/mock_spi.hpp -) + + filesystem/filesystem_fixture.hpp + filesystem/filesystem_in_memory_test.cpp) mark_as_advanced( BUILD_GMOCK BUILD_GTEST BUILD_SHARED_LIBS @@ -62,7 +64,7 @@ target_link_libraries( watch_display lvgl_lib drivers_ih - + filesystem buttons_driver windbond_spi_flash_driver ) diff --git a/Firmware/firmware_tests/coroutine/CMakeLists.txt b/Firmware/firmware_tests/coroutine/CMakeLists.txt index 59a9bb10..661b4c70 100644 --- a/Firmware/firmware_tests/coroutine/CMakeLists.txt +++ b/Firmware/firmware_tests/coroutine/CMakeLists.txt @@ -6,8 +6,6 @@ if( UNIX ) find_package(Threads REQUIRED) endif() -find_package(spdlog REQUIRED) - add_executable(coroutine_experiments_app ${PROJECT_SOURCES}) target_sources( @@ -16,12 +14,7 @@ target_sources( coroutine_thoughts.cpp thoughts.hpp st7789_draft.hpp - fs_ideas/filesystem_holder.hpp - - fs_ideas/platform_filesystem.hpp - wrapper/ih_block_device.hpp - wrapper/heap_block_device.hpp - wrapper/adaptor_block_device.hpp) +) target_include_directories( coroutine_experiments_app @@ -50,8 +43,7 @@ target_link_libraries( watch_display UtilsLibrary logger_service - littlefs - spdlog::spdlog + filesystem ) if(UNIX) target_link_libraries( coroutine_experiments_app PUBLIC Threads::Threads) diff --git a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp index 21938038..9b1a48af 100644 --- a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp +++ b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp @@ -19,10 +19,10 @@ #include #include "st7789_draft.hpp" +#include +#include +#include -#include "fs_ideas/platform_filesystem.hpp" -#include "wrapper/heap_block_device.hpp" -#include "wrapper/adaptor_block_device.hpp" #include using TFilesystem = Platform::Fs::Holder + +#include +#include +#include + + +#include + +struct FilesystemParamInterfaceData +{ + std::string_view fileData; + std::string_view filename; +}; + +class FilesystemTopLevelTestFixture + : public ::testing::Test + , public ::testing::WithParamInterface +{ + +public: + + using TFilesystem = Platform::Fs::Holder>>; + + using TFile = Platform::Fs::File; + +protected: + void SetUp() override + { + CoroUtils::syncWait(m_testFilesystem.initializeFs()); + } + + + +protected: + TFilesystem m_testFilesystem; +}; \ No newline at end of file diff --git a/Firmware/firmware_tests/filesystem/filesystem_in_memory_test.cpp b/Firmware/firmware_tests/filesystem/filesystem_in_memory_test.cpp new file mode 100644 index 00000000..4b7d08ff --- /dev/null +++ b/Firmware/firmware_tests/filesystem/filesystem_in_memory_test.cpp @@ -0,0 +1,74 @@ +#include "filesystem_fixture.hpp" +#include +#include +#include + + +constexpr auto HelloWorldData = FilesystemParamInterfaceData{ .fileData = "Hello world!", .filename = "helloworld.txt" }; + +constexpr auto kNmeaDataExample = std::string_view{ + "$GPGSA,A,1,,,,,,,,,,,,,,,* 1E\n" + "$GPGSV,1,1,0,,,,,,,,,,,,,,,,* 49\n" + "$GPRMC,114811.00,A,5548.2054190,N,03732.8518300,E,0.22,0.00,210618,0.0,E,A * 30\n" + "$GPGGA,114811.00,5548.2054190,N,03732.8518300,E,1,06,1.0,179.534,M,14.753,M,0.0,* 45\n" + "$GPGSA,A,3,02,21,25,26,31,,,,,,,,5.4,1.2,5.3,1 * 2B\n" + "$GAGSA,A,3,30,,,,,,,,,,,,0.0,0.0,0.0,3 * 3F\n" + "$GPGSV,2,1,05,02,23,059,28,21,30,222,32,25,41,166,35,26,36,303,34,1 * 67\n" + "$GPGSV,2,2,05,31,27,254,34,,,,,,,,,,,,,1 * 52\n" + "$GAGSV,1,1,01,30,23,183,33,,,,,,,,,,,,,7 * 4A\n" + "$GPRMC,114812.00,A,5548.2052305,N,03732.8513810,E,0.17,0.00,210618,0.0,E,A * 3C\n" + "$GPGGA,114812.00,5548.2052305,N,03732.8513810,E,1,06,1.0,178.149,M,14.753,M,0.0,* 40\n" + "$GPGSA,A,3,02,21,25,26,31,,,,,,,,5.4,1.2,5.3,1 * 2B\n" + "$GAGSA,A,3,30,,,,,,,,,,,,0.0,0.0,0.0,3 * 3F\n" + "$GPGSV,2,1,05,02,23,059,28,21,30,222,31,25,41,166,36,26,36,303,34,1 * 67\n" + "$GPGSV,2,2,05,31,27,254,34,,,,,,,,,,,,,1 * 52\n" + "$GAGSV,1,1,01,30,23,183,32,,,,,,,,,,,,,7 * 4B\n" + "$GPRMC,114813.00,A,5548.2048307,N,03732.8514121,E,0.28,0.00,210618,0.0,E,A * 34\n" + "$GPGGA,114813.00,5548.2048307,N,03732.8514121,E,1,06,1.0,172.326,M,14.753,M,0.0,* 45\n" + "$GPGSA,A,3,02,21,25,26,31,,,,,,,,5.4,1.2,5.3,1 * 2B\n" + "$GAGSA,A,3,30,,,,,,,,,,,,0.0,0.0,0.0,3 * 3F\n" + "$GPGSV,2,1,05,02,23,059,28,21,31,222,32,25,41,166,36,26,36,303,34,1 * 65\n" + "$GPGSV,2,2,05,31,27,254,34,,,,,,,,,,,,,1 * 52\n" + "$GAGSV,1,1,01,30,23,183,32,,,,,,,,,,,,,7 * 4B\n" + "$GPRMC,114814.00,A,5548.2047440,N,03732.8516481,E,0.19,0.00,210618,0.0,E,A * 37\n" + "$GPGGA,114814.00,5548.2047440,N,03732.8516481,E,1,06,1.0,172.488,M,14.753,M,0.0,* 47\n" + "$GPGSA,A,3,02,21,25,26,31,,,,,,,,5.4,1.2,5.3,1 * 2B\n" + "$GAGSA,A,3,30,,,,,,,,,,,,0.0,0.0,0.0,3 * 3F\n" + "$GPGSV,2,1,05,02,23,059,28,21,31,222,32,25,41,166,35,26,36,303,34,1 * 66\n" + "$GPGSV,2,2,05,31,27,254,34,,,,,,,,,,,,,1 * 52\n" + "$GAGSV,1,1,01,30,23,183,32,,,,,,,,,,,,,7 * 4B\n" + +}; + +constexpr auto NmeaData = FilesystemParamInterfaceData{ .fileData = kNmeaDataExample,.filename = "nmea_data.txt" }; + + +TEST_P(FilesystemTopLevelTestFixture, CheckFileReadWriteProcedure) +{ + spdlog::warn("simpleRwTest begin"); + auto lfs = m_testFilesystem.fsInstance(); + { + auto filename = std::move(CoroUtils::syncWait(m_testFilesystem.openFile(GetParam().filename))); + CoroUtils::syncWait(filename.write( + std::span(reinterpret_cast(GetParam().fileData.data()), GetParam().fileData.size()))); + } + + std::vector readFrom; + readFrom.resize(GetParam().fileData.size()); + + { + auto holdedFile = std::move(CoroUtils::syncWait(m_testFilesystem.openFile(GetParam().filename))); + auto resultRead = CoroUtils::syncWait( holdedFile.read(std::span(readFrom.data(), GetParam().fileData.size()))); + } + + auto kCompareStringView{ + std::string_view{reinterpret_cast(readFrom.data()), readFrom.size()} }; + EXPECT_EQ(kCompareStringView, GetParam().fileData); +} + + +INSTANTIATE_TEST_SUITE_P( + FilesystemTopLevelTesting, + FilesystemTopLevelTestFixture, + ::testing::Values( + FilesystemParamInterfaceData{})); \ No newline at end of file From df06039e71eed93325cce0a454ee7c13c2519e2a Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Wed, 19 Jan 2022 16:09:16 +0200 Subject: [PATCH 20/54] Added forgotten CMakeLists.txt file to the filesystem #17 --- Firmware/filesystem/CMakeLists.txt | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 Firmware/filesystem/CMakeLists.txt diff --git a/Firmware/filesystem/CMakeLists.txt b/Firmware/filesystem/CMakeLists.txt new file mode 100644 index 00000000..e17ee6b2 --- /dev/null +++ b/Firmware/filesystem/CMakeLists.txt @@ -0,0 +1,21 @@ +if(WIN32 OR UNIX) + find_package(spdlog REQUIRED) +endif() + +add_library(filesystem INTERFACE filesystem/filesystem_holder.hpp) + +target_sources(filesystem INTERFACE + filesystem/block_device_wrapper/ih_block_device.hpp + filesystem/block_device_wrapper/heap_block_device.hpp + filesystem/block_device_wrapper/adaptor_block_device.hpp +) + +target_include_directories(filesystem INTERFACE ${CMAKE_CURRENT_LIST_DIR} ) + +target_link_libraries(filesystem INTERFACE + littlefs +) + +if(WIN32 OR UNIX) + target_link_libraries(filesystem INTERFACE spdlog::spdlog) +endif() \ No newline at end of file From 5041d7eb6f3117bb67ab763857376a15680090db Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Thu, 3 Feb 2022 23:02:38 +0200 Subject: [PATCH 21/54] Fixed coroutine filesystem tests #17 --- .../filesystem/filesystem_holder.hpp | 2 ++ .../filesystem/filesystem_in_memory_test.cpp | 29 ++++++++++--------- 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/Firmware/filesystem/filesystem/filesystem_holder.hpp b/Firmware/filesystem/filesystem/filesystem_holder.hpp index 3ee863df..b6250eae 100644 --- a/Firmware/filesystem/filesystem/filesystem_holder.hpp +++ b/Firmware/filesystem/filesystem/filesystem_holder.hpp @@ -11,6 +11,7 @@ #include #include +#include namespace Platform::Fs { @@ -58,6 +59,7 @@ template class Holder } CoroUtils::Task> openFile(std::string_view path) noexcept { + assert(!path.empty()); File retFile{&m_fsInstance}; auto error = co_await lfs_file_open( &m_fsInstance, diff --git a/Firmware/firmware_tests/filesystem/filesystem_in_memory_test.cpp b/Firmware/firmware_tests/filesystem/filesystem_in_memory_test.cpp index 4b7d08ff..8a1a0cac 100644 --- a/Firmware/firmware_tests/filesystem/filesystem_in_memory_test.cpp +++ b/Firmware/firmware_tests/filesystem/filesystem_in_memory_test.cpp @@ -3,8 +3,8 @@ #include #include - -constexpr auto HelloWorldData = FilesystemParamInterfaceData{ .fileData = "Hello world!", .filename = "helloworld.txt" }; +constexpr auto HelloWorldData = + FilesystemParamInterfaceData{.fileData = "Hello world!", .filename = "helloworld.txt"}; constexpr auto kNmeaDataExample = std::string_view{ "$GPGSA,A,1,,,,,,,,,,,,,,,* 1E\n" @@ -40,35 +40,36 @@ constexpr auto kNmeaDataExample = std::string_view{ }; -constexpr auto NmeaData = FilesystemParamInterfaceData{ .fileData = kNmeaDataExample,.filename = "nmea_data.txt" }; - +constexpr auto NmeaData = + FilesystemParamInterfaceData{.fileData = kNmeaDataExample, .filename = "nmea_data.txt"}; TEST_P(FilesystemTopLevelTestFixture, CheckFileReadWriteProcedure) { - spdlog::warn("simpleRwTest begin"); auto lfs = m_testFilesystem.fsInstance(); { - auto filename = std::move(CoroUtils::syncWait(m_testFilesystem.openFile(GetParam().filename))); - CoroUtils::syncWait(filename.write( - std::span(reinterpret_cast(GetParam().fileData.data()), GetParam().fileData.size()))); + auto filePath = GetParam().filename; + auto filename = std::move(CoroUtils::syncWait(m_testFilesystem.openFile(filePath))); + CoroUtils::syncWait(filename.write(std::span( + reinterpret_cast(GetParam().fileData.data()), + GetParam().fileData.size()))); } std::vector readFrom; readFrom.resize(GetParam().fileData.size()); { - auto holdedFile = std::move(CoroUtils::syncWait(m_testFilesystem.openFile(GetParam().filename))); - auto resultRead = CoroUtils::syncWait( holdedFile.read(std::span(readFrom.data(), GetParam().fileData.size()))); + auto holdedFile = + std::move(CoroUtils::syncWait(m_testFilesystem.openFile(GetParam().filename))); + auto resultRead = CoroUtils::syncWait( + holdedFile.read(std::span(readFrom.data(), GetParam().fileData.size()))); } auto kCompareStringView{ - std::string_view{reinterpret_cast(readFrom.data()), readFrom.size()} }; + std::string_view{reinterpret_cast(readFrom.data()), readFrom.size()}}; EXPECT_EQ(kCompareStringView, GetParam().fileData); } - INSTANTIATE_TEST_SUITE_P( FilesystemTopLevelTesting, FilesystemTopLevelTestFixture, - ::testing::Values( - FilesystemParamInterfaceData{})); \ No newline at end of file + ::testing::Values(HelloWorldData, NmeaData)); \ No newline at end of file From 1ac6a71b426e38131bc3ca2ca57b89e7d7c6c219 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Fri, 4 Feb 2022 15:30:23 +0200 Subject: [PATCH 22/54] Attempted to fixup GCC builds on ARM and desktop #17 --- Firmware/3rdparty/littlefs_lib/littlefs | 2 +- Firmware/utils/inc/utils/coroutine/Task.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/3rdparty/littlefs_lib/littlefs b/Firmware/3rdparty/littlefs_lib/littlefs index 7f6f27d5..e56e369d 160000 --- a/Firmware/3rdparty/littlefs_lib/littlefs +++ b/Firmware/3rdparty/littlefs_lib/littlefs @@ -1 +1 @@ -Subproject commit 7f6f27d54393e53f606faeb97ea639a4c8ee663c +Subproject commit e56e369d9ea4f48302525a08ba4679a72aca472e diff --git a/Firmware/utils/inc/utils/coroutine/Task.hpp b/Firmware/utils/inc/utils/coroutine/Task.hpp index 1796660f..e316294a 100644 --- a/Firmware/utils/inc/utils/coroutine/Task.hpp +++ b/Firmware/utils/inc/utils/coroutine/Task.hpp @@ -1,6 +1,6 @@ #pragma once #include "Common.hpp" - +#include namespace CoroUtils { From 63e2f9c5ff40179b2261b7a43529219389e669b7 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Sun, 6 Feb 2022 23:18:32 +0200 Subject: [PATCH 23/54] Added interface for spi-based block device wrapper #17 --- .../drivers/board/inc/board/watchboard.hpp | 4 ++-- Firmware/drivers/board/watchboard.cpp | 8 ++++---- Firmware/filesystem/CMakeLists.txt | 15 +++++++++++---- .../adaptor_block_device.hpp | 3 ++- .../heap_block_device.hpp | 2 +- .../block_device_wrapper/ih_block_device.hpp | 2 +- .../block_device_wrapper/spi_block_device.hpp | 14 ++++++++++++++ .../coroutine/coroutine_thoughts.cpp | 10 +++++----- .../filesystem/filesystem_fixture.hpp | 19 ++++++++----------- 9 files changed, 48 insertions(+), 29 deletions(-) create mode 100644 Firmware/filesystem/filesystem/block_device_wrapper/spi_block_device.hpp diff --git a/Firmware/drivers/board/inc/board/watchboard.hpp b/Firmware/drivers/board/inc/board/watchboard.hpp index 25cc5ef7..6abb89b5 100644 --- a/Firmware/drivers/board/inc/board/watchboard.hpp +++ b/Firmware/drivers/board/inc/board/watchboard.hpp @@ -1,7 +1,7 @@ #pragma once -#include "utils/FastPimpl.hpp" -#include "utils/Platform.hpp" +#include +#include #include "hardware_usings.hpp" #include diff --git a/Firmware/drivers/board/watchboard.cpp b/Firmware/drivers/board/watchboard.cpp index 5817185e..ae91d141 100644 --- a/Firmware/drivers/board/watchboard.cpp +++ b/Firmware/drivers/board/watchboard.cpp @@ -15,11 +15,11 @@ APP_TIMER_DEF(m_ledDriverTimer); #endif -#include "utils/CallbackConnector.hpp" -#include "utils/CoroUtils.hpp" +#include +#include -#include "delay/delay_provider.hpp" -#include "logger/logger_service.hpp" +#include +#include #if defined (USE_DEVICE_SPECIFIC) #define FMT_HEADER_ONLY diff --git a/Firmware/filesystem/CMakeLists.txt b/Firmware/filesystem/CMakeLists.txt index e17ee6b2..caf4648e 100644 --- a/Firmware/filesystem/CMakeLists.txt +++ b/Firmware/filesystem/CMakeLists.txt @@ -1,13 +1,14 @@ -if(WIN32 OR UNIX) +if(WIN32 OR UNIX AND ${TARGET_PLATFORM} STREQUAL "FIRMWARE_SIMULATOR") find_package(spdlog REQUIRED) endif() -add_library(filesystem INTERFACE filesystem/filesystem_holder.hpp) +add_library(filesystem INTERFACE filesystem/filesystem_holder.hpp ) target_sources(filesystem INTERFACE filesystem/block_device_wrapper/ih_block_device.hpp filesystem/block_device_wrapper/heap_block_device.hpp filesystem/block_device_wrapper/adaptor_block_device.hpp + filesystem/block_device_wrapper/spi_block_device.hpp ) target_include_directories(filesystem INTERFACE ${CMAKE_CURRENT_LIST_DIR} ) @@ -16,6 +17,12 @@ target_link_libraries(filesystem INTERFACE littlefs ) -if(WIN32 OR UNIX) +if(WIN32 OR UNIX AND ${TARGET_PLATFORM} STREQUAL "FIRMWARE_SIMULATOR" ) target_link_libraries(filesystem INTERFACE spdlog::spdlog) -endif() \ No newline at end of file +endif() + +target_link_libraries( + filesystem INTERFACE + drivers_ih + windbond_spi_flash_driver +) \ No newline at end of file diff --git a/Firmware/filesystem/filesystem/block_device_wrapper/adaptor_block_device.hpp b/Firmware/filesystem/filesystem/block_device_wrapper/adaptor_block_device.hpp index a24928e7..d89f4962 100644 --- a/Firmware/filesystem/filesystem/block_device_wrapper/adaptor_block_device.hpp +++ b/Firmware/filesystem/filesystem/block_device_wrapper/adaptor_block_device.hpp @@ -4,6 +4,7 @@ #include #include +#include template <> struct fmt::formatter> { @@ -35,7 +36,7 @@ template <> struct fmt::formatter> } }; -namespace Wrapper +namespace Filesystem::BlockDevice { template diff --git a/Firmware/filesystem/filesystem/block_device_wrapper/heap_block_device.hpp b/Firmware/filesystem/filesystem/block_device_wrapper/heap_block_device.hpp index b2ad746f..50c950d5 100644 --- a/Firmware/filesystem/filesystem/block_device_wrapper/heap_block_device.hpp +++ b/Firmware/filesystem/filesystem/block_device_wrapper/heap_block_device.hpp @@ -3,7 +3,7 @@ #include "ih_block_device.hpp" #include -namespace Wrapper +namespace Filesystem::BlockDevice { inline constexpr std::size_t kBlockSize = 256; inline constexpr std::size_t kSectorsCount = 65'536; diff --git a/Firmware/filesystem/filesystem/block_device_wrapper/ih_block_device.hpp b/Firmware/filesystem/filesystem/block_device_wrapper/ih_block_device.hpp index 99d3ced9..ffeb0c0e 100644 --- a/Firmware/filesystem/filesystem/block_device_wrapper/ih_block_device.hpp +++ b/Firmware/filesystem/filesystem/block_device_wrapper/ih_block_device.hpp @@ -2,7 +2,7 @@ #include #include -namespace Wrapper +namespace Filesystem::BlockDevice { template class BlockDeviceEntity { diff --git a/Firmware/filesystem/filesystem/block_device_wrapper/spi_block_device.hpp b/Firmware/filesystem/filesystem/block_device_wrapper/spi_block_device.hpp new file mode 100644 index 00000000..110d8013 --- /dev/null +++ b/Firmware/filesystem/filesystem/block_device_wrapper/spi_block_device.hpp @@ -0,0 +1,14 @@ +#pragma once + +#include "ih_block_device.hpp" + +namespace Filesystem::BlockDevice +{ +template +class SpiFlashBlockDevice : public BlockDeviceEntity> +{ + + +}; + +}; // namespace Filesystem::BlockDevice \ No newline at end of file diff --git a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp index 9b1a48af..73fba652 100644 --- a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp +++ b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp @@ -25,11 +25,11 @@ #include -using TFilesystem = Platform::Fs::Holder>>; +using TFilesystem = Platform::Fs::Holder>>; using TFile = Platform::Fs::File; diff --git a/Firmware/firmware_tests/filesystem/filesystem_fixture.hpp b/Firmware/firmware_tests/filesystem/filesystem_fixture.hpp index d789b1e6..b2af8261 100644 --- a/Firmware/firmware_tests/filesystem/filesystem_fixture.hpp +++ b/Firmware/firmware_tests/filesystem/filesystem_fixture.hpp @@ -1,10 +1,9 @@ #pragma once #include -#include -#include #include - +#include +#include #include @@ -20,12 +19,12 @@ class FilesystemTopLevelTestFixture { public: - - using TFilesystem = Platform::Fs::Holder>>; + using TFilesystem = Platform::Fs::Holder< + Filesystem::BlockDevice::LogAdaptorBlockDevice>>; using TFile = Platform::Fs::File; @@ -35,8 +34,6 @@ class FilesystemTopLevelTestFixture CoroUtils::syncWait(m_testFilesystem.initializeFs()); } - - protected: TFilesystem m_testFilesystem; }; \ No newline at end of file From 2ad7d52c6483c1095ec5d7a0416f5b0e33fe34ef Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Tue, 8 Feb 2022 18:44:50 +0200 Subject: [PATCH 24/54] Added combiner block device with write call implementation #17 --- .../windbondflash/winbond_flash_templated.hpp | 2 +- Firmware/filesystem/CMakeLists.txt | 6 +- .../combiner_block_device.hpp | 79 ++++++++++++++++ .../block_device_wrapper/spi_block_device.hpp | 76 +++++++++++++++ Firmware/firmware_tests/CMakeLists.txt | 2 +- .../coroutine/coroutine_thoughts.cpp | 29 ++++-- .../filesystem/filesystem_fixture.hpp | 68 +++++++++++--- .../filesystem/filesystem_in_memory_test.cpp | 92 +++++++------------ .../filesystem/filesystem_test_data.hpp | 47 ++++++++++ 9 files changed, 315 insertions(+), 86 deletions(-) create mode 100644 Firmware/filesystem/filesystem/block_device_wrapper/combiner_block_device.hpp create mode 100644 Firmware/firmware_tests/filesystem/filesystem_test_data.hpp diff --git a/Firmware/drivers/winbondflash/inc/windbondflash/winbond_flash_templated.hpp b/Firmware/drivers/winbondflash/inc/windbondflash/winbond_flash_templated.hpp index db92b31a..61557a18 100644 --- a/Firmware/drivers/winbondflash/inc/windbondflash/winbond_flash_templated.hpp +++ b/Firmware/drivers/winbondflash/inc/windbondflash/winbond_flash_templated.hpp @@ -23,7 +23,7 @@ template class WinbondFlashDriver { constexpr std::uint16_t PageSize = 256; - assert(_blockData.size() < PageSize); + assert(_blockData.size() <= PageSize); using TTupleProgram = decltype(std::forward_as_tuple( WindbondCommandSet::PageProgram, diff --git a/Firmware/filesystem/CMakeLists.txt b/Firmware/filesystem/CMakeLists.txt index caf4648e..c3f73d17 100644 --- a/Firmware/filesystem/CMakeLists.txt +++ b/Firmware/filesystem/CMakeLists.txt @@ -2,7 +2,11 @@ if(WIN32 OR UNIX AND ${TARGET_PLATFORM} STREQUAL "FIRMWARE_SIMULATOR") find_package(spdlog REQUIRED) endif() -add_library(filesystem INTERFACE filesystem/filesystem_holder.hpp ) +add_library(filesystem INTERFACE + + filesystem/filesystem_holder.hpp + filesystem/block_device_wrapper/combiner_block_device.hpp +) target_sources(filesystem INTERFACE filesystem/block_device_wrapper/ih_block_device.hpp diff --git a/Firmware/filesystem/filesystem/block_device_wrapper/combiner_block_device.hpp b/Firmware/filesystem/filesystem/block_device_wrapper/combiner_block_device.hpp new file mode 100644 index 00000000..585e4e30 --- /dev/null +++ b/Firmware/filesystem/filesystem/block_device_wrapper/combiner_block_device.hpp @@ -0,0 +1,79 @@ +#pragma once +#include +#include + +namespace Filesystem::BlockDevice +{ +template class CombinerBlockDevice +{ +public: + using TCombinedBlocksStore = std::tuple; + + constexpr std::uint32_t getBlockSize() const noexcept + { + return getFirstBlock()->getBlockSize(); + } + constexpr std::uint32_t getBlocksCount() const noexcept + { + return getFirstBlock()->getBlocksCount(); + } + constexpr std::uint32_t getReadSize() const noexcept + { + return getFirstBlock()->getReadSize(); + } + constexpr std::uint32_t getProgSize() const noexcept + { + return getFirstBlock()->getProgSize(); + } + constexpr std::uint32_t getEraseSize() const noexcept + { + return getFirstBlock()->getEraseSize(); + } + + CoroUtils::VoidTask write( + std::uint32_t _address, + const std::uint8_t* _blockData, + std::uint32_t _blockSize) noexcept + { + co_await launchAllWrite( + _address, + _blockData, + _blockSize, + std::make_integer_sequence{}); + } + + CoroUtils::VoidTask read( + std::uint8_t* _pBlockOut, + std::uint32_t _address, + std::uint32_t _blockSize) noexcept + { + // TODO add comarison of the differrent block device reads + co_await getFirstBlock()->read(_pBlockOut, _address, _blockSize); + } + +private: + template + CoroUtils::VoidTask launchAllWrite( + std::uint32_t _address, + const std::uint8_t* _blockData, + std::uint32_t _blockSize, + std::integer_sequence) noexcept + { + (co_await std::get(m_combinedBlocks).write(_address, _blockData, _blockSize), ...); + } + + decltype(auto) getFirstBlock() noexcept + { + return &std::get<0>(m_combinedBlocks); + } + + decltype(auto) getFirstBlock() const noexcept + { + return &std::get<0>(m_combinedBlocks); + } + +private: + TCombinedBlocksStore m_combinedBlocks; +}; + +} // namespace Filesystem::BlockDevice \ No newline at end of file diff --git a/Firmware/filesystem/filesystem/block_device_wrapper/spi_block_device.hpp b/Firmware/filesystem/filesystem/block_device_wrapper/spi_block_device.hpp index 110d8013..f5054361 100644 --- a/Firmware/filesystem/filesystem/block_device_wrapper/spi_block_device.hpp +++ b/Firmware/filesystem/filesystem/block_device_wrapper/spi_block_device.hpp @@ -7,8 +7,84 @@ namespace Filesystem::BlockDevice template class SpiFlashBlockDevice : public BlockDeviceEntity> { +public: + constexpr std::uint32_t getBlockSize() const noexcept + { + return kBlockSize; + } + constexpr std::uint32_t getBlocksCount() const noexcept + { + return kSectorsCount; + } + constexpr std::uint32_t getReadSize() const noexcept + { + return kReadSize; + } + constexpr std::uint32_t getProgSize() const noexcept + { + return kBlockSize; + } + constexpr std::uint32_t getEraseSize() const noexcept + { + return kEraseSize; + } +public: + CoroUtils::VoidTask write( + std::uint32_t _address, + const std::uint8_t* _blockData, + std::uint32_t _blockSize) noexcept + { + std::uint32_t requestSize = _blockSize; + const std::uint8_t* pBlockRequest = _blockData; + std::uint32_t blockAddress{_address}; + while (requestSize > 0) + { + std::uint32_t highPart = blockAddress / getBlockSize(); + std::uint32_t lowPart = blockAddress % getBlockSize(); + + co_await m_currentFlashDriver.pageWrite(_address, std::span(_blockData, _blockSize)); + + blockAddress += getProgSize(); + pBlockRequest += getProgSize(); + requestSize -= getProgSize(); + } + co_return; + } + + CoroUtils::VoidTask read( + std::uint8_t* _pBlockOut, + std::uint32_t _address, + std::uint32_t _blockSize) noexcept + { + std::uint32_t blockSize{_blockSize}; + std::uint8_t* pReadBuffer{_pBlockOut}; + std::uint32_t blockAddress{_address}; + + while (blockSize > 0) + { + std::uint32_t hi = blockAddress / getBlockSize(); + std::uint32_t lo = blockAddress % getBlockSize(); + + auto resultBuffer = co_await m_currentFlashDriver.requestReadBlock(); + memcpy(pReadBuffer, resultBuffer.data(), getReadSize()); + + blockAddress += getReadSize(); + pReadBuffer += getReadSize(); + blockSize -= getReadSize(); + } + co_return; + } + +private: + static constexpr std::size_t kBlockSize = 256; + static constexpr std::size_t kSectorsCount = 65'536; + static constexpr std::size_t kReadSize = 256; + static constexpr std::size_t kEraseSize = 4096; + +private: + TFlashDriver m_currentFlashDriver; }; }; // namespace Filesystem::BlockDevice \ No newline at end of file diff --git a/Firmware/firmware_tests/CMakeLists.txt b/Firmware/firmware_tests/CMakeLists.txt index 5d6fdc31..a340c5bc 100644 --- a/Firmware/firmware_tests/CMakeLists.txt +++ b/Firmware/firmware_tests/CMakeLists.txt @@ -36,7 +36,7 @@ add_executable( drivers/spi/mock_spi.hpp filesystem/filesystem_fixture.hpp - filesystem/filesystem_in_memory_test.cpp) + filesystem/filesystem_in_memory_test.cpp ) mark_as_advanced( BUILD_GMOCK BUILD_GTEST BUILD_SHARED_LIBS diff --git a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp index 73fba652..9519e59a 100644 --- a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp +++ b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp @@ -22,14 +22,30 @@ #include #include #include +#include +#include + +#include #include -using TFilesystem = Platform::Fs::Holder>>; +using TSpiBus = Interface::SpiTemplated::SpiBus; +using TFlashDriver = ExternalFlash::WinbondFlashDriver; + +using TSpiFlashBlockDevice = Filesystem::BlockDevice::SpiFlashBlockDevice; + +using TDisplayDriver = DisplayDriver::GC9A01Compact; + +using TLogHeapBlockDevice = + Filesystem::BlockDevice::LogAdaptorBlockDevice>; + +using TCombinedBlockDevice = Filesystem::BlockDevice::CombinerBlockDevice; + +using TFilesystem = Platform::Fs::Holder; using TFile = Platform::Fs::File; @@ -114,9 +130,6 @@ int main() CoroUtils::syncWait(fileTest(platformFilesystem)); - using TSpiBus = Interface::SpiTemplated::SpiBus; - - using TDisplayDriver = DisplayDriver::GC9A01Compact; /*Display display{}; display.fillRectangle(0, 0, 220, 220, nullptr);*/ diff --git a/Firmware/firmware_tests/filesystem/filesystem_fixture.hpp b/Firmware/firmware_tests/filesystem/filesystem_fixture.hpp index b2af8261..30f56df7 100644 --- a/Firmware/firmware_tests/filesystem/filesystem_fixture.hpp +++ b/Firmware/firmware_tests/filesystem/filesystem_fixture.hpp @@ -7,26 +7,63 @@ #include -struct FilesystemParamInterfaceData +#include +#include + +#include +#include + +// TODO Fix include more clearly +#include "../drivers/spi/mock_gpio.hpp" +#include "../drivers/spi/spi_fake_backend.hpp" +#include "filesystem_test_data.hpp" + +using TFlashTestDriver = ExternalFlash::WinbondFlashDriver< + Interface::SpiTemplated::SpiBus>; + +using TSpiFlashBlockDevice = Filesystem::BlockDevice::SpiFlashBlockDevice; + +using TLogHeapBlockDevice = + Filesystem::BlockDevice::LogAdaptorBlockDevice>; + +using TCombinedBlockDevice = + Filesystem::BlockDevice::CombinerBlockDevice; + +using TWrappedFilesystem = Platform::Fs::Holder; + +using THeapFilesystem = Platform::Fs::Holder< + Filesystem::BlockDevice::LogAdaptorBlockDevice>>; + +template struct TestParamPlaceholder { - std::string_view fileData; - std::string_view filename; + using THoldedFilesystem = TFilesystem; + std::vector testData; }; -class FilesystemTopLevelTestFixture - : public ::testing::Test - , public ::testing::WithParamInterface +static std::tuple, TestParamPlaceholder> + kFilesystemTestParams{ + {{HelloWorldData, NmeaData}}, + {{HelloWorldData, NmeaData}}, + }; + +// http://www.ashermancinelli.com/gtest-type-val-param +template class FilesystemTopLevelTestFixture : public ::testing::Test { public: - using TFilesystem = Platform::Fs::Holder< - Filesystem::BlockDevice::LogAdaptorBlockDevice>>; - - using TFile = Platform::Fs::File; + FilesystemTopLevelTestFixture() + : m_params{std::get>(kFilesystemTestParams)} + { + } protected: void SetUp() override @@ -35,5 +72,6 @@ class FilesystemTopLevelTestFixture } protected: - TFilesystem m_testFilesystem; + TestParamPlaceholder m_params; + Filesystem m_testFilesystem; }; \ No newline at end of file diff --git a/Firmware/firmware_tests/filesystem/filesystem_in_memory_test.cpp b/Firmware/firmware_tests/filesystem/filesystem_in_memory_test.cpp index 8a1a0cac..9099efb7 100644 --- a/Firmware/firmware_tests/filesystem/filesystem_in_memory_test.cpp +++ b/Firmware/firmware_tests/filesystem/filesystem_in_memory_test.cpp @@ -1,75 +1,47 @@ #include "filesystem_fixture.hpp" + #include #include #include -constexpr auto HelloWorldData = - FilesystemParamInterfaceData{.fileData = "Hello world!", .filename = "helloworld.txt"}; -constexpr auto kNmeaDataExample = std::string_view{ - "$GPGSA,A,1,,,,,,,,,,,,,,,* 1E\n" - "$GPGSV,1,1,0,,,,,,,,,,,,,,,,* 49\n" - "$GPRMC,114811.00,A,5548.2054190,N,03732.8518300,E,0.22,0.00,210618,0.0,E,A * 30\n" - "$GPGGA,114811.00,5548.2054190,N,03732.8518300,E,1,06,1.0,179.534,M,14.753,M,0.0,* 45\n" - "$GPGSA,A,3,02,21,25,26,31,,,,,,,,5.4,1.2,5.3,1 * 2B\n" - "$GAGSA,A,3,30,,,,,,,,,,,,0.0,0.0,0.0,3 * 3F\n" - "$GPGSV,2,1,05,02,23,059,28,21,30,222,32,25,41,166,35,26,36,303,34,1 * 67\n" - "$GPGSV,2,2,05,31,27,254,34,,,,,,,,,,,,,1 * 52\n" - "$GAGSV,1,1,01,30,23,183,33,,,,,,,,,,,,,7 * 4A\n" - "$GPRMC,114812.00,A,5548.2052305,N,03732.8513810,E,0.17,0.00,210618,0.0,E,A * 3C\n" - "$GPGGA,114812.00,5548.2052305,N,03732.8513810,E,1,06,1.0,178.149,M,14.753,M,0.0,* 40\n" - "$GPGSA,A,3,02,21,25,26,31,,,,,,,,5.4,1.2,5.3,1 * 2B\n" - "$GAGSA,A,3,30,,,,,,,,,,,,0.0,0.0,0.0,3 * 3F\n" - "$GPGSV,2,1,05,02,23,059,28,21,30,222,31,25,41,166,36,26,36,303,34,1 * 67\n" - "$GPGSV,2,2,05,31,27,254,34,,,,,,,,,,,,,1 * 52\n" - "$GAGSV,1,1,01,30,23,183,32,,,,,,,,,,,,,7 * 4B\n" - "$GPRMC,114813.00,A,5548.2048307,N,03732.8514121,E,0.28,0.00,210618,0.0,E,A * 34\n" - "$GPGGA,114813.00,5548.2048307,N,03732.8514121,E,1,06,1.0,172.326,M,14.753,M,0.0,* 45\n" - "$GPGSA,A,3,02,21,25,26,31,,,,,,,,5.4,1.2,5.3,1 * 2B\n" - "$GAGSA,A,3,30,,,,,,,,,,,,0.0,0.0,0.0,3 * 3F\n" - "$GPGSV,2,1,05,02,23,059,28,21,31,222,32,25,41,166,36,26,36,303,34,1 * 65\n" - "$GPGSV,2,2,05,31,27,254,34,,,,,,,,,,,,,1 * 52\n" - "$GAGSV,1,1,01,30,23,183,32,,,,,,,,,,,,,7 * 4B\n" - "$GPRMC,114814.00,A,5548.2047440,N,03732.8516481,E,0.19,0.00,210618,0.0,E,A * 37\n" - "$GPGGA,114814.00,5548.2047440,N,03732.8516481,E,1,06,1.0,172.488,M,14.753,M,0.0,* 47\n" - "$GPGSA,A,3,02,21,25,26,31,,,,,,,,5.4,1.2,5.3,1 * 2B\n" - "$GAGSA,A,3,30,,,,,,,,,,,,0.0,0.0,0.0,3 * 3F\n" - "$GPGSV,2,1,05,02,23,059,28,21,31,222,32,25,41,166,35,26,36,303,34,1 * 66\n" - "$GPGSV,2,2,05,31,27,254,34,,,,,,,,,,,,,1 * 52\n" - "$GAGSV,1,1,01,30,23,183,32,,,,,,,,,,,,,7 * 4B\n" +//https://stackoverflow.com/questions/56115790/gtest-parametrized-tests-for-different-types +// http://www.ashermancinelli.com/gtest-type-val-param -}; +TYPED_TEST_SUITE_P(FilesystemTopLevelTestFixture); -constexpr auto NmeaData = - FilesystemParamInterfaceData{.fileData = kNmeaDataExample, .filename = "nmea_data.txt"}; -TEST_P(FilesystemTopLevelTestFixture, CheckFileReadWriteProcedure) +TYPED_TEST_P(FilesystemTopLevelTestFixture, CheckFileReadWriteProcedure) { - auto lfs = m_testFilesystem.fsInstance(); + for (auto const& testParamData : this->m_params.testData) { - auto filePath = GetParam().filename; - auto filename = std::move(CoroUtils::syncWait(m_testFilesystem.openFile(filePath))); - CoroUtils::syncWait(filename.write(std::span( - reinterpret_cast(GetParam().fileData.data()), - GetParam().fileData.size()))); + auto& filesystemInstance = this->m_testFilesystem; + auto lfs = filesystemInstance.fsInstance(); + { + auto filePath = testParamData.filename; + auto filename = std::move(CoroUtils::syncWait(filesystemInstance.openFile(filePath))); + CoroUtils::syncWait(filename.write(std::span( + reinterpret_cast(testParamData.fileData.data()), + testParamData.fileData.size()))); + } + + std::vector readFrom; + readFrom.resize(testParamData.fileData.size()); + + { + auto holdedFile = std::move(CoroUtils::syncWait(filesystemInstance.openFile(testParamData.filename))); + auto resultRead = CoroUtils::syncWait( + holdedFile.read(std::span(readFrom.data(), testParamData.fileData.size()))); + } + + auto kCompareStringView{ + std::string_view{reinterpret_cast(readFrom.data()), readFrom.size()}}; + EXPECT_EQ(kCompareStringView, testParamData.fileData); } +} - std::vector readFrom; - readFrom.resize(GetParam().fileData.size()); - - { - auto holdedFile = - std::move(CoroUtils::syncWait(m_testFilesystem.openFile(GetParam().filename))); - auto resultRead = CoroUtils::syncWait( - holdedFile.read(std::span(readFrom.data(), GetParam().fileData.size()))); - } - auto kCompareStringView{ - std::string_view{reinterpret_cast(readFrom.data()), readFrom.size()}}; - EXPECT_EQ(kCompareStringView, GetParam().fileData); -} +REGISTER_TYPED_TEST_SUITE_P(FilesystemTopLevelTestFixture, CheckFileReadWriteProcedure); -INSTANTIATE_TEST_SUITE_P( - FilesystemTopLevelTesting, - FilesystemTopLevelTestFixture, - ::testing::Values(HelloWorldData, NmeaData)); \ No newline at end of file +using TTestFilesystems = ::testing::Types; +INSTANTIATE_TYPED_TEST_SUITE_P(FilesystemTests, FilesystemTopLevelTestFixture, TTestFilesystems); diff --git a/Firmware/firmware_tests/filesystem/filesystem_test_data.hpp b/Firmware/firmware_tests/filesystem/filesystem_test_data.hpp new file mode 100644 index 00000000..3f8e4f0b --- /dev/null +++ b/Firmware/firmware_tests/filesystem/filesystem_test_data.hpp @@ -0,0 +1,47 @@ +#pragma once + +struct FilesystemParamInterfaceData +{ + std::string_view fileData; + std::string_view filename; +}; + +inline constexpr auto HelloWorldData = + FilesystemParamInterfaceData{.fileData = "Hello world!", .filename = "helloworld.txt"}; + +constexpr auto kNmeaDataExample = std::string_view{ + "$GPGSA,A,1,,,,,,,,,,,,,,,* 1E\n" + "$GPGSV,1,1,0,,,,,,,,,,,,,,,,* 49\n" + "$GPRMC,114811.00,A,5548.2054190,N,03732.8518300,E,0.22,0.00,210618,0.0,E,A * 30\n" + "$GPGGA,114811.00,5548.2054190,N,03732.8518300,E,1,06,1.0,179.534,M,14.753,M,0.0,* 45\n" + "$GPGSA,A,3,02,21,25,26,31,,,,,,,,5.4,1.2,5.3,1 * 2B\n" + "$GAGSA,A,3,30,,,,,,,,,,,,0.0,0.0,0.0,3 * 3F\n" + "$GPGSV,2,1,05,02,23,059,28,21,30,222,32,25,41,166,35,26,36,303,34,1 * 67\n" + "$GPGSV,2,2,05,31,27,254,34,,,,,,,,,,,,,1 * 52\n" + "$GAGSV,1,1,01,30,23,183,33,,,,,,,,,,,,,7 * 4A\n" + "$GPRMC,114812.00,A,5548.2052305,N,03732.8513810,E,0.17,0.00,210618,0.0,E,A * 3C\n" + "$GPGGA,114812.00,5548.2052305,N,03732.8513810,E,1,06,1.0,178.149,M,14.753,M,0.0,* 40\n" + "$GPGSA,A,3,02,21,25,26,31,,,,,,,,5.4,1.2,5.3,1 * 2B\n" + "$GAGSA,A,3,30,,,,,,,,,,,,0.0,0.0,0.0,3 * 3F\n" + "$GPGSV,2,1,05,02,23,059,28,21,30,222,31,25,41,166,36,26,36,303,34,1 * 67\n" + "$GPGSV,2,2,05,31,27,254,34,,,,,,,,,,,,,1 * 52\n" + "$GAGSV,1,1,01,30,23,183,32,,,,,,,,,,,,,7 * 4B\n" + "$GPRMC,114813.00,A,5548.2048307,N,03732.8514121,E,0.28,0.00,210618,0.0,E,A * 34\n" + "$GPGGA,114813.00,5548.2048307,N,03732.8514121,E,1,06,1.0,172.326,M,14.753,M,0.0,* 45\n" + "$GPGSA,A,3,02,21,25,26,31,,,,,,,,5.4,1.2,5.3,1 * 2B\n" + "$GAGSA,A,3,30,,,,,,,,,,,,0.0,0.0,0.0,3 * 3F\n" + "$GPGSV,2,1,05,02,23,059,28,21,31,222,32,25,41,166,36,26,36,303,34,1 * 65\n" + "$GPGSV,2,2,05,31,27,254,34,,,,,,,,,,,,,1 * 52\n" + "$GAGSV,1,1,01,30,23,183,32,,,,,,,,,,,,,7 * 4B\n" + "$GPRMC,114814.00,A,5548.2047440,N,03732.8516481,E,0.19,0.00,210618,0.0,E,A * 37\n" + "$GPGGA,114814.00,5548.2047440,N,03732.8516481,E,1,06,1.0,172.488,M,14.753,M,0.0,* 47\n" + "$GPGSA,A,3,02,21,25,26,31,,,,,,,,5.4,1.2,5.3,1 * 2B\n" + "$GAGSA,A,3,30,,,,,,,,,,,,0.0,0.0,0.0,3 * 3F\n" + "$GPGSV,2,1,05,02,23,059,28,21,31,222,32,25,41,166,35,26,36,303,34,1 * 66\n" + "$GPGSV,2,2,05,31,27,254,34,,,,,,,,,,,,,1 * 52\n" + "$GAGSV,1,1,01,30,23,183,32,,,,,,,,,,,,,7 * 4B\n" + +}; + +inline constexpr auto NmeaData = + FilesystemParamInterfaceData{.fileData = kNmeaDataExample, .filename = "nmea_data.txt"}; From fe37da7709a2e8287a45c5197c22bb498e96e668 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Tue, 22 Mar 2022 19:12:37 +0200 Subject: [PATCH 25/54] Updated littlefs CMakeLists --- Firmware/3rdparty/littlefs_lib/CMakeLists.txt | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/Firmware/3rdparty/littlefs_lib/CMakeLists.txt b/Firmware/3rdparty/littlefs_lib/CMakeLists.txt index 9f2307e0..a0aa3292 100644 --- a/Firmware/3rdparty/littlefs_lib/CMakeLists.txt +++ b/Firmware/3rdparty/littlefs_lib/CMakeLists.txt @@ -1,15 +1,13 @@ cmake_minimum_required(VERSION 3.14) -set(CMAKE_CXX_EXTENSIONS OFF) - add_library(littlefs) target_sources(littlefs PRIVATE - "littlefs/lfs.cpp" - "littlefs/lfs_util.cpp" + littlefs/lfs.cpp + littlefs/lfs_util.cpp ) -target_include_directories(littlefs PUBLIC littlefs +target_include_directories(littlefs PUBLIC littlefs ) target_link_libraries(littlefs PUBLIC UtilsLibrary ) From 7fe0f968b827661515ef9f6a6409c2fc88c3a37a Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Tue, 22 Mar 2022 19:18:33 +0200 Subject: [PATCH 26/54] Updated cmake generator to VS2022 --- .github/workflows/build.yml | 285 ++++++++++++++++++------------------ 1 file changed, 141 insertions(+), 144 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4713d119..ee75b4e5 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -4,9 +4,9 @@ name: CI # events but only for the master branch on: push: - branches: [ master,dev/develop,dev/littlefs_impl] + branches: [master, dev/develop, dev/littlefs_impl] pull_request: - branches: [ master,dev/develop] + branches: [master, dev/develop] # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: @@ -18,105 +18,103 @@ jobs: buildDir: '${{ github.workspace }}\build' # Steps represent a sequence of tasks that will be executed as part of the job steps: - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 - with: - submodules: 'true' - - - name: Setup python - uses: actions/setup-python@v2 - with: - python-version: '3.8' - - - name: Install conan - uses: BSFishy/pip-action@v1 - with: - packages: | - conan - - #Install the latest cmake - - name : Get the latest CMake version - uses: lukka/get-cmake@latest - - - name: Run build for MSVC compiler - run: | - cmake -G"Visual Studio 16 2019" -Ax64 -S"${{ github.workspace }}/Firmware/" -B"${{ env.buildDir }}" -DPACKAGE_TESTS=ON -DTARGET_PLATFORM:STRING="FIRMWARE_SIMULATOR" -DCMAKE_BUILD_TYPE=Release - cd ${{ env.buildDir }} - cmake --build . --config Release - - name : Run firmware testing - run: | - cd ${{ env.buildDir }}/Release - .\FirmwareTesting.exe + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + with: + submodules: "true" + + - name: Setup python + uses: actions/setup-python@v2 + with: + python-version: "3.8" + + - name: Install conan + uses: BSFishy/pip-action@v1 + with: + packages: | + conan + + #Install the latest cmake + - name: Get the latest CMake version + uses: lukka/get-cmake@latest + + - name: Run build for MSVC compiler + run: | + cmake -G"Visual Studio 17 2022" -Ax64 -S"${{ github.workspace }}/Firmware/" -B"${{ env.buildDir }}" -DPACKAGE_TESTS=ON -DTARGET_PLATFORM:STRING="FIRMWARE_SIMULATOR" -DCMAKE_BUILD_TYPE=Release + cd ${{ env.buildDir }} + cmake --build . --config Release + - name: Run firmware testing + run: | + cd ${{ env.buildDir }}/Release + .\FirmwareTesting.exe build-arm: - runs-on: ubuntu-latest steps: - - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 - with: - submodules: 'true' - - #Install the latest cmake - - name : Get the latest CMake version - uses: lukka/get-cmake@latest - - # - name: Get the latest arm-none-eabi-gcc - # uses: fiam/arm-none-eabi-gcc@v1 - # with: - # release: '10-2020-q2' - # directory: ${{ github.workspace }}/toolchain - - name: Cache GCC toolchain - id: cache-gcc-toolchain - uses: actions/cache@v2 - with: - path: ${{ github.workspace }}/gcc_toolchain_10_3 - key: ${{runner.os}}-toolchain-v10_3 - - - name: Get the latest arm-gcc-none-eabi-gcc - uses: wei/wget@v1 - if: steps.cache-gcc-toolchain.outputs.cache-hit != 'true' - id: download-arm-gcc - with: - args: 'https://developer.arm.com/-/media/Files/downloads/gnu-rm/10.3-2021.07/gcc-arm-none-eabi-10.3-2021.07-x86_64-linux.tar.bz2' - - - name: Unpack arm-gcc-compiler - if: steps.cache-gcc-toolchain.outputs.cache-hit != 'true' - run: | - mkdir gcc_toolchain_10_3 - tar -xjf gcc-arm-none-eabi-10.3-2021.07-x86_64-linux.tar.bz2 --directory ${{ github.workspace }}/gcc_toolchain_10_3 - - - name: Cache NordicSDK - id: cache-nordic-sdk - uses: actions/cache@v2 - with: - path: ${{ github.workspace }}/Nrf52SDKv16_0 - key: ${{runner.os}}-nordic-sdk-v16-0 - - - name: Get NRF52 16.0 SDK - uses: wei/wget@v1 - id: download-nrf52sdk - if: steps.cache-nordic-sdk.outputs.cache-hit != 'true' - with: - args: 'https://www.nordicsemi.com/-/media/Software-and-other-downloads/SDKs/nRF5/Binaries/nRF5SDK160098a08e2.zip' - - - name: Unpack NordicSDK - if: steps.cache-nordic-sdk.outputs.cache-hit != 'true' - run: | - mkdir Nrf52SDKv16_0 - unzip nRF5SDK160098a08e2.zip -d Nrf52SDKv16_0 - mv Nrf52SDKv16_0/components/boards/pca10040.h Nrf52SDKv16_0/components/boards/pca10040_1.h - - - name: Run CMakeLists generation for GCC compiler - uses: lukka/run-cmake@v2 - with: - cmakeGenerator: Ninja - cmakeListsOrSettingsJson: CMakeListsTxtAdvanced - cmakeListsTxtPath: ${{ github.workspace }}/Firmware/CMakeLists.txt - cmakeBuildType: Debug - cmakeAppendedArgs : '-DTARGET_PLATFORM:STRING="ARM_CORTEX" -DEXECUTE_MCU_FLASHING=OFF -DCMAKE_BUILD_TYPE:STRING=Debug -DREDUCE_LVGL_BINARY_SIZE=ON -DPACKAGE_TESTS=OFF -DNRF5_SDK_PATH=${{ github.workspace }}/Nrf52SDKv16_0 -DARM_NONE_EABI_TOOLCHAIN_PATH:PATH=${{ github.workspace }}/gcc_toolchain_10_3/gcc-arm-none-eabi-10.3-2021.07' - buildWithCMake: true + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + with: + submodules: "true" + + #Install the latest cmake + - name: Get the latest CMake version + uses: lukka/get-cmake@latest + + # - name: Get the latest arm-none-eabi-gcc + # uses: fiam/arm-none-eabi-gcc@v1 + # with: + # release: '10-2020-q2' + # directory: ${{ github.workspace }}/toolchain + - name: Cache GCC toolchain + id: cache-gcc-toolchain + uses: actions/cache@v2 + with: + path: ${{ github.workspace }}/gcc_toolchain_10_3 + key: ${{runner.os}}-toolchain-v10_3 + + - name: Get the latest arm-gcc-none-eabi-gcc + uses: wei/wget@v1 + if: steps.cache-gcc-toolchain.outputs.cache-hit != 'true' + id: download-arm-gcc + with: + args: "https://developer.arm.com/-/media/Files/downloads/gnu-rm/10.3-2021.07/gcc-arm-none-eabi-10.3-2021.07-x86_64-linux.tar.bz2" + + - name: Unpack arm-gcc-compiler + if: steps.cache-gcc-toolchain.outputs.cache-hit != 'true' + run: | + mkdir gcc_toolchain_10_3 + tar -xjf gcc-arm-none-eabi-10.3-2021.07-x86_64-linux.tar.bz2 --directory ${{ github.workspace }}/gcc_toolchain_10_3 + + - name: Cache NordicSDK + id: cache-nordic-sdk + uses: actions/cache@v2 + with: + path: ${{ github.workspace }}/Nrf52SDKv16_0 + key: ${{runner.os}}-nordic-sdk-v16-0 + + - name: Get NRF52 16.0 SDK + uses: wei/wget@v1 + id: download-nrf52sdk + if: steps.cache-nordic-sdk.outputs.cache-hit != 'true' + with: + args: "https://www.nordicsemi.com/-/media/Software-and-other-downloads/SDKs/nRF5/Binaries/nRF5SDK160098a08e2.zip" + + - name: Unpack NordicSDK + if: steps.cache-nordic-sdk.outputs.cache-hit != 'true' + run: | + mkdir Nrf52SDKv16_0 + unzip nRF5SDK160098a08e2.zip -d Nrf52SDKv16_0 + mv Nrf52SDKv16_0/components/boards/pca10040.h Nrf52SDKv16_0/components/boards/pca10040_1.h + + - name: Run CMakeLists generation for GCC compiler + uses: lukka/run-cmake@v2 + with: + cmakeGenerator: Ninja + cmakeListsOrSettingsJson: CMakeListsTxtAdvanced + cmakeListsTxtPath: ${{ github.workspace }}/Firmware/CMakeLists.txt + cmakeBuildType: Debug + cmakeAppendedArgs: '-DTARGET_PLATFORM:STRING="ARM_CORTEX" -DEXECUTE_MCU_FLASHING=OFF -DCMAKE_BUILD_TYPE:STRING=Debug -DREDUCE_LVGL_BINARY_SIZE=ON -DPACKAGE_TESTS=OFF -DNRF5_SDK_PATH=${{ github.workspace }}/Nrf52SDKv16_0 -DARM_NONE_EABI_TOOLCHAIN_PATH:PATH=${{ github.workspace }}/gcc_toolchain_10_3/gcc-arm-none-eabi-10.3-2021.07' + buildWithCMake: true # # Runs a set of commands using the runners shell # - name: Run a multi-line script @@ -126,51 +124,50 @@ jobs: build-linux-desktop-simulator: runs-on: ubuntu-latest env: - buildDir: '${{ github.workspace }}/build' + buildDir: "${{ github.workspace }}/build" steps: - - # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it - - uses: actions/checkout@v2 - with: - submodules: 'true' - - - name: Setup python - uses: actions/setup-python@v2 - with: - python-version: '3.8' - - - name: Install conan - uses: BSFishy/pip-action@v1 - with: - packages: | - conan - - - name: Intall system required packages - run: | - sudo apt-get update - sudo apt-get install -y libegl-dev - #Install the latest cmake - - name : Get the latest CMake version - uses: lukka/get-cmake@latest - - - name: Set up GCC 11 - uses: egor-tensin/setup-gcc@v1 - with: - version: 11 - platform: x64 - - - name: Run CMakeLists generation for GCC compiler - uses: lukka/run-cmake@v2 - with: - cmakeGenerator: Unix Makefiles - cmakeListsOrSettingsJson: CMakeListsTxtAdvanced - cmakeListsTxtPath: ${{ github.workspace }}/Firmware/CMakeLists.txt - cmakeBuildType: Debug - cmakeAppendedArgs : '-DTARGET_PLATFORM:STRING="FIRMWARE_SIMULATOR" -DCMAKE_BUILD_TYPE:STRING=Debug -DREDUCE_LVGL_BINARY_SIZE=OFF -DPACKAGE_TESTS=ON -DENABLE_SANITIZE_BUILD=ON' - buildDirectory: ${{ env.buildDir }} - buildWithCMake: true - - - name : Run firmware testing - run: | - cd ${{ env.buildDir }} - ./FirmwareTesting + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + with: + submodules: "true" + + - name: Setup python + uses: actions/setup-python@v2 + with: + python-version: "3.8" + + - name: Install conan + uses: BSFishy/pip-action@v1 + with: + packages: | + conan + + - name: Intall system required packages + run: | + sudo apt-get update + sudo apt-get install -y libegl-dev + #Install the latest cmake + - name: Get the latest CMake version + uses: lukka/get-cmake@latest + + - name: Set up GCC 11 + uses: egor-tensin/setup-gcc@v1 + with: + version: 11 + platform: x64 + + - name: Run CMakeLists generation for GCC compiler + uses: lukka/run-cmake@v2 + with: + cmakeGenerator: Unix Makefiles + cmakeListsOrSettingsJson: CMakeListsTxtAdvanced + cmakeListsTxtPath: ${{ github.workspace }}/Firmware/CMakeLists.txt + cmakeBuildType: Debug + cmakeAppendedArgs: '-DTARGET_PLATFORM:STRING="FIRMWARE_SIMULATOR" -DCMAKE_BUILD_TYPE:STRING=Debug -DREDUCE_LVGL_BINARY_SIZE=OFF -DPACKAGE_TESTS=ON -DENABLE_SANITIZE_BUILD=ON' + buildDirectory: ${{ env.buildDir }} + buildWithCMake: true + + - name: Run firmware testing + run: | + cd ${{ env.buildDir }} + ./FirmwareTesting From 6f9251c2021fe4d465492cea1a3092ed9649c542 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Tue, 22 Mar 2022 19:22:28 +0200 Subject: [PATCH 27/54] Updated conan-cmake version --- Firmware/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Firmware/CMakeLists.txt b/Firmware/CMakeLists.txt index 1faa160c..1b94a99e 100644 --- a/Firmware/CMakeLists.txt +++ b/Firmware/CMakeLists.txt @@ -32,9 +32,9 @@ if( ${TARGET_PLATFORM} STREQUAL "ARM_CORTEX" ) elseif(${TARGET_PLATFORM} STREQUAL "FIRMWARE_SIMULATOR") if(NOT EXISTS "${CMAKE_BINARY_DIR}/conan.cmake") message(STATUS "Downloading conan.cmake from https://github.com/conan-io/cmake-conan") - file(DOWNLOAD "https://raw.githubusercontent.com/conan-io/cmake-conan/v0.16.1/conan.cmake" + file(DOWNLOAD "https://raw.githubusercontent.com/conan-io/cmake-conan/release/0.17/conan.cmake" "${CMAKE_BINARY_DIR}/conan.cmake" - EXPECTED_HASH SHA256=396e16d0f5eabdc6a14afddbcfff62a54a7ee75c6da23f32f7a31bc85db23484 + EXPECTED_HASH SHA256=3bef79da16c2e031dc429e1dac87a08b9226418b300ce004cc125a82687baeef TLS_VERIFY ON) endif() From e13fe5b6048ed345d2b5725c2e5ddc3c459554b1 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Wed, 23 Mar 2022 22:31:26 +0200 Subject: [PATCH 28/54] Refactored root CMakeLists.txt to using the CMAKE_CURRENT_LIST_DIR location --- Firmware/CMakeLists.txt | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/Firmware/CMakeLists.txt b/Firmware/CMakeLists.txt index 1b94a99e..1de1a743 100644 --- a/Firmware/CMakeLists.txt +++ b/Firmware/CMakeLists.txt @@ -13,7 +13,7 @@ if( ${TARGET_PLATFORM} STREQUAL "ARM_CORTEX" ) -MP -MD -mthumb -mabi=aapcs -Wall -g3 -ffunction-sections -fdata-sections -fno-strict-aliasing -fno-builtin --short-enums -fno-exceptions ${CPU_FLAGS} ) - set( CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/cmake/arm-gcc-toolchain.cmake ) + set( CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_LIST_DIR}/cmake/arm-gcc-toolchain.cmake ) endif() project(nordic-template C CXX ASM) @@ -23,7 +23,7 @@ if( ${TARGET_PLATFORM} STREQUAL "ARM_CORTEX" ) set( NRF_TARGET "nrf52" ) set( NRF52SOFTDEVICE "S112" ) - set( SDK_DEPENDENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/sdk_dependent") + set( SDK_DEPENDENT_DIR "${CMAKE_CURRENT_LIST_DIR}/sdk_dependent") #https://stackoverflow.com/questions/31355692/how-do-i-enable-link-time-optimization-lto-with-cmake set(CMAKE_INTERPROCEDURAL_OPTIMIZATION FALSE) @@ -62,9 +62,7 @@ elseif(${TARGET_PLATFORM} STREQUAL "FIRMWARE_SIMULATOR") endif() -set (3RDPARTY_DIR "3rdparty") -add_subdirectory( ${3RDPARTY_DIR} ${CMAKE_BINARY_DIR}/3rdparty ) - +add_subdirectory(3rdparty) add_subdirectory(drivers) add_subdirectory(utils) add_subdirectory(logger) @@ -73,13 +71,9 @@ add_subdirectory(service_providers) add_subdirectory(filesystem) set (NORDIC_TARGET theOpenWatch) -add_executable(${NORDIC_TARGET} ${PROJECT_SOURCES}) - -target_sources( - ${NORDIC_TARGET} - PRIVATE - main.cpp - ap_application.cpp +add_executable(${NORDIC_TARGET} + ${CMAKE_CURRENT_LIST_DIR}/main.cpp + ${CMAKE_CURRENT_LIST_DIR}/ap_application.cpp ) target_link_libraries( From 4f21d46a32098f5a6ebfe391d71d0a924c5c17f6 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Wed, 23 Mar 2022 22:32:11 +0200 Subject: [PATCH 29/54] Application class has been changed to the singleton --- Firmware/ap_application.cpp | 14 ++++++++++---- Firmware/ap_application.hpp | 10 +++++----- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/Firmware/ap_application.cpp b/Firmware/ap_application.cpp index 7eb04f55..71215467 100644 --- a/Firmware/ap_application.cpp +++ b/Firmware/ap_application.cpp @@ -59,16 +59,22 @@ void Application::initBoard() noexcept void Application::initServices() noexcept { - m_fakeServiceProvider = ServiceProviders::getFakeServiceCreator(); - m_batteryLevelService = m_fakeServiceProvider->getBatteryService(); - m_heartrateService = m_fakeServiceProvider->getHeartrateService(); - m_dateTimeService = m_fakeServiceProvider->getDateTimeService(); + auto bleServiceProvider = ServiceProviders::getFakeServiceCreator(); + m_batteryLevelService = bleServiceProvider->getBatteryService(); + m_heartrateService = bleServiceProvider->getHeartrateService(); + m_dateTimeService = bleServiceProvider->getDateTimeService(); } void Application::initPeripheral() noexcept { } +Application& Application::Instance() +{ + static Application app; + return app; +} + void Application::initBleStack() noexcept { diff --git a/Firmware/ap_application.hpp b/Firmware/ap_application.hpp index 24049ac2..bf52ab74 100644 --- a/Firmware/ap_application.hpp +++ b/Firmware/ap_application.hpp @@ -20,11 +20,8 @@ class Application : public Utils::noncopyable { public: - Application() noexcept; - - ~Application() noexcept; + static Application& Instance(); -public: void runApplicationLoop() noexcept; private: @@ -40,9 +37,12 @@ class Application : public Utils::noncopyable void connectBoardSpecificEvents() noexcept; +private: + Application() noexcept; + ~Application() noexcept; + private: Ble::Stack::TSoftDevicePtr m_bleStackKeeper; - std::unique_ptr m_fakeServiceProvider; std::unique_ptr m_batteryLevelService; std::unique_ptr m_heartrateService; From 6afa37bcda560b22e28101611ee0bc6d1fd97ca3 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Sat, 26 Mar 2022 00:48:23 +0200 Subject: [PATCH 30/54] Refactored event subsystem dispatching --- Firmware/ap_application.cpp | 40 +++++++++---------- .../headers/ih/drivers/ih_button_driver.hpp | 4 +- Firmware/graphics/gs_event_dispatcher.hpp | 2 +- Firmware/graphics/ih/gs_events.hpp | 36 ++++++++--------- 4 files changed, 41 insertions(+), 41 deletions(-) diff --git a/Firmware/ap_application.cpp b/Firmware/ap_application.cpp index 71215467..0cfcb351 100644 --- a/Firmware/ap_application.cpp +++ b/Firmware/ap_application.cpp @@ -17,6 +17,8 @@ #include +namespace GsEvents = Graphics::Events; + namespace EventConvert { Graphics::Events::TButtonsEvents toButtonEvent(Buttons::ButtonState _buttonToConvert) @@ -94,23 +96,23 @@ void Application::initBleStack() noexcept auto& pMainWindow = m_graphicsService->getMainWindow(); m_bleStackKeeper->onConnected.connect([&pMainWindow] { pMainWindow.getEventDispatcher().postEvent( - {Graphics::Events::EventGroup::BleDevice, - Graphics::Events::TBleClientEvents::DeviceConnected, + {GsEvents::EventGroup::BleDevice, + GsEvents::to_underlying(GsEvents::TBleClientEvents::DeviceConnected), std::nullopt}); }); m_bleStackKeeper->onDisconnected.connect([&pMainWindow] { pMainWindow.getEventDispatcher().postEvent( - {Graphics::Events::EventGroup::BleDevice, - Graphics::Events::TBleClientEvents::DeviceDisconnected, + {GsEvents::EventGroup::BleDevice, + GsEvents::to_underlying(GsEvents::TBleClientEvents::DeviceDisconnected), std::nullopt}); }); auto& dateTimeService = m_bleStackKeeper->getDateTimeService(); dateTimeService.onDateTimeDiscovered.connect([&pMainWindow](const TimeWrapper& _newBleTime) { pMainWindow.getEventDispatcher().postEvent( - {Graphics::Events::EventGroup::DateTime, - Graphics::Events::TDateTimeEvents::DateTimeChanged, + {GsEvents::EventGroup::DateTime, + GsEvents::to_underlying(GsEvents::TDateTimeEvents::DateTimeChanged), _newBleTime}); }); } @@ -124,15 +126,15 @@ void Application::initGraphicsStack() noexcept m_batteryLevelService->onBatteryLevelChangedSig.connect( [&pMainWindow](std::uint8_t _newBatteryValue) { pMainWindow.getEventDispatcher().postEvent( - {Graphics::Events::EventGroup::Battery, - Graphics::Events::TBatteryEvents::BatteryLevelChanged, + {GsEvents::EventGroup::Battery, + GsEvents::to_underlying(GsEvents::TBatteryEvents::BatteryLevelChanged), _newBatteryValue}); }); m_dateTimeService->onDateTimeChanged.connect([&pMainWindow](const TimeWrapper& _newTime) { pMainWindow.getEventDispatcher().postEvent( - {Graphics::Events::EventGroup::DateTime, - Graphics::Events::TDateTimeEvents::DateTimeChanged, + {GsEvents::EventGroup::DateTime, + GsEvents::to_underlying(GsEvents::TDateTimeEvents::DateTimeChanged), _newTime}); }); } @@ -141,17 +143,15 @@ void Application::connectBoardSpecificEvents() noexcept { auto& pMainWindow = m_graphicsService->getMainWindow(); - m_pBoardImpl->getButtonsDriver()->onButtonEvent.connect( - [&pMainWindow](Buttons::ButtonEvent _buttonEvent) { - Graphics::Events::HardwareButtonId graphicsButton{ - Graphics::Events::enumConvert( - _buttonEvent.buttonId)}; + m_pBoardImpl->getButtonsDriver()->onButtonEvent.connect([&pMainWindow]( + Buttons::ButtonEvent _buttonEvent) { + GsEvents::HardwareButtonId graphicsButton{GsEvents::to_underlying(_buttonEvent.buttonId)}; - pMainWindow.getEventDispatcher().postEvent( - {Graphics::Events::EventGroup::Buttons, - EventConvert::toButtonEvent(_buttonEvent.buttonEvent), - graphicsButton}); - }); + pMainWindow.getEventDispatcher().postEvent( + {GsEvents::EventGroup::Buttons, + GsEvents::to_underlying(EventConvert::toButtonEvent(_buttonEvent.buttonEvent)), + graphicsButton}); + }); } void Application::runApplicationLoop() noexcept diff --git a/Firmware/drivers/headers/ih/drivers/ih_button_driver.hpp b/Firmware/drivers/headers/ih/drivers/ih_button_driver.hpp index 57e092d7..2c407ba3 100644 --- a/Firmware/drivers/headers/ih/drivers/ih_button_driver.hpp +++ b/Firmware/drivers/headers/ih/drivers/ih_button_driver.hpp @@ -12,7 +12,7 @@ namespace Buttons { -enum class ButtonState +enum class ButtonState : std::uint8_t { kButtonUp, kButtonDown, @@ -22,7 +22,7 @@ enum class ButtonState Undefined }; -enum class ButtonId +enum class ButtonId : std::uint8_t { kLeftButtonTop, kLeftButtonMedium, diff --git a/Firmware/graphics/gs_event_dispatcher.hpp b/Firmware/graphics/gs_event_dispatcher.hpp index 7c8bd80d..c224f315 100644 --- a/Firmware/graphics/gs_event_dispatcher.hpp +++ b/Firmware/graphics/gs_event_dispatcher.hpp @@ -33,7 +33,7 @@ class EventDispatcher : private Utils::noncopyable private: static constexpr inline int EventsCount = - Events::enumConvert(EventGroup::EventGroupEnd); + Events::to_underlying(EventGroup::EventGroupEnd); static constexpr inline int EventPoolSize = 16; using TEventsMap = etl::vector, EventsCount>; diff --git a/Firmware/graphics/ih/gs_events.hpp b/Firmware/graphics/ih/gs_events.hpp index 85146ecf..e24d6451 100644 --- a/Firmware/graphics/ih/gs_events.hpp +++ b/Firmware/graphics/ih/gs_events.hpp @@ -1,12 +1,13 @@ #pragma once #include +#include #include namespace Graphics::Events { -enum class EventGroup +enum class EventGroup : std::uint8_t { Battery, Heartrate, @@ -22,7 +23,7 @@ enum class EventGroup struct TEvent { EventGroup eventGroup; - std::any eventType; + std::uint8_t eventType; std::any eventData; }; @@ -31,54 +32,53 @@ enum class TEventKind EventBegin }; -template -constexpr auto enumConvert(TToConvert _valueToConvert) +template constexpr auto to_underlying(TToConvert _valueToConvert) { - return static_cast::type>(_valueToConvert); + return static_cast::type>(_valueToConvert); } -enum class TBatteryEvents +enum class TBatteryEvents : std::uint8_t { - BatteryEventsStart = enumConvert(TEventKind::EventBegin), + BatteryEventsStart = to_underlying(TEventKind::EventBegin), BatteryLevelChanged, BatteryEventsEnd }; -enum class THeartRateEvents +enum class THeartRateEvents : std::uint8_t { - HeartRateEventsBegin = enumConvert(TBatteryEvents::BatteryEventsEnd), + HeartRateEventsBegin = to_underlying(TBatteryEvents::BatteryEventsEnd), MeasureStarted, MeasureCompleted, MeasureFailed, HeartRateEventsEnd }; -enum class TDateTimeEvents +enum class TDateTimeEvents : std::uint8_t { - DateTimeEventsBegin = enumConvert(THeartRateEvents::HeartRateEventsEnd), + DateTimeEventsBegin = to_underlying(THeartRateEvents::HeartRateEventsEnd), DateTimeChanged, DateTimeEventsEnd }; -enum class TBleClientEvents +enum class TBleClientEvents : std::uint8_t { - BleClientEventsBegin = enumConvert(TDateTimeEvents::DateTimeEventsEnd), + BleClientEventsBegin = to_underlying(TDateTimeEvents::DateTimeEventsEnd), DeviceConnected, DeviceDisconnected, BleClientEventsEnd }; -enum class TGraphicsEvents +enum class TGraphicsEvents : std::uint8_t { - GraphicsEventsBegin = enumConvert(TBleClientEvents::BleClientEventsEnd), + GraphicsEventsBegin = to_underlying(TBleClientEvents::BleClientEventsEnd), PageHiding, PageActivated, GraphicsEventsEnd }; -enum class TButtonsEvents +enum class TButtonsEvents : std::uint8_t { - TButtonsEventsBegin = enumConvert(TGraphicsEvents::GraphicsEventsEnd), + TButtonsEventsBegin = to_underlying(TGraphicsEvents::GraphicsEventsEnd), ButtonClicked, ButtonPressed, ButtonReleased, @@ -87,7 +87,7 @@ enum class TButtonsEvents ButtonEventsEnd }; -enum class HardwareButtonId +enum class HardwareButtonId : std::uint8_t { kLeftButtonTop, kLeftButtonMedium, From 4b3819b68ca0168e943970a4ba5c51e97362cbf2 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Sat, 26 Mar 2022 00:48:49 +0200 Subject: [PATCH 31/54] Application instance was moved to Singleton --- Firmware/main.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/Firmware/main.cpp b/Firmware/main.cpp index fb84bd5b..ac52bd74 100644 --- a/Firmware/main.cpp +++ b/Firmware/main.cpp @@ -2,10 +2,6 @@ int main(void) { - - Application mainApp; - - mainApp.runApplicationLoop(); - + Application::Instance().runApplicationLoop(); return 0; } \ No newline at end of file From 9981bac1015150da54121ebdb761b4f9698010b2 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Sat, 26 Mar 2022 01:02:15 +0200 Subject: [PATCH 32/54] Success compilation of the coro-fs implementation on the ARM target --- Firmware/3rdparty/littlefs_lib/CMakeLists.txt | 20 +++++++- Firmware/drivers/board/CMakeLists.txt | 1 + .../board/inc/board/hardware_usings.hpp | 29 ++++++++++++ .../drivers/board/inc/board/watchboard.hpp | 7 ++- Firmware/drivers/board/watchboard.cpp | 19 ++++---- Firmware/filesystem/CMakeLists.txt | 12 ++--- .../block_device_wrapper/spi_block_device.hpp | 46 ++++++++++--------- .../filesystem/filesystem_holder.hpp | 8 ++-- Firmware/firmware_tests/CMakeLists.txt | 2 +- .../firmware_tests/coroutine/CMakeLists.txt | 2 +- .../coroutine/coroutine_thoughts.cpp | 2 +- .../filesystem/filesystem_fixture.hpp | 2 +- Firmware/utils/CMakeLists.txt | 5 ++ .../coroutine/BlockingEventBaremetal.hpp | 23 ++++++++++ .../utils/coroutine/BlockingEventCondvar.hpp | 28 +++++++++++ .../utils/inc/utils/coroutine/SyncWait.hpp | 29 ++---------- 16 files changed, 165 insertions(+), 70 deletions(-) create mode 100644 Firmware/utils/inc/utils/coroutine/BlockingEventBaremetal.hpp create mode 100644 Firmware/utils/inc/utils/coroutine/BlockingEventCondvar.hpp diff --git a/Firmware/3rdparty/littlefs_lib/CMakeLists.txt b/Firmware/3rdparty/littlefs_lib/CMakeLists.txt index a0aa3292..1f30b505 100644 --- a/Firmware/3rdparty/littlefs_lib/CMakeLists.txt +++ b/Firmware/3rdparty/littlefs_lib/CMakeLists.txt @@ -12,4 +12,22 @@ target_include_directories(littlefs PUBLIC littlefs target_link_libraries(littlefs PUBLIC UtilsLibrary ) -target_compile_definitions(littlefs PUBLIC LFS_YES_TRACE ) \ No newline at end of file +target_compile_definitions(littlefs PUBLIC LFS_YES_TRACE ) + +target_link_options( + littlefs + PUBLIC + ${CPU_FLAGS} +) + +target_compile_options( + littlefs + PUBLIC + ${COMMON_FLAGS} +) + +target_compile_options( + littlefs + PUBLIC + $<$:-Os> +) diff --git a/Firmware/drivers/board/CMakeLists.txt b/Firmware/drivers/board/CMakeLists.txt index 2194ea33..146b9b18 100644 --- a/Firmware/drivers/board/CMakeLists.txt +++ b/Firmware/drivers/board/CMakeLists.txt @@ -16,6 +16,7 @@ target_link_libraries( buttons_driver spi windbond_spi_flash_driver + watch_filesystem PRIVATE UtilsLibrary logger_service diff --git a/Firmware/drivers/board/inc/board/hardware_usings.hpp b/Firmware/drivers/board/inc/board/hardware_usings.hpp index 4b92cf1f..3474b88c 100644 --- a/Firmware/drivers/board/inc/board/hardware_usings.hpp +++ b/Firmware/drivers/board/inc/board/hardware_usings.hpp @@ -4,6 +4,9 @@ #ifndef USE_DEVICE_SPECIFIC #include #include +#include +#include +#include #else #include #include @@ -12,6 +15,9 @@ #include #include +#include +#include + namespace Hal { @@ -20,6 +26,15 @@ using BoardTimer = Buttons::FirmwareSimulatorTimerBackend; using ButtonsBackend = Buttons::FirmwareSimulatorButtonsBackend; using TFlashDriver = ExternalFlash::WinbondFlashDriver< Interface::SpiTemplated::SpiBus>; + +using TLogHeapBlockDevice = + Filesystem::BlockDevice::LogAdaptorBlockDevice>; + +using TFilesystem = Platform::Fs::Holder; #else using BoardTimer = Buttons::NordicTimerBackend; using ButtonsBackend = Buttons::NordicButtonsBackend; @@ -27,6 +42,20 @@ using TFlashDriver = ExternalFlash::WinbondFlashDriver< Interface::SpiTemplated::SpiBus>>; + +struct BoardSpiFlashDescriptor +{ + static constexpr inline std::size_t kBlockSize = 256; + static constexpr inline std::size_t kSectorsCount = 65'536; + static constexpr inline std::size_t kReadSize = 256; + static constexpr inline std::size_t kEraseSize = 4096; +}; + +using TSpiFlashBlockDevice = + Filesystem::BlockDevice::SpiFlashBlockDevice; + +using TFilesystem = Platform::Fs::Holder; + #endif using ButtonsDriver = Buttons::ButtonsDriverTemplate; diff --git a/Firmware/drivers/board/inc/board/watchboard.hpp b/Firmware/drivers/board/inc/board/watchboard.hpp index 6abb89b5..381f0b99 100644 --- a/Firmware/drivers/board/inc/board/watchboard.hpp +++ b/Firmware/drivers/board/inc/board/watchboard.hpp @@ -3,9 +3,12 @@ #include #include -#include "hardware_usings.hpp" #include +#include +#include +#include + namespace WatchBoard { @@ -35,7 +38,9 @@ class Board : private Utils::noncopyable private: Hal::ButtonsDriver m_buttonsDriver; using TFlashDriverPtr = std::unique_ptr; + using TFilesystemPtr = std::unique_ptr; + TFilesystemPtr m_filesystem; TFlashDriverPtr m_pFlashDriver; }; diff --git a/Firmware/drivers/board/watchboard.cpp b/Firmware/drivers/board/watchboard.cpp index ae91d141..88933898 100644 --- a/Firmware/drivers/board/watchboard.cpp +++ b/Firmware/drivers/board/watchboard.cpp @@ -21,7 +21,7 @@ APP_TIMER_DEF(m_ledDriverTimer); #include #include -#if defined (USE_DEVICE_SPECIFIC) +#if defined(USE_DEVICE_SPECIFIC) #define FMT_HEADER_ONLY #endif @@ -115,15 +115,16 @@ void Board::initBoardTimer() noexcept void Board::initBoardSpiFlash() noexcept { m_pFlashDriver = std::make_unique(); - if (m_pFlashDriver) - { - const std::uint32_t JedecId = co_await m_pFlashDriver->requestJEDEDCId(); - LOG_DEBUG("Jedec Id is:"); - LOG_DEBUG_ENDL(fmt::format("{:#04x}", JedecId)); - const std::span DeviceId = co_await m_pFlashDriver->requestDeviceId(); - LOG_DEBUG_ENDL(fmt::format("{:02X}", fmt::join(DeviceId, ""))); - } + const std::uint32_t JedecId = co_await m_pFlashDriver->requestJEDEDCId(); + LOG_DEBUG("Jedec Id is:"); + LOG_DEBUG_ENDL(fmt::format("{:#04x}", JedecId)); + + const std::span DeviceId = co_await m_pFlashDriver->requestDeviceId(); + LOG_DEBUG_ENDL(fmt::format("{:02X}", fmt::join(DeviceId, ""))); + + m_filesystem = std::make_unique(); + CoroUtils::syncWait(m_filesystem->initializeFs()); } Board::Board() noexcept diff --git a/Firmware/filesystem/CMakeLists.txt b/Firmware/filesystem/CMakeLists.txt index c3f73d17..71d704b3 100644 --- a/Firmware/filesystem/CMakeLists.txt +++ b/Firmware/filesystem/CMakeLists.txt @@ -2,31 +2,31 @@ if(WIN32 OR UNIX AND ${TARGET_PLATFORM} STREQUAL "FIRMWARE_SIMULATOR") find_package(spdlog REQUIRED) endif() -add_library(filesystem INTERFACE +add_library(watch_filesystem INTERFACE filesystem/filesystem_holder.hpp filesystem/block_device_wrapper/combiner_block_device.hpp ) -target_sources(filesystem INTERFACE +target_sources(watch_filesystem INTERFACE filesystem/block_device_wrapper/ih_block_device.hpp filesystem/block_device_wrapper/heap_block_device.hpp filesystem/block_device_wrapper/adaptor_block_device.hpp filesystem/block_device_wrapper/spi_block_device.hpp ) -target_include_directories(filesystem INTERFACE ${CMAKE_CURRENT_LIST_DIR} ) +target_include_directories(watch_filesystem INTERFACE ${CMAKE_CURRENT_LIST_DIR} ) -target_link_libraries(filesystem INTERFACE +target_link_libraries(watch_filesystem INTERFACE littlefs ) if(WIN32 OR UNIX AND ${TARGET_PLATFORM} STREQUAL "FIRMWARE_SIMULATOR" ) - target_link_libraries(filesystem INTERFACE spdlog::spdlog) + target_link_libraries(watch_filesystem INTERFACE spdlog::spdlog) endif() target_link_libraries( - filesystem INTERFACE + watch_filesystem INTERFACE drivers_ih windbond_spi_flash_driver ) \ No newline at end of file diff --git a/Firmware/filesystem/filesystem/block_device_wrapper/spi_block_device.hpp b/Firmware/filesystem/filesystem/block_device_wrapper/spi_block_device.hpp index f5054361..5ba84632 100644 --- a/Firmware/filesystem/filesystem/block_device_wrapper/spi_block_device.hpp +++ b/Firmware/filesystem/filesystem/block_device_wrapper/spi_block_device.hpp @@ -4,29 +4,40 @@ namespace Filesystem::BlockDevice { -template -class SpiFlashBlockDevice : public BlockDeviceEntity> + +struct FlashBlockDeviceDescriptor +{ + static constexpr inline std::size_t kBlockSize = 256; + static constexpr inline std::size_t kSectorsCount = 65'536; + static constexpr inline std::size_t kReadSize = 256; + static constexpr inline std::size_t kEraseSize = 4096; +}; + +template + +class SpiFlashBlockDevice + : public BlockDeviceEntity> { public: constexpr std::uint32_t getBlockSize() const noexcept { - return kBlockSize; + return TBlockDeviceDescriptor::kBlockSize; } constexpr std::uint32_t getBlocksCount() const noexcept { - return kSectorsCount; + return TBlockDeviceDescriptor::kSectorsCount; } constexpr std::uint32_t getReadSize() const noexcept { - return kReadSize; + return TBlockDeviceDescriptor::kReadSize; } constexpr std::uint32_t getProgSize() const noexcept { - return kBlockSize; + return TBlockDeviceDescriptor::kBlockSize; } constexpr std::uint32_t getEraseSize() const noexcept { - return kEraseSize; + return TBlockDeviceDescriptor::kEraseSize; } public: @@ -41,10 +52,8 @@ class SpiFlashBlockDevice : public BlockDeviceEntity 0) { - std::uint32_t highPart = blockAddress / getBlockSize(); - std::uint32_t lowPart = blockAddress % getBlockSize(); - - co_await m_currentFlashDriver.pageWrite(_address, std::span(_blockData, _blockSize)); + co_await m_currentFlashDriver.pageWrite( + blockAddress, std::span(pBlockRequest, getProgSize())); blockAddress += getProgSize(); pBlockRequest += getProgSize(); @@ -64,10 +73,8 @@ class SpiFlashBlockDevice : public BlockDeviceEntity 0) { - std::uint32_t hi = blockAddress / getBlockSize(); - std::uint32_t lo = blockAddress % getBlockSize(); - - auto resultBuffer = co_await m_currentFlashDriver.requestReadBlock(); + auto resultBuffer = + co_await m_currentFlashDriver.requestReadBlock(blockAddress, getReadSize()); memcpy(pReadBuffer, resultBuffer.data(), getReadSize()); blockAddress += getReadSize(); @@ -77,14 +84,11 @@ class SpiFlashBlockDevice : public BlockDeviceEntity +using SpiBlockDeviceDefaultDevice = SpiFlashBlockDevice; + }; // namespace Filesystem::BlockDevice \ No newline at end of file diff --git a/Firmware/filesystem/filesystem/filesystem_holder.hpp b/Firmware/filesystem/filesystem/filesystem_holder.hpp index b6250eae..a134faa7 100644 --- a/Firmware/filesystem/filesystem/filesystem_holder.hpp +++ b/Firmware/filesystem/filesystem/filesystem_holder.hpp @@ -3,15 +3,15 @@ #include #include #include -#include #include +#include #include #include #include -#include #include +//#include namespace Platform::Fs { @@ -158,7 +158,6 @@ template class Holder template class File { public: - constexpr File(lfs_t* pFsHolder) noexcept : m_pFileHandle{std::make_unique()}, m_pFsHolder{pFsHolder} { @@ -176,7 +175,8 @@ template class File return; CoroUtils::syncWait(lfs_file_close(m_pFsHolder, m_pFileHandle.get())); - spdlog::warn("~File::File()"); + // TODO move somewhere to global observer + // spdlog::warn("~File::File()"); } CoroUtils::VoidTask write(std::span dataHolder) noexcept diff --git a/Firmware/firmware_tests/CMakeLists.txt b/Firmware/firmware_tests/CMakeLists.txt index a340c5bc..00465aef 100644 --- a/Firmware/firmware_tests/CMakeLists.txt +++ b/Firmware/firmware_tests/CMakeLists.txt @@ -64,7 +64,7 @@ target_link_libraries( watch_display lvgl_lib drivers_ih - filesystem + watch_filesystem buttons_driver windbond_spi_flash_driver ) diff --git a/Firmware/firmware_tests/coroutine/CMakeLists.txt b/Firmware/firmware_tests/coroutine/CMakeLists.txt index 661b4c70..e727bf8e 100644 --- a/Firmware/firmware_tests/coroutine/CMakeLists.txt +++ b/Firmware/firmware_tests/coroutine/CMakeLists.txt @@ -43,7 +43,7 @@ target_link_libraries( watch_display UtilsLibrary logger_service - filesystem + watch_filesystem ) if(UNIX) target_link_libraries( coroutine_experiments_app PUBLIC Threads::Threads) diff --git a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp index 9519e59a..e5887b3b 100644 --- a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp +++ b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp @@ -32,7 +32,7 @@ using TSpiBus = Interface::SpiTemplated::SpiBus; using TFlashDriver = ExternalFlash::WinbondFlashDriver; -using TSpiFlashBlockDevice = Filesystem::BlockDevice::SpiFlashBlockDevice; +using TSpiFlashBlockDevice = Filesystem::BlockDevice::SpiBlockDeviceDefaultDevice; using TDisplayDriver = DisplayDriver::GC9A01Compact; diff --git a/Firmware/firmware_tests/filesystem/filesystem_fixture.hpp b/Firmware/firmware_tests/filesystem/filesystem_fixture.hpp index 30f56df7..f2c7ce6a 100644 --- a/Firmware/firmware_tests/filesystem/filesystem_fixture.hpp +++ b/Firmware/firmware_tests/filesystem/filesystem_fixture.hpp @@ -21,7 +21,7 @@ using TFlashTestDriver = ExternalFlash::WinbondFlashDriver< Interface::SpiTemplated::SpiBus>; -using TSpiFlashBlockDevice = Filesystem::BlockDevice::SpiFlashBlockDevice; +using TSpiFlashBlockDevice = Filesystem::BlockDevice::SpiBlockDeviceDefaultDevice; using TLogHeapBlockDevice = Filesystem::BlockDevice::LogAdaptorBlockDevice + +namespace CoroUtils +{ +class BlockingEvent +{ +public: + void wait() + { + while (!m_isSet) + { + } + } + + void set() + { + m_isSet.store(true); + } + +private: + std::atomic_bool m_isSet = false; +}; +} // namespace CoroUtils \ No newline at end of file diff --git a/Firmware/utils/inc/utils/coroutine/BlockingEventCondvar.hpp b/Firmware/utils/inc/utils/coroutine/BlockingEventCondvar.hpp new file mode 100644 index 00000000..08409957 --- /dev/null +++ b/Firmware/utils/inc/utils/coroutine/BlockingEventCondvar.hpp @@ -0,0 +1,28 @@ +// Detailed research from cppcoro library +#include +#include +#include + +namespace CoroUtils +{ +class BlockingEvent +{ +public: + void wait() + { + std::unique_lock lock(mutex); + condEvent.wait(lock, [this] { return m_isSet.load(std::memory_order_acquire); }); + } + + void set() + { + m_isSet.store(true, std::memory_order_release); + condEvent.notify_all(); + } + +private: + std::atomic_bool m_isSet = false; + std::mutex mutex; + std::condition_variable condEvent; +}; +} \ No newline at end of file diff --git a/Firmware/utils/inc/utils/coroutine/SyncWait.hpp b/Firmware/utils/inc/utils/coroutine/SyncWait.hpp index 48b11b31..1b3173aa 100644 --- a/Firmware/utils/inc/utils/coroutine/SyncWait.hpp +++ b/Firmware/utils/inc/utils/coroutine/SyncWait.hpp @@ -1,10 +1,12 @@ #pragma once #include "Event.hpp" #include "Task.hpp" +#if defined USE_DESKTOP_SIMULATOR +#include "BlockingEventCondvar.hpp" +#else +#include "BlockingEventBaremetal.hpp" +#endif -// Detailed research from cppcoro library -#include -#include namespace CoroUtils { @@ -37,27 +39,6 @@ auto awaiterGetter(TAwaiter&& _awaiter) -> decltype(awaiterGetterImpl(_awaiter,0 } -class BlockingEvent -{ -public: - void wait() - { - std::unique_lock lock(mutex); - condEvent.wait(lock, [this] { return m_isSet.load(std::memory_order_acquire); }); - } - - void set() - { - m_isSet.store(true, std::memory_order_release); - condEvent.notify_all(); - } - -private: - std::atomic_bool m_isSet = false; - std::mutex mutex; - std::condition_variable condEvent; -}; - template struct AwaitResultGetter { From 7b79909400a4c4409e22fa4c37d90e51d1950a7a Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Sat, 26 Mar 2022 01:02:44 +0200 Subject: [PATCH 33/54] Fixed windows simulator build. Removed unnecessary any_cast --- .../buttons_driver/buttons_fixture.hpp | 2 +- .../clock_page_handler_fixture.hpp | 4 ++-- .../clock_page_view_handler_test.cpp | 22 +++++++++---------- .../main_window/mainwindow_model_test.cpp | 6 ++--- .../widgets_layer/gs_event_handler_base.hpp | 12 +++++----- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/Firmware/firmware_tests/buttons_driver/buttons_fixture.hpp b/Firmware/firmware_tests/buttons_driver/buttons_fixture.hpp index 6abed442..fbdfa27d 100644 --- a/Firmware/firmware_tests/buttons_driver/buttons_fixture.hpp +++ b/Firmware/firmware_tests/buttons_driver/buttons_fixture.hpp @@ -38,7 +38,7 @@ class ButtonsDriverTest : public ::testing::Test m_pButtonsDriver.onButtonEvent.connect([this](const Buttons::ButtonEvent& _buttonEvent) { m_pEventDispatcher->postEvent( {Graphics::Events::EventGroup::Buttons, - toUiEvent(_buttonEvent.buttonEvent), + Graphics::Events::to_underlying(toUiEvent(_buttonEvent.buttonEvent)), _buttonEvent.buttonId}); }); } diff --git a/Firmware/firmware_tests/clock_page_handler/clock_page_handler_fixture.hpp b/Firmware/firmware_tests/clock_page_handler/clock_page_handler_fixture.hpp index 31a58e8a..64726329 100644 --- a/Firmware/firmware_tests/clock_page_handler/clock_page_handler_fixture.hpp +++ b/Firmware/firmware_tests/clock_page_handler/clock_page_handler_fixture.hpp @@ -27,7 +27,7 @@ class ClockPageHandlerTest : public ::testing::Test pageWatchHandler->handleEvent( {Graphics::Events::EventGroup::DateTime, - Graphics::Events::TDateTimeEvents::DateTimeChanged, + Graphics::Events::to_underlying(Graphics::Events::TDateTimeEvents::DateTimeChanged), TimeWrapper("2020/06/22 14:24:43", '/', ':')}); } @@ -45,7 +45,7 @@ class ClockPageHandlerTest : public ::testing::Test pageMockWatchHandler->handleEvent( {Graphics::Events::EventGroup::DateTime, - Graphics::Events::TDateTimeEvents::DateTimeChanged, + Graphics::Events::to_underlying(Graphics::Events::TDateTimeEvents::DateTimeChanged), TimeWrapper("2020/06/22 14:24:43", '/', ':')}); } diff --git a/Firmware/firmware_tests/clock_page_handler/clock_page_view_handler_test.cpp b/Firmware/firmware_tests/clock_page_handler/clock_page_view_handler_test.cpp index 2fc1fb92..8c25e991 100644 --- a/Firmware/firmware_tests/clock_page_handler/clock_page_view_handler_test.cpp +++ b/Firmware/firmware_tests/clock_page_handler/clock_page_view_handler_test.cpp @@ -35,7 +35,7 @@ TEST_F(ClockPageHandlerTest, ViewStaysUnchangedWhenInviisible) // Only hours were changed pageWatchHandler->handleEvent( {Graphics::Events::EventGroup::DateTime, - Graphics::Events::TDateTimeEvents::DateTimeChanged, + Graphics::Events::to_underlying(Graphics::Events::TDateTimeEvents::DateTimeChanged), TimeWrapper("2020/06/22 14:24:43", '/', ':')}); EXPECT_EQ(fakeView.getHours(), "14"); } @@ -53,7 +53,7 @@ TEST_F(ClockPageHandlerTest, OnlyHoursLabelIsRefreshedWhenNewDateTimeEventOccurs // Only hours were changed pageMockWatchHandler->handleEvent( {Graphics::Events::EventGroup::DateTime, - Graphics::Events::TDateTimeEvents::DateTimeChanged, + Graphics::Events::to_underlying( Graphics::Events::TDateTimeEvents::DateTimeChanged), TimeWrapper("2020/06/22 15:24:43", '/', ':')}); } @@ -70,7 +70,7 @@ TEST_F(ClockPageHandlerTest, FulldateRefreshedWhenWeekdayWasChanged) // Only weekday was changed pageMockWatchHandler->handleEvent( {Graphics::Events::EventGroup::DateTime, - Graphics::Events::TDateTimeEvents::DateTimeChanged, + Graphics::Events::to_underlying(Graphics::Events::TDateTimeEvents::DateTimeChanged), TimeWrapper("2020/06/29 14:24:43", '/', ':')}); } @@ -87,7 +87,7 @@ TEST_F(ClockPageHandlerTest, FulldateRefreshedWhenMonthWasChanged) // Only month was changed pageMockWatchHandler->handleEvent( {Graphics::Events::EventGroup::DateTime, - Graphics::Events::TDateTimeEvents::DateTimeChanged, + Graphics::Events::to_underlying(Graphics::Events::TDateTimeEvents::DateTimeChanged), TimeWrapper("2020/07/13 14:24:43", '/', ':')}); } @@ -104,7 +104,7 @@ TEST_F(ClockPageHandlerTest, FulldateRefreshedWhenYearWasChanged) // Only year was changed pageMockWatchHandler->handleEvent( {Graphics::Events::EventGroup::DateTime, - Graphics::Events::TDateTimeEvents::DateTimeChanged, + Graphics::Events::to_underlying(Graphics::Events::TDateTimeEvents::DateTimeChanged), TimeWrapper("2021/06/14 14:24:43", '/', ':')}); } @@ -121,7 +121,7 @@ TEST_F(ClockPageHandlerTest, WeekdayChangeHandledCorrectly) pageMockWatchHandler->handleEvent( {Graphics::Events::EventGroup::DateTime, - Graphics::Events::TDateTimeEvents::DateTimeChanged, + Graphics::Events::to_underlying(Graphics::Events::TDateTimeEvents::DateTimeChanged), TimeWrapper("2020/06/23 14:24:43", '/', ':')}); } TEST_F(ClockPageHandlerTest, WeekdayChangeFromSundayToMondayHandledCorrectly) @@ -137,7 +137,7 @@ TEST_F(ClockPageHandlerTest, WeekdayChangeFromSundayToMondayHandledCorrectly) pageMockWatchHandler->handleEvent( {Graphics::Events::EventGroup::DateTime, - Graphics::Events::TDateTimeEvents::DateTimeChanged, + Graphics::Events::to_underlying(Graphics::Events::TDateTimeEvents::DateTimeChanged), TimeWrapper("2020/06/28 14:24:43", '/', ':')}); EXPECT_CALL(fakePageMock, setWeekday(std::string_view("MON"))).Times(1); @@ -145,7 +145,7 @@ TEST_F(ClockPageHandlerTest, WeekdayChangeFromSundayToMondayHandledCorrectly) pageMockWatchHandler->handleEvent( {Graphics::Events::EventGroup::DateTime, - Graphics::Events::TDateTimeEvents::DateTimeChanged, + Graphics::Events::to_underlying( Graphics::Events::TDateTimeEvents::DateTimeChanged), TimeWrapper("2020/06/29 14:24:43", '/', ':')}); } @@ -159,7 +159,7 @@ TEST_F(ClockPageHandlerTest, FormattingDateWorkCorrectlyForDigitsWithoutLeadingZ pageWatchHandler->handleEvent( {Graphics::Events::EventGroup::DateTime, - Graphics::Events::TDateTimeEvents::DateTimeChanged, + Graphics::Events::to_underlying(Graphics::Events::TDateTimeEvents::DateTimeChanged), TimeWrapper("2020/06/22 15:24:43", '/', ':')}); EXPECT_EQ(fakeView.getFullDate(), "JUN/22/2020"); } @@ -174,7 +174,7 @@ TEST_F(ClockPageHandlerTest, FormattingDateWorkCorrectlyForDigitsWithLeadingZero pageWatchHandler->handleEvent( {Graphics::Events::EventGroup::DateTime, - Graphics::Events::TDateTimeEvents::DateTimeChanged, + Graphics::Events::to_underlying(Graphics::Events::TDateTimeEvents::DateTimeChanged), TimeWrapper("2020/06/2 15:24:43", '/', ':')}); EXPECT_EQ(fakeView.getFullDate(), "JUN/02/2020"); } @@ -189,7 +189,7 @@ TEST_F(ClockPageHandlerTest, FormattingDateWorkCorrectlyForDigitsWithTrailingZer pageWatchHandler->handleEvent( {Graphics::Events::EventGroup::DateTime, - Graphics::Events::TDateTimeEvents::DateTimeChanged, + Graphics::Events::to_underlying(Graphics::Events::TDateTimeEvents::DateTimeChanged), TimeWrapper("2020/06/20 15:24:43", '/', ':')}); EXPECT_EQ(fakeView.getFullDate(), "JUN/20/2020"); } \ No newline at end of file diff --git a/Firmware/firmware_tests/main_window/mainwindow_model_test.cpp b/Firmware/firmware_tests/main_window/mainwindow_model_test.cpp index 2f62d1c4..292179e8 100644 --- a/Firmware/firmware_tests/main_window/mainwindow_model_test.cpp +++ b/Firmware/firmware_tests/main_window/mainwindow_model_test.cpp @@ -28,7 +28,7 @@ TEST_F(MainWindowTest, HandleNavigateToNextPage_ButtonClickEvent) { m_pMainWindow->getEventDispatcher().postEvent( {Graphics::Events::EventGroup::Buttons, - Graphics::Events::TButtonsEvents::ButtonClicked, + Graphics::Events::to_underlying(Graphics::Events::TButtonsEvents::ButtonClicked), Graphics::Events::HardwareButtonId::kLeftButtonTop}); m_pMainWindow->getEventDispatcher().processEventQueue(); @@ -44,7 +44,7 @@ TEST_F(MainWindowTest, HandleNavigateNextFromLastPage_ButtonClickEvent) m_pMainWindow->getEventDispatcher().postEvent( {Graphics::Events::EventGroup::Buttons, - Graphics::Events::TButtonsEvents::ButtonClicked, + Graphics::Events::to_underlying(Graphics::Events::TButtonsEvents::ButtonClicked), Graphics::Events::HardwareButtonId::kLeftButtonTop}); m_pMainWindow->getEventDispatcher().processEventQueue(); @@ -58,7 +58,7 @@ TEST_F(MainWindowTest, HandleNavigateToPreviousPageFromInitialState_ButtonClickE { m_pMainWindow->getEventDispatcher().postEvent( {Graphics::Events::EventGroup::Buttons, - Graphics::Events::TButtonsEvents::ButtonClicked, + Graphics::Events::to_underlying(Graphics::Events::TButtonsEvents::ButtonClicked), Graphics::Events::HardwareButtonId::kLeftButtonBottom}); m_pMainWindow->getEventDispatcher().processEventQueue(); diff --git a/Firmware/graphics/widgets_layer/gs_event_handler_base.hpp b/Firmware/graphics/widgets_layer/gs_event_handler_base.hpp index 2cfc20a1..18852a9f 100644 --- a/Firmware/graphics/widgets_layer/gs_event_handler_base.hpp +++ b/Firmware/graphics/widgets_layer/gs_event_handler_base.hpp @@ -37,41 +37,41 @@ class EventHandler case Events::EventGroup::Battery: if constexpr (Meta::HasType::value) this->handleEventImpl( - std::any_cast(genericEvent.eventType), + static_cast(genericEvent.eventType), genericEvent.eventData); break; case Events::EventGroup::Heartrate: if constexpr (Meta::HasType::value) this->handleEventImpl( - std::any_cast(genericEvent.eventType), + static_cast(genericEvent.eventType), genericEvent.eventData); break; case Events::EventGroup::BleDevice: if constexpr (Meta::HasType::value) this->handleEventImpl( - std::any_cast(genericEvent.eventType), + static_cast(genericEvent.eventType), genericEvent.eventData); break; case Events::EventGroup::DateTime: if constexpr (Meta::HasType::value) this->handleEventImpl( - std::any_cast(genericEvent.eventType), + static_cast(genericEvent.eventType), genericEvent.eventData); break; case Events::EventGroup::GraphicsEvents: if constexpr (Meta::HasType::value) this->handleEventImpl( - std::any_cast(genericEvent.eventType), + static_cast(genericEvent.eventType), genericEvent.eventData); break; case Events::EventGroup::Buttons: if constexpr (Meta::HasType::value) this->handleEventImpl( - std::any_cast(genericEvent.eventType), + static_cast(genericEvent.eventType), genericEvent.eventData); break; default: From 0a71a2a91d6bc117f23f9cf429f793aa5da08dd2 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Sat, 26 Mar 2022 01:18:53 +0200 Subject: [PATCH 34/54] Removed LOG_DEBUG_ENDL macro --- Firmware/drivers/ble/ble_datetime_service.cpp | 10 ++++----- Firmware/drivers/ble/ble_softdevice.cpp | 22 +++++++++---------- Firmware/drivers/board/watchboard.cpp | 10 ++++----- .../buttons/bt_nordic_hardware_backend.cpp | 14 ++++++------ .../factory_impl/ble_services_stub.cpp | 6 ++--- Firmware/drivers/gpio/gpio_pin.cpp | 4 ++-- .../headers/ih/drivers/ih_button_driver.hpp | 6 ++--- Firmware/drivers/i2c/i2c_test.cpp | 4 ++-- Firmware/filesystem/CMakeLists.txt | 1 + .../filesystem/filesystem_holder.hpp | 7 +++--- .../firmware_tests/coroutine/st7789_draft.hpp | 4 ++-- .../firmware_tests/coroutine/thoughts.hpp | 2 +- Firmware/graphics/gs_lvgl_service.cpp | 6 ++--- .../graphics/platform/gs_platform_layer.cpp | 2 +- Firmware/logger/inc/logger/logger_service.hpp | 6 +---- Firmware/logger/logger_service_impl.cpp | 5 ----- 16 files changed, 51 insertions(+), 58 deletions(-) diff --git a/Firmware/drivers/ble/ble_datetime_service.cpp b/Firmware/drivers/ble/ble_datetime_service.cpp index e0ccdc66..8c64bca4 100644 --- a/Firmware/drivers/ble/ble_datetime_service.cpp +++ b/Firmware/drivers/ble/ble_datetime_service.cpp @@ -54,14 +54,14 @@ void DateTimeServiceNordic::serviceEventHandler( switch (_pEvent->evt_type) { case BLE_CTS_C_EVT_DISCOVERY_COMPLETE: - LOG_DEBUG_ENDL("Current Time Service discovered on server."); + LOG_DEBUG("Current Time Service discovered on server."); errorCode = ble_cts_c_handles_assign( &m_currentTimeService, _pEvent->conn_handle, &_pEvent->params.char_handles); APP_ERROR_CHECK(errorCode); break; case BLE_CTS_C_EVT_DISCOVERY_FAILED: - LOG_DEBUG_ENDL("Current Time Service not found on server. "); + LOG_DEBUG("Current Time Service not found on server. "); // CTS not found in this case we just disconnect. There is no reason to stay // in the connection for this simple app since it all wants is to interact with CT // if (_pEvent->conn_handle != BLE_CONN_HANDLE_INVALID) @@ -73,16 +73,16 @@ void DateTimeServiceNordic::serviceEventHandler( break; case BLE_CTS_C_EVT_DISCONN_COMPLETE: - LOG_DEBUG_ENDL("Disconnect Complete."); + LOG_DEBUG("Disconnect Complete."); break; case BLE_CTS_C_EVT_CURRENT_TIME: - LOG_DEBUG_ENDL("Current Time received."); + LOG_DEBUG("Current Time received."); // current_time_print(_pEvent); break; case BLE_CTS_C_EVT_INVALID_TIME: - LOG_DEBUG_ENDL("Invalid Time received."); + LOG_DEBUG("Invalid Time received."); break; default: diff --git a/Firmware/drivers/ble/ble_softdevice.cpp b/Firmware/drivers/ble/ble_softdevice.cpp index 0b699240..ff361927 100644 --- a/Firmware/drivers/ble/ble_softdevice.cpp +++ b/Firmware/drivers/ble/ble_softdevice.cpp @@ -125,7 +125,7 @@ void BleStackKeeper::gattEventHandler( if (_pEvent->evt_id == NRF_BLE_GATT_EVT_ATT_MTU_UPDATED) { - LOG_DEBUG_ENDL("GATT ATT MTU on connection 0x%x changed to %d."); + LOG_DEBUG("GATT ATT MTU on connection 0x%x changed to %d."); onConnected.emitLater(); // NRF_LOG_INFO("GATT ATT MTU on connection 0x%x changed to %d.", @@ -175,7 +175,7 @@ void BleStackKeeper::bleEventHandler(ble_evt_t const* _pBleEvent) noexcept switch (_pBleEvent->header.evt_id) { case BLE_GAP_EVT_DISCONNECTED: - LOG_DEBUG_ENDL("Disconnected."); + LOG_DEBUG("Disconnected."); m_isConnected = false; m_connectionHandle = BLE_CONN_HANDLE_INVALID; @@ -183,7 +183,7 @@ void BleStackKeeper::bleEventHandler(ble_evt_t const* _pBleEvent) noexcept break; case BLE_GAP_EVT_CONNECTED: - LOG_DEBUG_ENDL("Connected"); + LOG_DEBUG("Connected"); m_isConnected = true; // NRF_LOG_INFO("Connected."); // errCode = bsp_indication_set( BSP_INDICATE_CONNECTED ); @@ -196,7 +196,7 @@ void BleStackKeeper::bleEventHandler(ble_evt_t const* _pBleEvent) noexcept break; case BLE_GAP_EVT_PHY_UPDATE_REQUEST: { - LOG_DEBUG_ENDL("PHY update request."); + LOG_DEBUG("PHY update request."); ble_gap_phys_t const phys = { .tx_phys = BLE_GAP_PHY_AUTO, @@ -210,7 +210,7 @@ void BleStackKeeper::bleEventHandler(ble_evt_t const* _pBleEvent) noexcept case BLE_GATTC_EVT_TIMEOUT: // Disconnect on GATT Client timeout event. - LOG_DEBUG_ENDL("GATT Client Timeout."); + LOG_DEBUG("GATT Client Timeout."); errCode = sd_ble_gap_disconnect( _pBleEvent->evt.gattc_evt.conn_handle, BLE_HCI_REMOTE_USER_TERMINATED_CONNECTION); @@ -270,7 +270,7 @@ void BleStackKeeper::advertisingEventHandler(ble_adv_evt_t _pAdvertisingEvent) n switch (_pAdvertisingEvent) { case BLE_ADV_EVT_FAST: - LOG_DEBUG_ENDL("Fast advertising."); + LOG_DEBUG("Fast advertising."); if (!m_isConnected) onDisconnected.emitLater(); // errorCode = bsp_indication_set(BSP_INDICATE_ADVERTISING); @@ -282,7 +282,7 @@ void BleStackKeeper::advertisingEventHandler(ble_adv_evt_t _pAdvertisingEvent) n break; case BLE_ADV_EVT_SLOW_WHITELIST: - LOG_DEBUG_ENDL("Slow advertising with WhiteList"); + LOG_DEBUG("Slow advertising with WhiteList"); // errorCode = bsp_indication_set( BSP_INDICATE_ADVERTISING_WHITELIST ); // APP_ERROR_CHECK( errorCode ); errorCode = ble_advertising_restart_without_whitelist(&m_advertising); @@ -302,7 +302,7 @@ void BleStackKeeper::advertisingEventHandler(ble_adv_evt_t _pAdvertisingEvent) n pm_whitelist_get(whiteListAddrs.data(), &AddrCount, whiteListIrks.data(), &IrkCount); APP_ERROR_CHECK(errorCode); - LOG_DEBUG_ENDL("pm_whitelist_get returns %d addr in whitelist and %d irk whitelist"); + LOG_DEBUG("pm_whitelist_get returns %d addr in whitelist and %d irk whitelist"); // Apply the whitelist. errorCode = ble_advertising_whitelist_reply( @@ -419,7 +419,7 @@ void BleStackKeeper::peerManagerEventHandler(pm_evt_t const* _pPeerEvent) noexce switch (_pPeerEvent->evt_id) { case PM_EVT_BONDED_PEER_CONNECTED: { - LOG_DEBUG_ENDL("Connected to a previously bonded device."); + LOG_DEBUG("Connected to a previously bonded device."); } break; @@ -497,7 +497,7 @@ void BleStackKeeper::peerManagerEventHandler(pm_evt_t const* _pPeerEvent) noexce if (IsUpdateSucceeded) { - LOG_DEBUG_ENDL("New Bond, add the peer to the whitelist if possible"); + LOG_DEBUG("New Bond, add the peer to the whitelist if possible"); if (m_whiteListPeerCount < BLE_GAP_WHITELIST_ADDR_MAX_COUNT) { @@ -568,7 +568,7 @@ void BleStackKeeper::deleteBonds() noexcept { ret_code_t errCode{}; - LOG_DEBUG_ENDL("Erase bonds!"); + LOG_DEBUG("Erase bonds!"); errCode = pm_peers_delete(); APP_ERROR_CHECK(errCode); diff --git a/Firmware/drivers/board/watchboard.cpp b/Firmware/drivers/board/watchboard.cpp index 88933898..3fc7523b 100644 --- a/Firmware/drivers/board/watchboard.cpp +++ b/Firmware/drivers/board/watchboard.cpp @@ -89,7 +89,7 @@ void Board::initBoard() noexcept /* Configure board. */ bsp_board_init(BSP_INIT_LEDS); - LOG_DEBUG_ENDL("Hello from E73 Mod Board!"); + LOG_DEBUG("Hello from E73 Mod Board!"); ret_code_t errorCode{}; @@ -108,7 +108,7 @@ void Board::initBoardTimer() noexcept app_timer_create(&m_ledDriverTimer, APP_TIMER_MODE_SINGLE_SHOT, TimerExpiredCallback); APP_ERROR_CHECK(errorCode); LOG_DEBUG("LED timer create code is:"); - LOG_DEBUG_ENDL(errorCode); + LOG_DEBUG(errorCode); #endif } @@ -118,10 +118,10 @@ void Board::initBoardSpiFlash() noexcept const std::uint32_t JedecId = co_await m_pFlashDriver->requestJEDEDCId(); LOG_DEBUG("Jedec Id is:"); - LOG_DEBUG_ENDL(fmt::format("{:#04x}", JedecId)); + LOG_DEBUG(fmt::format("{:#04x}", JedecId)); const std::span DeviceId = co_await m_pFlashDriver->requestDeviceId(); - LOG_DEBUG_ENDL(fmt::format("{:02X}", fmt::join(DeviceId, ""))); + LOG_DEBUG(fmt::format("{:02X}", fmt::join(DeviceId, ""))); m_filesystem = std::make_unique(); CoroUtils::syncWait(m_filesystem->initializeFs()); @@ -140,7 +140,7 @@ void Board::ledToggle() noexcept while (true) { co_await 300ms; - // LOG_DEBUG_ENDL("LED TIMER EXPIRED"); + // LOG_DEBUG("LED TIMER EXPIRED"); bsp_board_led_invert(0); co_await 100ms; bsp_board_led_invert(0); diff --git a/Firmware/drivers/buttons/bt_nordic_hardware_backend.cpp b/Firmware/drivers/buttons/bt_nordic_hardware_backend.cpp index 20a961fa..a78f1c0d 100644 --- a/Firmware/drivers/buttons/bt_nordic_hardware_backend.cpp +++ b/Firmware/drivers/buttons/bt_nordic_hardware_backend.cpp @@ -32,7 +32,7 @@ void NordicTimerBackend::initialize() auto timerExpiredCallback = cbc::obtain_connector([this](void* _pContext) { m_isTimerEllapsed = true; onTimerExpired.emit(); - LOG_DEBUG_ENDL("m_isTimerEllapsed = true;"); + LOG_DEBUG("m_isTimerEllapsed = true;"); }); errorCode = @@ -113,12 +113,12 @@ void NordicButtonsBackend::handleHardwareButtonEvent( auto toLocalEvent = [](std::uint8_t _buttonEvent) { if (_buttonEvent == APP_BUTTON_PUSH) { - LOG_DEBUG_ENDL("ButtonBackendEvent::kPressed"); + LOG_DEBUG("ButtonBackendEvent::kPressed"); return ButtonBackendEvent::kPressed; } else if (_buttonEvent == APP_BUTTON_RELEASE) { - LOG_DEBUG_ENDL("ButtonBackendEvent::kReleased"); + LOG_DEBUG("ButtonBackendEvent::kReleased"); return ButtonBackendEvent::kReleased; } else @@ -131,19 +131,19 @@ void NordicButtonsBackend::handleHardwareButtonEvent( switch (_pinNumber) { case BUTTON_1: - LOG_DEBUG_ENDL("BUTTON_1"); + LOG_DEBUG("BUTTON_1"); onButtonEvent.emit(Buttons::ButtonId::kLeftButtonTop, toLocalEvent(_buttonEvent)); break; case BUTTON_2: - LOG_DEBUG_ENDL("BUTTON_2"); + LOG_DEBUG("BUTTON_2"); onButtonEvent.emit(Buttons::ButtonId::kLeftButtonMedium, toLocalEvent(_buttonEvent)); break; case BUTTON_3: - LOG_DEBUG_ENDL("BUTTON_3"); + LOG_DEBUG("BUTTON_3"); onButtonEvent.emit(Buttons::ButtonId::kLeftButtonBottom, toLocalEvent(_buttonEvent)); break; case BUTTON_4: - LOG_DEBUG_ENDL("BUTTON_4"); + LOG_DEBUG("BUTTON_4"); onButtonEvent.emit(Buttons::ButtonId::kRightButtonTop, toLocalEvent(_buttonEvent)); break; default: diff --git a/Firmware/drivers/factory_impl/ble_services_stub.cpp b/Firmware/drivers/factory_impl/ble_services_stub.cpp index 5e92f81f..d6d805b9 100644 --- a/Firmware/drivers/factory_impl/ble_services_stub.cpp +++ b/Firmware/drivers/factory_impl/ble_services_stub.cpp @@ -8,13 +8,13 @@ namespace Ble::BatteryService StubBatteryService::StubBatteryService() noexcept { - LOG_DEBUG_ENDL("Initialized DesktopStubBatteryService"); + LOG_DEBUG("Initialized DesktopStubBatteryService"); } void StubBatteryService::onBatteryLevelChanged(std::uint8_t _newBatteryLevel) noexcept { LOG_DEBUG("New battery level is:"); - LOG_DEBUG_ENDL(_newBatteryLevel); + LOG_DEBUG(_newBatteryLevel); } } // namespace Ble::BatteryService @@ -24,7 +24,7 @@ namespace Ble::DateTimeService StubDateTimeService::StubDateTimeService() noexcept { - LOG_DEBUG_ENDL("Initialized StubDateTimeService"); + LOG_DEBUG("Initialized StubDateTimeService"); } void StubDateTimeService::handleDiscoveryEvent(const std::any& _pBleDbDiscoveryEvent) noexcept diff --git a/Firmware/drivers/gpio/gpio_pin.cpp b/Firmware/drivers/gpio/gpio_pin.cpp index 0a10c1bd..b54a5bc2 100644 --- a/Firmware/drivers/gpio/gpio_pin.cpp +++ b/Firmware/drivers/gpio/gpio_pin.cpp @@ -37,13 +37,13 @@ GpioPin::GpioPin() noexcept = default; template void GpioPin::set() noexcept { - LOG_DEBUG_ENDL("Gpio Set called"); + LOG_DEBUG("Gpio Set called"); } template void GpioPin::reset() noexcept { - LOG_DEBUG_ENDL("Gpio Reset called"); + LOG_DEBUG("Gpio Reset called"); } #endif diff --git a/Firmware/drivers/headers/ih/drivers/ih_button_driver.hpp b/Firmware/drivers/headers/ih/drivers/ih_button_driver.hpp index 2c407ba3..79749f5e 100644 --- a/Firmware/drivers/headers/ih/drivers/ih_button_driver.hpp +++ b/Firmware/drivers/headers/ih/drivers/ih_button_driver.hpp @@ -93,12 +93,12 @@ template class ButtonsDriverTemplate switch (buttonDescriptor.pressCount) { case 1: - LOG_DEBUG_ENDL( + LOG_DEBUG( "onButtonEvent.emit({ m_lastPressedId, ButtonState::kButtonClick });"); onButtonEvent.emit({buttonDescriptor.id, ButtonState::kButtonClick}); break; case 2: - LOG_DEBUG_ENDL( + LOG_DEBUG( "onButtonEvent.emit({ _buttonId, ButtonState::kButtonDblClick });"); onButtonEvent.emit({buttonDescriptor.id, ButtonState::kButtonDblClick}); break; @@ -139,7 +139,7 @@ template class ButtonsDriverTemplate { m_buttons[arrayIndex].pressCount = 0; m_buttons[arrayIndex].longPressTimeoutExpired = false; - LOG_DEBUG_ENDL( + LOG_DEBUG( "onButtonEvent.emit({ m_lastPressedId, ButtonState::kButtonLongPress });"); onButtonEvent.emit({m_buttons[arrayIndex].id, ButtonState::kButtonLongPress}); } diff --git a/Firmware/drivers/i2c/i2c_test.cpp b/Firmware/drivers/i2c/i2c_test.cpp index c9522fd2..79d197ad 100644 --- a/Firmware/drivers/i2c/i2c_test.cpp +++ b/Firmware/drivers/i2c/i2c_test.cpp @@ -40,14 +40,14 @@ void scanI2CSensors() errorCode = nrf_drv_twi_rx(&m_twi, Mpu9250Addr, &SampleData, sizeof(SampleData)); if (errorCode == NRF_SUCCESS) - LOG_DEBUG_ENDL("MPU9250 detected on address 0x69"); + LOG_DEBUG("MPU9250 detected on address 0x69"); constexpr std::uint8_t Max30102Addr = 0x57; errorCode = nrf_drv_twi_rx(&m_twi, Max30102Addr, &SampleData, sizeof(SampleData)); if (errorCode == NRF_SUCCESS) - LOG_DEBUG_ENDL("Max30102 detected on address 0x57"); + LOG_DEBUG("Max30102 detected on address 0x57"); #endif } diff --git a/Firmware/filesystem/CMakeLists.txt b/Firmware/filesystem/CMakeLists.txt index 71d704b3..0a5da533 100644 --- a/Firmware/filesystem/CMakeLists.txt +++ b/Firmware/filesystem/CMakeLists.txt @@ -29,4 +29,5 @@ target_link_libraries( watch_filesystem INTERFACE drivers_ih windbond_spi_flash_driver + logger_service ) \ No newline at end of file diff --git a/Firmware/filesystem/filesystem/filesystem_holder.hpp b/Firmware/filesystem/filesystem/filesystem_holder.hpp index a134faa7..d4e4c53e 100644 --- a/Firmware/filesystem/filesystem/filesystem_holder.hpp +++ b/Firmware/filesystem/filesystem/filesystem_holder.hpp @@ -11,7 +11,7 @@ #include #include -//#include +#include namespace Platform::Fs { @@ -45,6 +45,8 @@ template class Holder CoroUtils::VoidTask initializeFs() { + LOG_DEBUG("Called to initializeFs"); + auto error = co_await lfs_mount(&m_fsInstance, &m_fsConfig); if (error) { @@ -175,8 +177,7 @@ template class File return; CoroUtils::syncWait(lfs_file_close(m_pFsHolder, m_pFileHandle.get())); - // TODO move somewhere to global observer - // spdlog::warn("~File::File()"); + LOG_DEBUG("~File::File()"); } CoroUtils::VoidTask write(std::span dataHolder) noexcept diff --git a/Firmware/firmware_tests/coroutine/st7789_draft.hpp b/Firmware/firmware_tests/coroutine/st7789_draft.hpp index 93cbf020..7a23903c 100644 --- a/Firmware/firmware_tests/coroutine/st7789_draft.hpp +++ b/Firmware/firmware_tests/coroutine/st7789_draft.hpp @@ -264,7 +264,7 @@ // std::tuple_size::value> {} // ); // -// LOG_DEBUG_ENDL("Display initialized"); +// LOG_DEBUG("Display initialized"); // constexpr bool pushToMainQueue = true; // m_displayInitialized.set(pushToMainQueue); // } @@ -313,7 +313,7 @@ // , std::uint16_t _height // )noexcept // { -// LOG_DEBUG_ENDL("void initColumnRow"); +// LOG_DEBUG("void initColumnRow"); // } // // void setAddrWindow( diff --git a/Firmware/firmware_tests/coroutine/thoughts.hpp b/Firmware/firmware_tests/coroutine/thoughts.hpp index f0a6fd90..5b8d70a4 100644 --- a/Firmware/firmware_tests/coroutine/thoughts.hpp +++ b/Firmware/firmware_tests/coroutine/thoughts.hpp @@ -249,7 +249,7 @@ class ST7789CppCoro : public DisplayDriver::BaseSpiDisplayCoroutine : DisplayDriver::BaseSpiDisplayCoroutine(std::move(_busPtr), _width, _height) { initDisplay(); - LOG_DEBUG_ENDL("Display initialized"); + LOG_DEBUG("Display initialized"); } ~ST7789CppCoro() noexcept override diff --git a/Firmware/graphics/gs_lvgl_service.cpp b/Firmware/graphics/gs_lvgl_service.cpp index 103433c4..2046e2da 100644 --- a/Firmware/graphics/gs_lvgl_service.cpp +++ b/Firmware/graphics/gs_lvgl_service.cpp @@ -72,7 +72,7 @@ class LvglGraphicsService::GSLvglServiceImpl void initLvglLogger() noexcept { auto lvglLoggerCallback = cbc::obtain_connector([](const char* loggerMessage) { - LOG_DEBUG_ENDL(loggerMessage); + LOG_DEBUG(loggerMessage); }); #if LV_USE_LOG == 1 lv_log_register_print_cb(lvglLoggerCallback); @@ -93,9 +93,9 @@ class LvglGraphicsService::GSLvglServiceImpl auto monitorCallback = cbc::obtain_connector([](lv_disp_drv_t* disp_drv, uint32_t time, uint32_t px) { LOG_DEBUG("Refresh time:"); - LOG_DEBUG_ENDL(time); + LOG_DEBUG(time); LOG_DEBUG("Refreshed pixels:"); - LOG_DEBUG_ENDL(px); + LOG_DEBUG(px); }); m_glDisplayDriver.monitor_cb = monitorCallback; diff --git a/Firmware/graphics/platform/gs_platform_layer.cpp b/Firmware/graphics/platform/gs_platform_layer.cpp index 4aa6d314..5bf72c3e 100644 --- a/Firmware/graphics/platform/gs_platform_layer.cpp +++ b/Firmware/graphics/platform/gs_platform_layer.cpp @@ -125,7 +125,7 @@ void PlatformBackend::memoryMonitor(lv_timer_t* _param) noexcept lv_mem_monitor_t moninor{}; lv_mem_monitor(&moninor); - LOG_DEBUG_ENDL(fmt::format( + LOG_DEBUG(fmt::format( "Used: {} , {}% fragmentation: {}, biggest free: {}", static_cast(moninor.total_size - moninor.free_size), static_cast(moninor.used_pct), diff --git a/Firmware/logger/inc/logger/logger_service.hpp b/Firmware/logger/inc/logger/logger_service.hpp index 695e50bd..fd75c387 100644 --- a/Firmware/logger/inc/logger/logger_service.hpp +++ b/Firmware/logger/inc/logger/logger_service.hpp @@ -10,11 +10,9 @@ #define ENABLE_DEBUG_LOGGING #ifdef ENABLE_DEBUG_LOGGING -#define LOG_DEBUG(ARGS) (Logger::Instance().logDebug(ARGS)) -#define LOG_DEBUG_ENDL(ARGS) (Logger::Instance().logDebugEndl(ARGS)) +#define LOG_DEBUG(ARGS) (Logger::Instance().logDebugEndl(ARGS)) #else #define LOG_DEBUG(ARGS) -#define LOG_DEBUG_ENDL(ARGS) #endif class Logger @@ -25,8 +23,6 @@ class Logger void logDebugEndl(std::string_view _toLog) noexcept; - void logDebug(std::string_view _toLog) noexcept; - template static constexpr bool IsStringType() noexcept { using TClearType = typename std::decay::type; diff --git a/Firmware/logger/logger_service_impl.cpp b/Firmware/logger/logger_service_impl.cpp index 5958a325..e971e517 100644 --- a/Firmware/logger/logger_service_impl.cpp +++ b/Firmware/logger/logger_service_impl.cpp @@ -165,9 +165,4 @@ void Logger::logDebugEndl(std::string_view _toLog) noexcept { m_pLoggerImpl->logString(_toLog); m_pLoggerImpl->logString(CaretReset); -} - -void Logger::logDebug(std::string_view _toLog) noexcept -{ - m_pLoggerImpl->logString(_toLog); } \ No newline at end of file From 796d397f97743d7ce20154eeaf0ff3ca4771488b Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Sat, 26 Mar 2022 01:39:10 +0200 Subject: [PATCH 35/54] Extended logger with the severity modes --- Firmware/ap_application.cpp | 4 ++ Firmware/drivers/board/watchboard.cpp | 10 +-- Firmware/logger/inc/logger/logger_service.hpp | 65 ++++++------------- Firmware/logger/logger_service_impl.cpp | 23 ++++++- 4 files changed, 49 insertions(+), 53 deletions(-) diff --git a/Firmware/ap_application.cpp b/Firmware/ap_application.cpp index 0cfcb351..9073e3e7 100644 --- a/Firmware/ap_application.cpp +++ b/Firmware/ap_application.cpp @@ -44,8 +44,12 @@ Graphics::Events::TButtonsEvents toButtonEvent(Buttons::ButtonState _buttonToCon Application::Application() noexcept { + LOG_INFO("Application start"); initBoard(); + LOG_INFO("Complete board init"); initPeripheral(); + LOG_INFO("Complete peripheral init"); + initServices(); initGraphicsStack(); initBleStack(); diff --git a/Firmware/drivers/board/watchboard.cpp b/Firmware/drivers/board/watchboard.cpp index 3fc7523b..b673d6d0 100644 --- a/Firmware/drivers/board/watchboard.cpp +++ b/Firmware/drivers/board/watchboard.cpp @@ -107,8 +107,7 @@ void Board::initBoardTimer() noexcept errorCode = app_timer_create(&m_ledDriverTimer, APP_TIMER_MODE_SINGLE_SHOT, TimerExpiredCallback); APP_ERROR_CHECK(errorCode); - LOG_DEBUG("LED timer create code is:"); - LOG_DEBUG(errorCode); + LOG_DEBUG(fmt::format("LED timer create code is {}", errorCode)); #endif } @@ -117,14 +116,15 @@ void Board::initBoardSpiFlash() noexcept m_pFlashDriver = std::make_unique(); const std::uint32_t JedecId = co_await m_pFlashDriver->requestJEDEDCId(); - LOG_DEBUG("Jedec Id is:"); - LOG_DEBUG(fmt::format("{:#04x}", JedecId)); + LOG_DEBUG(fmt::format("Jedec Id is {:#04x}", JedecId)); const std::span DeviceId = co_await m_pFlashDriver->requestDeviceId(); - LOG_DEBUG(fmt::format("{:02X}", fmt::join(DeviceId, ""))); + LOG_DEBUG(fmt::format("Device id is {:02X}", fmt::join(DeviceId, ""))); + LOG_DEBUG("Started filesystem initialization"); m_filesystem = std::make_unique(); CoroUtils::syncWait(m_filesystem->initializeFs()); + LOG_DEBUG("Filesystem is ready"); } Board::Board() noexcept diff --git a/Firmware/logger/inc/logger/logger_service.hpp b/Firmware/logger/inc/logger/logger_service.hpp index fd75c387..ec4c2ba5 100644 --- a/Firmware/logger/inc/logger/logger_service.hpp +++ b/Firmware/logger/inc/logger/logger_service.hpp @@ -8,11 +8,25 @@ #include #include +enum class LogSeverity +{ + Debug, + Info, + Warn, + Error +}; + #define ENABLE_DEBUG_LOGGING #ifdef ENABLE_DEBUG_LOGGING -#define LOG_DEBUG(ARGS) (Logger::Instance().logDebugEndl(ARGS)) +#define LOG_DEBUG(ARGS) (Logger::Instance().logDebug(LogSeverity::Debug, ARGS)) +#define LOG_INFO(ARGS) (Logger::Instance().logDebug(LogSeverity::Info, ARGS)) +#define LOG_WARN(ARGS) (Logger::Instance().logDebug(LogSeverity::Warn, ARGS)) +#define LOG_ERROR(ARGS) (Logger::Instance().logDebug(LogSeverity::Error, ARGS)) #else #define LOG_DEBUG(ARGS) +#define LOG_INFO(ARGS) +#define LOG_WARN(ARGS) +#define LOG_ERROR(ARGS) #endif class Logger @@ -21,8 +35,6 @@ class Logger public: static Logger& Instance() noexcept; - void logDebugEndl(std::string_view _toLog) noexcept; - template static constexpr bool IsStringType() noexcept { using TClearType = typename std::decay::type; @@ -43,7 +55,7 @@ class Logger return isCharType; } - template void logDebugEndl(const TToLog& _toLog) noexcept + template void logDebug(LogSeverity severity, const TToLog& _toLog) noexcept { constexpr bool isString = IsStringType(); @@ -53,56 +65,19 @@ class Logger if (auto [p, ec] = std::to_chars(str.data(), str.data() + str.size(), _toLog); ec == std::errc()) { - logDebugEndl(std::string_view(str.data(), p - str.data())); - } - } - else - { - if constexpr (IsCharType()) - logDebugEndl(static_cast(_toLog)); - else - logDebugEndl(static_cast(_toLog)); - } - } - - template void logDebug(const TToLog& _toLog) noexcept - { - constexpr bool isString = IsStringType(); - if constexpr (!isString) - { - std::array str{}; - if (auto [p, ec] = std::to_chars(str.data(), str.data() + str.size(), _toLog); - ec == std::errc()) - { - logDebug(std::string_view(str.data(), p - str.data())); + logDebug(severity, std::string_view(str.data(), p - str.data())); } } else { if constexpr (IsCharType()) - logDebug(static_cast(_toLog)); + logDebug(severity, static_cast(_toLog)); else - logDebug(static_cast(_toLog)); + logDebug(severity, static_cast(_toLog)); } } - template - void logDebug(const std::array& _arrayToLog) noexcept - { - for (auto arrayItem : _arrayToLog) - { - logDebug('['); - logDebug(arrayItem); - logDebug(']'); - } - } - - template - void logDebugEndl(const std::array& _arrayToLog) noexcept - { - logDebug(_arrayToLog); - logDebug('\n'); - } + void logDebug(LogSeverity severity, std::string_view _toLog) noexcept; private: Logger() noexcept; diff --git a/Firmware/logger/logger_service_impl.cpp b/Firmware/logger/logger_service_impl.cpp index e971e517..971f212a 100644 --- a/Firmware/logger/logger_service_impl.cpp +++ b/Firmware/logger/logger_service_impl.cpp @@ -21,8 +21,8 @@ #include "SEGGER_RTT.h" #elif defined(LoggerDesktop) #include -#include #include +#include #if defined USE_MSVC_DEBUG_OUT #include #endif @@ -32,7 +32,23 @@ namespace { std::string_view CaretReset = "\r\n"; + +constexpr const char* const severityToString(LogSeverity severity) +{ + switch (severity) + { + + case LogSeverity::Debug: + return "[DEBUG]"; + case LogSeverity::Info: + return "[INFO]"; + case LogSeverity::Warn: + return "[WARN]"; + case LogSeverity::Error: + return "[ERROR]"; + } } +} // namespace #if defined(LoggerUart) @@ -143,7 +159,7 @@ class Logger::LoggerImpl public: void logString(std::string_view _toLog) const noexcept { - fmt::print(fg(fmt::color::steel_blue),"{}",_toLog.data()); + fmt::print(fg(fmt::color::steel_blue), "{}", _toLog.data()); #if defined USE_MSVC_DEBUG_OUT OutputDebugString(_toLog.data()); #endif @@ -161,8 +177,9 @@ Logger& Logger::Instance() noexcept return intance; } -void Logger::logDebugEndl(std::string_view _toLog) noexcept +void Logger::logDebug(LogSeverity severity, std::string_view _toLog) noexcept { + m_pLoggerImpl->logString(severityToString(severity)); m_pLoggerImpl->logString(_toLog); m_pLoggerImpl->logString(CaretReset); } \ No newline at end of file From dda71d167f3a8983db2d48d865808db28b69bdef Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Sun, 27 Mar 2022 00:00:21 +0200 Subject: [PATCH 36/54] Fixed write-read data from the SPI-flash --- Firmware/3rdparty/CMakeLists.txt | 4 +- Firmware/3rdparty/littlefs_lib/CMakeLists.txt | 8 + .../3rdparty/littlefs_lib/lfs_util_segger.h | 266 ++++++++++++++++++ Firmware/drivers/board/watchboard.cpp | 13 +- .../inc/windbondflash/winbond_commandset.hpp | 56 ++-- .../windbondflash/winbond_flash_templated.hpp | 174 +++++++----- Firmware/filesystem/CMakeLists.txt | 14 + .../adaptor_block_device.hpp | 35 +-- .../filesystem/filesystem_holder.hpp | 3 + Firmware/graphics/gs_lvgl_service.cpp | 11 +- .../graphics/platform/gs_platform_layer.cpp | 2 - Firmware/logger/CMakeLists.txt | 8 +- Firmware/logger/inc/logger/logger_service.hpp | 36 +++ .../utils/coroutine/ExecutionQueueCoro.hpp | 2 + Firmware/utils/inc/utils/coroutine/Task.hpp | 49 +++- 15 files changed, 540 insertions(+), 141 deletions(-) create mode 100644 Firmware/3rdparty/littlefs_lib/lfs_util_segger.h diff --git a/Firmware/3rdparty/CMakeLists.txt b/Firmware/3rdparty/CMakeLists.txt index 7ea5e51a..a14455b4 100644 --- a/Firmware/3rdparty/CMakeLists.txt +++ b/Firmware/3rdparty/CMakeLists.txt @@ -5,7 +5,7 @@ if( ${TARGET_PLATFORM} STREQUAL "FIRMWARE_SIMULATOR" ) set(CMAKE_CXX_STANDARD 20) #add_subdirectory( cppcoro_lib ) elseif( ${TARGET_PLATFORM} STREQUAL "ARM_CORTEX" ) - set(CMAKE_CXX_STANDARD 17) + set(CMAKE_CXX_STANDARD 20) endif() set(CMAKE_CXX_STANDARD_REQUIRED ON) @@ -21,4 +21,4 @@ target_compile_definitions(fmt FMT_USE_DOUBLE=0 FMT_USE_LONG_DOUBLE=0 FMT_REDUCE_INT_INSTANTIATIONS=0 -) \ No newline at end of file +) diff --git a/Firmware/3rdparty/littlefs_lib/CMakeLists.txt b/Firmware/3rdparty/littlefs_lib/CMakeLists.txt index 1f30b505..bcb059d2 100644 --- a/Firmware/3rdparty/littlefs_lib/CMakeLists.txt +++ b/Firmware/3rdparty/littlefs_lib/CMakeLists.txt @@ -31,3 +31,11 @@ target_compile_options( PUBLIC $<$:-Os> ) + +target_include_directories(littlefs PUBLIC ${CMAKE_CURRENT_LIST_DIR}) + +if( ${TARGET_PLATFORM} STREQUAL "ARM_CORTEX" ) + target_include_directories(littlefs PRIVATE ${CMAKE_CURRENT_LIST_DIR} ) + target_precompile_headers(littlefs PRIVATE ${CMAKE_CURRENT_LIST_DIR}/lfs_util_segger.h) + target_link_libraries(littlefs PRIVATE NordicSDK::Common) +endif() diff --git a/Firmware/3rdparty/littlefs_lib/lfs_util_segger.h b/Firmware/3rdparty/littlefs_lib/lfs_util_segger.h new file mode 100644 index 00000000..40c89bf9 --- /dev/null +++ b/Firmware/3rdparty/littlefs_lib/lfs_util_segger.h @@ -0,0 +1,266 @@ +/* + * lfs utility functions + * + * Copyright (c) 2017, Arm Limited. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef LFS_UTIL_H +#define LFS_UTIL_H + +// Users can override lfs_util.h with their own configuration by defining +// LFS_CONFIG as a header file to include (-DLFS_CONFIG=lfs_config.h). +// +// If LFS_CONFIG is used, none of the default utils will be emitted and must be +// provided by the config file. To start, I would suggest copying lfs_util.h +// and modifying as needed. +#ifdef LFS_CONFIG +#define LFS_STRINGIZE(x) LFS_STRINGIZE2(x) +#define LFS_STRINGIZE2(x) #x +#include LFS_STRINGIZE(LFS_CONFIG) +#else + +// System includes +#include "SEGGER_RTT.h" +#include +#include +#include +#include +#include +#ifndef LFS_NO_MALLOC +#include +#endif +#ifndef LFS_NO_ASSERT +#include +#endif +#if !defined(LFS_NO_DEBUG) || !defined(LFS_NO_WARN) || !defined(LFS_NO_ERROR) || \ + defined(LFS_YES_TRACE) +#include +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + +// Macros, may be replaced by system specific wrappers. Arguments to these +// macros must not have side-effects as the macros can be removed for a smaller +// code footprint + +// Logging functions +#ifndef LFS_TRACE +#ifdef LFS_YES_TRACE +#define LFS_TRACE(fmt, ...) \ + SEGGER_RTT_printf(0, "%s:%d:trace: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__, ""); \ + SEGGER_RTT_printf(0, "\r\n") +#else +#define LFS_TRACE(...) +#endif +#endif + +#ifndef LFS_DEBUG +#ifndef LFS_NO_DEBUG +#define LFS_DEBUG(fmt, ...) \ + SEGGER_RTT_printf(0, "%s:%d:debug: " fmt "%s\n", __VA_ARGS__, ""); \ + SEGGER_RTT_printf(0, "\r\n") +#else +#define LFS_DEBUG(...) +#endif +#endif + +#ifndef LFS_WARN +#ifndef LFS_NO_WARN +#define LFS_WARN(fmt, ...) \ + SEGGER_RTT_printf(0, "%s:%d:warn: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__, ""); \ + SEGGER_RTT_printf(0, "\r\n") +#else +#define LFS_WARN(...) +#endif +#endif + +#ifndef LFS_ERROR +#ifndef LFS_NO_ERROR +#define LFS_ERROR(fmt, ...) \ + SEGGER_RTT_printf(0, "%s:%d:error: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__, ""); \ + SEGGER_RTT_printf(0, "\r\n"); +#else +#define LFS_ERROR(...) +#endif +#endif + +// Runtime assertions +#ifndef LFS_ASSERT +#ifndef LFS_NO_ASSERT +#define LFS_ASSERT(test) assert(test) +#else +#define LFS_ASSERT(test) +#endif +#endif + + // Builtin functions, these may be replaced by more efficient + // toolchain-specific implementations. LFS_NO_INTRINSICS falls back to a more + // expensive basic C implementation for debugging purposes + + // Min/max functions for unsigned 32-bit numbers + static inline uint32_t lfs_max(uint32_t a, uint32_t b) + { + return (a > b) ? a : b; + } + + static inline uint32_t lfs_min(uint32_t a, uint32_t b) + { + return (a < b) ? a : b; + } + + // Align to nearest multiple of a size + static inline uint32_t lfs_aligndown(uint32_t a, uint32_t alignment) + { + return a - (a % alignment); + } + + static inline uint32_t lfs_alignup(uint32_t a, uint32_t alignment) + { + return lfs_aligndown(a + alignment - 1, alignment); + } + + // Find the smallest power of 2 greater than or equal to a + static inline uint32_t lfs_npw2(uint32_t a) + { +#if !defined(LFS_NO_INTRINSICS) && (defined(__GNUC__) || defined(__CC_ARM)) + return 32 - __builtin_clz(a - 1); +#else + uint32_t r = 0; + uint32_t s; + a -= 1; + s = (a > 0xffff) << 4; + a >>= s; + r |= s; + s = (a > 0xff) << 3; + a >>= s; + r |= s; + s = (a > 0xf) << 2; + a >>= s; + r |= s; + s = (a > 0x3) << 1; + a >>= s; + r |= s; + return (r | (a >> 1)) + 1; +#endif + } + + // Count the number of trailing binary zeros in a + // lfs_ctz(0) may be undefined + static inline uint32_t lfs_ctz(uint32_t a) + { +#if !defined(LFS_NO_INTRINSICS) && defined(__GNUC__) + return __builtin_ctz(a); +#else + return lfs_npw2((a & -a) + 1) - 1; +#endif + } + + // Count the number of binary ones in a + static inline uint32_t lfs_popc(uint32_t a) + { +#if !defined(LFS_NO_INTRINSICS) && (defined(__GNUC__) || defined(__CC_ARM)) + return __builtin_popcount(a); +#else + a = a - ((a >> 1) & 0x55555555); + a = (a & 0x33333333) + ((a >> 2) & 0x33333333); + return (((a + (a >> 4)) & 0xf0f0f0f) * 0x1010101) >> 24; +#endif + } + + // Find the sequence comparison of a and b, this is the distance + // between a and b ignoring overflow + static inline int lfs_scmp(uint32_t a, uint32_t b) + { + return (int)(unsigned)(a - b); + } + + // Convert between 32-bit little-endian and native order + static inline uint32_t lfs_fromle32(uint32_t a) + { +#if !defined(LFS_NO_INTRINSICS) && \ + ((defined(BYTE_ORDER) && defined(ORDER_LITTLE_ENDIAN) && BYTE_ORDER == ORDER_LITTLE_ENDIAN) || \ + (defined(__BYTE_ORDER) && defined(__ORDER_LITTLE_ENDIAN) && \ + __BYTE_ORDER == __ORDER_LITTLE_ENDIAN) || \ + (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \ + __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) + return a; +#elif !defined(LFS_NO_INTRINSICS) && \ + ((defined(BYTE_ORDER) && defined(ORDER_BIG_ENDIAN) && BYTE_ORDER == ORDER_BIG_ENDIAN) || \ + (defined(__BYTE_ORDER) && defined(__ORDER_BIG_ENDIAN) && \ + __BYTE_ORDER == __ORDER_BIG_ENDIAN) || \ + (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \ + __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) + return __builtin_bswap32(a); +#else + return (((uint8_t*)&a)[0] << 0) | (((uint8_t*)&a)[1] << 8) | (((uint8_t*)&a)[2] << 16) | + (((uint8_t*)&a)[3] << 24); +#endif + } + + static inline uint32_t lfs_tole32(uint32_t a) + { + return lfs_fromle32(a); + } + + // Convert between 32-bit big-endian and native order + static inline uint32_t lfs_frombe32(uint32_t a) + { +#if !defined(LFS_NO_INTRINSICS) && \ + ((defined(BYTE_ORDER) && defined(ORDER_LITTLE_ENDIAN) && BYTE_ORDER == ORDER_LITTLE_ENDIAN) || \ + (defined(__BYTE_ORDER) && defined(__ORDER_LITTLE_ENDIAN) && \ + __BYTE_ORDER == __ORDER_LITTLE_ENDIAN) || \ + (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && \ + __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) + return __builtin_bswap32(a); +#elif !defined(LFS_NO_INTRINSICS) && \ + ((defined(BYTE_ORDER) && defined(ORDER_BIG_ENDIAN) && BYTE_ORDER == ORDER_BIG_ENDIAN) || \ + (defined(__BYTE_ORDER) && defined(__ORDER_BIG_ENDIAN) && \ + __BYTE_ORDER == __ORDER_BIG_ENDIAN) || \ + (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && \ + __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) + return a; +#else + return (((uint8_t*)&a)[0] << 24) | (((uint8_t*)&a)[1] << 16) | (((uint8_t*)&a)[2] << 8) | + (((uint8_t*)&a)[3] << 0); +#endif + } + + static inline uint32_t lfs_tobe32(uint32_t a) + { + return lfs_frombe32(a); + } + + // Calculate CRC-32 with polynomial = 0x04c11db7 + uint32_t lfs_crc(uint32_t crc, const void* buffer, size_t size); + + // Allocate memory, only used if buffers are not provided to littlefs + // Note, memory must be 64-bit aligned + static inline void* lfs_malloc(size_t size) + { +#ifndef LFS_NO_MALLOC + return malloc(size); +#else + (void)size; + return NULL; +#endif + } + + // Deallocate memory, only used if buffers are not provided to littlefs + static inline void lfs_free(void* p) + { +#ifndef LFS_NO_MALLOC + free(p); +#else + (void)p; +#endif + } + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +#endif diff --git a/Firmware/drivers/board/watchboard.cpp b/Firmware/drivers/board/watchboard.cpp index b673d6d0..afeb9bc6 100644 --- a/Firmware/drivers/board/watchboard.cpp +++ b/Firmware/drivers/board/watchboard.cpp @@ -94,6 +94,7 @@ void Board::initBoard() noexcept ret_code_t errorCode{}; errorCode = app_timer_init(); + LOG_DEBUG(fmt::format("app_timer_init code() {}", errorCode)); APP_ERROR_CHECK(errorCode); #endif m_buttonsDriver.initializeHalDependent(); @@ -113,6 +114,7 @@ void Board::initBoardTimer() noexcept void Board::initBoardSpiFlash() noexcept { + LOG_DEBUG("creation of flash driver started"); m_pFlashDriver = std::make_unique(); const std::uint32_t JedecId = co_await m_pFlashDriver->requestJEDEDCId(); @@ -121,8 +123,17 @@ void Board::initBoardSpiFlash() noexcept const std::span DeviceId = co_await m_pFlashDriver->requestDeviceId(); LOG_DEBUG(fmt::format("Device id is {:02X}", fmt::join(DeviceId, ""))); - LOG_DEBUG("Started filesystem initialization"); + LOG_DEBUG("m_pFlashDriver->requestBlockWrite"); + auto blockTest = std::array{1, 2, 3, 4, 5, 6, 7, 8}; + co_await m_pFlashDriver->pageWrite(0x00, blockTest); + LOG_DEBUG("m_pFlashDriver->compltetedBlockWrite"); + + LOG_DEBUG("m_pFlashDriver->requestReadBlock"); + auto readResult = co_await m_pFlashDriver->requestReadBlock(0x00, blockTest.size()); + LOG_DEBUG(fmt::format("Got read block {}", readResult)); + m_filesystem = std::make_unique(); + LOG_DEBUG("Started filesystem initialization"); CoroUtils::syncWait(m_filesystem->initializeFs()); LOG_DEBUG("Filesystem is ready"); } diff --git a/Firmware/drivers/winbondflash/inc/windbondflash/winbond_commandset.hpp b/Firmware/drivers/winbondflash/inc/windbondflash/winbond_commandset.hpp index a27b2118..d8da2aa5 100644 --- a/Firmware/drivers/winbondflash/inc/windbondflash/winbond_commandset.hpp +++ b/Firmware/drivers/winbondflash/inc/windbondflash/winbond_commandset.hpp @@ -2,42 +2,46 @@ #include - +namespace WindbondCommandSet::Masks +{ +inline constexpr std::uint8_t EraseWriteInProgress = 1 << 0; +} namespace WindbondCommandSet { - constexpr std::uint8_t WriteEnable = 0x06; - constexpr std::uint8_t WriteDisable = 0x04; +inline constexpr std::uint8_t WriteEnable = 0x06; +inline constexpr std::uint8_t WriteDisable = 0x04; - constexpr std::uint8_t ReadStatusRegister1 = 0x05; - constexpr std::uint8_t ReadStatusRegister2 = 0x35; +inline constexpr std::uint8_t ReadStatusRegister1 = 0x05; +inline constexpr std::uint8_t ReadStatusRegister2 = 0x35; +inline constexpr std::uint8_t ReadStatusRegister3 = 0x15; - constexpr std::uint8_t WriteStatusRegister = 0x01; +inline constexpr std::uint8_t WriteStatusRegister = 0x01; - constexpr std::uint8_t ReadData = 0x03; - constexpr std::uint8_t FastRead = 0x0b; - constexpr std::uint8_t PageProgram = 0x02; +inline constexpr std::uint8_t ReadData = 0x03; +inline constexpr std::uint8_t FastRead = 0x0b; +inline constexpr std::uint8_t PageProgram = 0x02; - constexpr std::uint8_t SectorErase4KB = 0x20; - constexpr std::uint8_t BlockErase32KB = 0x52; - constexpr std::uint8_t BlockErase64KB = 0xd8; +inline constexpr std::uint8_t SectorErase4KB = 0x20; +inline constexpr std::uint8_t BlockErase32KB = 0x52; +inline constexpr std::uint8_t BlockErase64KB = 0xd8; - constexpr std::uint8_t ChipErase = 0xc7; - constexpr std::uint8_t ChipEraseSimilar = 0x60; +inline constexpr std::uint8_t ChipErase = 0xc7; +inline constexpr std::uint8_t ChipEraseSimilar = 0x60; - constexpr std::uint8_t EraseSuspend = 0x75; - constexpr std::uint8_t EraseResume = 0x7A; +inline constexpr std::uint8_t EraseSuspend = 0x75; +inline constexpr std::uint8_t EraseResume = 0x7A; - constexpr std::uint8_t PowerDownMode = 0xb9; - constexpr std::uint8_t ResumePowerDownMode = 0xab; +inline constexpr std::uint8_t PowerDownMode = 0xb9; +inline constexpr std::uint8_t ResumePowerDownMode = 0xab; - constexpr std::uint8_t DeviceIdFromPowedDownRelease = 0xab; - constexpr std::uint8_t ReadManufactureId = 0x90; +inline constexpr std::uint8_t DeviceIdFromPowedDownRelease = 0xab; +inline constexpr std::uint8_t ReadManufactureId = 0x90; - constexpr std::uint8_t JedecIdLength = 3; - constexpr std::uint8_t ReadJedecId = 0x9F; +inline constexpr std::uint8_t JedecIdLength = 3; +inline constexpr std::uint8_t ReadJedecId = 0x9F; - constexpr std::uint8_t UniqueIdLength = 8; // 64 bits - constexpr std::uint8_t ReadUniqueId = 0x4B; +inline constexpr std::uint8_t UniqueIdLength = 8; // 64 bits +inline constexpr std::uint8_t ReadUniqueId = 0x4B; - constexpr std::uint8_t DummyByte = 0x00; -} +inline constexpr std::uint8_t DummyByte = 0x00; +} // namespace WindbondCommandSet diff --git a/Firmware/drivers/winbondflash/inc/windbondflash/winbond_flash_templated.hpp b/Firmware/drivers/winbondflash/inc/windbondflash/winbond_flash_templated.hpp index 61557a18..04875c44 100644 --- a/Firmware/drivers/winbondflash/inc/windbondflash/winbond_flash_templated.hpp +++ b/Firmware/drivers/winbondflash/inc/windbondflash/winbond_flash_templated.hpp @@ -4,8 +4,10 @@ #include #include +#include #include +#include #include #include @@ -16,75 +18,102 @@ template class WinbondFlashDriver { using This_t = WinbondFlashDriver; + struct ChipSelectGuard + { + ChipSelectGuard(This_t* pThis) : m_pThis{pThis} + { + m_pThis->getSpiBus()->setCsPinLow(); + } + + ~ChipSelectGuard() + { + m_pThis->getSpiBus()->setCsPinHigh(); + } + + This_t* m_pThis; + }; + public: CoroUtils::VoidTask pageWrite( const std::uint32_t _address, std::span _blockData) noexcept { + + LOG_DEBUG("WinbondFlashDriver pageWrite"); constexpr std::uint16_t PageSize = 256; assert(_blockData.size() <= PageSize); - using TTupleProgram = decltype(std::forward_as_tuple( - WindbondCommandSet::PageProgram, - static_cast(_address & 0x00'FF'00'00 >> 16), - static_cast(_address & 0x00'00'FF'00 >> 8), - static_cast(_address & 0x00'00'00'FF))); - constexpr bool ManageSpiTransactions = false; + co_await eraseSector(_address); - getSpiBus()->setCsPinLow(); + LOG_DEBUG("WinbondFlashDriver XFER WE"); - using TTupleWe = decltype(std::forward_as_tuple(WindbondCommandSet::WriteEnable)); - co_await prepareXferTransaction( - std::forward_as_tuple(WindbondCommandSet::WriteEnable)); + { + ChipSelectGuard csGuard{this}; + co_await prepareXferTransaction(std::forward_as_tuple(WindbondCommandSet::WriteEnable)); + } + while (co_await checkIsBusy()) + { + LOG_DEBUG("WinbondFlashDriver wait for write completion"); + co_yield CoroUtils::CoroQueueMainLoop::GetInstance(); + } + + { + ChipSelectGuard csGuard{this}; - co_await prepareXferTransaction(std::forward_as_tuple( - WindbondCommandSet::PageProgram, - static_cast(_address & 0x00'FF'00'00 >> 16), - static_cast(_address & 0x00'00'FF'00 >> 8), - static_cast(_address & 0x00'00'00'FF))); + LOG_DEBUG("WinbondFlashDriver XFER PageProgram"); + co_await prepareXferTransaction(std::forward_as_tuple( + WindbondCommandSet::PageProgram, + static_cast((_address & 0x00'FF'00'00) >> 16), + static_cast((_address & 0x00'00'FF'00) >> 8), + static_cast(_address & 0x00'00'00'FF))); - co_await transmitChunk(std::span(_blockData.data(), _blockData.size())); + LOG_DEBUG("WinbondFlashDriver XFER blockData"); + co_await transmitChunk(std::span(_blockData.data(), _blockData.size())); + } + + while (co_await checkIsBusy()) + { + LOG_DEBUG("WinbondFlashDriver wait for write completion"); + co_yield CoroUtils::CoroQueueMainLoop::GetInstance(); + } - getSpiBus()->setCsPinHigh(); + LOG_DEBUG("WinbondFlashDriver XFER completed write"); } CoroUtils::Task> requestReadBlock( const std::uint32_t _address, const std::uint16_t _blockSize) noexcept { + constexpr std::uint16_t PageSize = 256; assert(_blockSize < PageSize); + std::span receivedData{}; - using TTupleRead = decltype(std::forward_as_tuple( - WindbondCommandSet::ReadData, - static_cast(_address & 0x00'FF'00'00 >> 16), - static_cast(_address & 0x00'00'FF'00 >> 8), - static_cast(_address & 0x00'00'00'FF))); - constexpr bool ManageSpiTransactions = false; - - getSpiBus()->setCsPinLow(); - - co_await prepareXferTransaction(std::forward_as_tuple( - WindbondCommandSet::ReadData, - static_cast((_address & 0x00'FF'00'00) >> 16), - static_cast((_address & 0x00'00'FF'00) >> 8), - static_cast(_address & 0x00'00'00'FF))); + { + ChipSelectGuard csGuard{this}; - auto& transmitBuffer = getSpiBus()->getDmaBufferTransmit(); - auto& receiveBuffer = getSpiBus()->getDmaBufferReceive(); + co_await prepareXferTransaction(std::forward_as_tuple( + WindbondCommandSet::ReadData, + static_cast((_address & 0x00'FF'00'00) >> 16), + static_cast((_address & 0x00'00'FF'00) >> 8), + static_cast(_address & 0x00'00'00'FF))); - std::fill_n( - transmitBuffer.begin(), - _blockSize, - WindbondCommandSet::DummyByte); + auto& transmitBuffer = getSpiBus()->getDmaBufferTransmit(); + auto& receiveBuffer = getSpiBus()->getDmaBufferReceive(); - auto receivedData = co_await xferTransaction( - std::span(transmitBuffer.data(), _blockSize), - std::span(receiveBuffer.data(), _blockSize)); + std::fill_n(transmitBuffer.begin(), _blockSize, WindbondCommandSet::DummyByte); - getSpiBus()->setCsPinHigh(); + receivedData = co_await xferTransaction( + std::span(transmitBuffer.data(), _blockSize), + std::span(receiveBuffer.data(), _blockSize)); + } + while (co_await checkIsBusy()) + { + LOG_DEBUG("WinbondFlashDriver wait for read completion"); + co_yield CoroUtils::CoroQueueMainLoop::GetInstance(); + } co_return receivedData; } @@ -94,22 +123,26 @@ template class WinbondFlashDriver CoroUtils::VoidTask requestChipErase() noexcept { + ChipSelectGuard csGuard{this}; co_await prepareXferTransaction(std::forward_as_tuple(WindbondCommandSet::ChipErase)); } CoroUtils::VoidTask requestPowerDown() noexcept { + ChipSelectGuard csGuard{this}; co_await prepareXferTransaction(std::forward_as_tuple(WindbondCommandSet::PowerDownMode)); } CoroUtils::VoidTask resumePowerDown() noexcept { + ChipSelectGuard csGuard{this}; co_await prepareXferTransaction( std::forward_as_tuple(WindbondCommandSet::ResumePowerDownMode)); } CoroUtils::Task> requestDeviceId() noexcept { + ChipSelectGuard csGuard{this}; auto receivedData = co_await prepareXferTransaction( std::forward_as_tuple( WindbondCommandSet::ReadUniqueId, @@ -129,6 +162,7 @@ template class WinbondFlashDriver CoroUtils::Task requestJEDEDCId() noexcept { + ChipSelectGuard csGuard{this}; auto receivedData = co_await prepareXferTransaction( std::forward_as_tuple(WindbondCommandSet::ReadJedecId), WindbondCommandSet::DummyByte, @@ -144,6 +178,20 @@ template class WinbondFlashDriver co_return JedecDeviceId; } + CoroUtils::Task checkIsBusy() noexcept + { + ChipSelectGuard csGuard{this}; + + LOG_DEBUG("WinbondFlashDriver checkIsBusy"); + + auto busyStatusRegister = co_await prepareXferTransaction( + std::forward_as_tuple(WindbondCommandSet::ReadStatusRegister1), + WindbondCommandSet::DummyByte); + + LOG_DEBUG("WinbondFlashDriver checkIsBusy completion"); + co_return busyStatusRegister[0] & WindbondCommandSet::Masks::EraseWriteInProgress; + } + const auto getSpiBus() const noexcept { return &m_spiBus; @@ -154,8 +202,25 @@ template class WinbondFlashDriver return &m_spiBus; } + CoroUtils::VoidTask eraseSector(std::uint32_t _address) + { + { + ChipSelectGuard guard{this}; + co_await prepareXferTransaction(std::forward_as_tuple( + WindbondCommandSet::SectorErase4KB, + static_cast((_address & 0x00'FF'00'00) >> 16), + static_cast((_address & 0x00'00'FF'00) >> 8), + static_cast(_address & 0x00'00'00'FF))); + } + while (co_await checkIsBusy()) + { + LOG_DEBUG("WinbondFlashDriver wait for the eraseSector completion"); + co_yield CoroUtils::CoroQueueMainLoop::GetInstance(); + } + } + private: - template + template CoroUtils::Task> prepareXferTransaction( TCommand&& _command, Args&&... _argList) @@ -163,9 +228,6 @@ template class WinbondFlashDriver auto& transmitBuffer = getSpiBus()->getDmaBufferTransmit(); auto& receiveBuffer = getSpiBus()->getDmaBufferReceive(); - if constexpr (manageCsPin) - getSpiBus()->setCsPinLow(); - processTransmitBuffer(transmitBuffer, std::forward(_command)); constexpr std::size_t CommandSize = std::tuple_size_v; @@ -180,29 +242,17 @@ template class WinbondFlashDriver std::span(transmitBuffer.data(), DummyListSize), std::span(receiveBuffer.data(), DummyListSize)); - if constexpr (manageCsPin) - getSpiBus()->setCsPinHigh(); - co_return std::span(receiveBuffer.data(), DummyListSize); } - template - CoroUtils::VoidTask prepareXferTransaction(TTuple&& _command) + template CoroUtils::VoidTask prepareXferTransaction(TTuple&& _command) { auto& transmitBuffer = getSpiBus()->getDmaBufferTransmit(); - auto& receiveBuffer = getSpiBus()->getDmaBufferReceive(); - - if constexpr (manageCsPin) - getSpiBus()->setCsPinLow(); - processTransmitBuffer(transmitBuffer, std::forward(_command)); constexpr std::size_t CommandSize = std::tuple_size_v; co_await transmitChunk(std::span(transmitBuffer.data(), CommandSize)); - - if constexpr (manageCsPin) - getSpiBus()->setCsPinHigh(); } CoroUtils::Task> xferTransaction( @@ -274,9 +324,7 @@ template class WinbondFlashDriver void await_suspend(std::coroutine_handle<> thisCoroutine) const { pThis->getSpiBus()->transmitBuffer( - pTransmitBuffer, - thisCoroutine.address(), - restoreInSpiCtx); + pTransmitBuffer, thisCoroutine.address(), restoreInSpiCtx); } }; @@ -285,7 +333,7 @@ template class WinbondFlashDriver std::span _pReceiveBuffer) noexcept { return XferAwaiter{ - .restoreInSpiCtx = true, + .restoreInSpiCtx = false, .pTransmitBuffer = _pTrasnmitBuffer, .pReceiveBuffer = _pReceiveBuffer, .pThis = this}; @@ -294,7 +342,7 @@ template class WinbondFlashDriver auto transmitChunk(std::span _pTrasnmitBuffer) noexcept { return TransmitAwaiter{ - .restoreInSpiCtx = true, .pTransmitBuffer = _pTrasnmitBuffer, .pThis = this}; + .restoreInSpiCtx = false, .pTransmitBuffer = _pTrasnmitBuffer, .pThis = this}; } private: diff --git a/Firmware/filesystem/CMakeLists.txt b/Firmware/filesystem/CMakeLists.txt index 0a5da533..32ec92f3 100644 --- a/Firmware/filesystem/CMakeLists.txt +++ b/Firmware/filesystem/CMakeLists.txt @@ -19,8 +19,22 @@ target_include_directories(watch_filesystem INTERFACE ${CMAKE_CURRENT_LIST_DIR} target_link_libraries(watch_filesystem INTERFACE littlefs + fmt::fmt ) +target_link_options( + watch_filesystem + INTERFACE + ${CPU_FLAGS} +) + +target_compile_options( + watch_filesystem + INTERFACE + ${COMMON_FLAGS} +) + + if(WIN32 OR UNIX AND ${TARGET_PLATFORM} STREQUAL "FIRMWARE_SIMULATOR" ) target_link_libraries(watch_filesystem INTERFACE spdlog::spdlog) endif() diff --git a/Firmware/filesystem/filesystem/block_device_wrapper/adaptor_block_device.hpp b/Firmware/filesystem/filesystem/block_device_wrapper/adaptor_block_device.hpp index d89f4962..7c4c21e7 100644 --- a/Firmware/filesystem/filesystem/block_device_wrapper/adaptor_block_device.hpp +++ b/Firmware/filesystem/filesystem/block_device_wrapper/adaptor_block_device.hpp @@ -3,38 +3,9 @@ #include "ih_block_device.hpp" #include -#include +#include #include - -template <> struct fmt::formatter> -{ - - constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) - { - - auto it = ctx.begin(), end = ctx.end(); - - if (it != end && *it == 'f') - { - ++it; - if (it != end && *it != '}') - throw format_error("invalid format"); - } - return it; - } - - template - auto format(const std::span& p, FormatContext& ctx) -> decltype(ctx.out()) - { - - auto tempFormatHolder = std::string_view{ - reinterpret_cast(p.data()), - reinterpret_cast(p.data()) + p.size()}; - auto dataSize = tempFormatHolder.length(); - - return format_to(ctx.out(), "{}", tempFormatHolder); - } -}; +#include namespace Filesystem::BlockDevice { @@ -93,4 +64,4 @@ class LogAdaptorBlockDevice : public BlockDeviceEntity class Holder public: Holder() noexcept { + LOG_DEBUG("Filesystem holder c-tor"); m_fsConfig = createLfsConfig(); } @@ -48,6 +49,8 @@ template class Holder LOG_DEBUG("Called to initializeFs"); auto error = co_await lfs_mount(&m_fsInstance, &m_fsConfig); + + LOG_DEBUG(fmt::format("lfs_mount error is ", error)); if (error) { co_await lfs_format(&m_fsInstance, &m_fsConfig); diff --git a/Firmware/graphics/gs_lvgl_service.cpp b/Firmware/graphics/gs_lvgl_service.cpp index 2046e2da..977bdf0e 100644 --- a/Firmware/graphics/gs_lvgl_service.cpp +++ b/Firmware/graphics/gs_lvgl_service.cpp @@ -71,9 +71,8 @@ class LvglGraphicsService::GSLvglServiceImpl private: void initLvglLogger() noexcept { - auto lvglLoggerCallback = cbc::obtain_connector([](const char* loggerMessage) { - LOG_DEBUG(loggerMessage); - }); + auto lvglLoggerCallback = + cbc::obtain_connector([](const char* loggerMessage) { LOG_DEBUG(loggerMessage); }); #if LV_USE_LOG == 1 lv_log_register_print_cb(lvglLoggerCallback); #endif @@ -92,10 +91,8 @@ class LvglGraphicsService::GSLvglServiceImpl auto monitorCallback = cbc::obtain_connector([](lv_disp_drv_t* disp_drv, uint32_t time, uint32_t px) { - LOG_DEBUG("Refresh time:"); - LOG_DEBUG(time); - LOG_DEBUG("Refreshed pixels:"); - LOG_DEBUG(px); + LOG_DEBUG(fmt::format("Refresh time: {}", time)); + LOG_DEBUG(fmt::format("Refreshed pixels: {}", px)); }); m_glDisplayDriver.monitor_cb = monitorCallback; diff --git a/Firmware/graphics/platform/gs_platform_layer.cpp b/Firmware/graphics/platform/gs_platform_layer.cpp index 5bf72c3e..be7ea2b7 100644 --- a/Firmware/graphics/platform/gs_platform_layer.cpp +++ b/Firmware/graphics/platform/gs_platform_layer.cpp @@ -87,8 +87,6 @@ void PlatformBackend::executeLvTaskHandler() noexcept #include #include -#include - namespace Graphics { diff --git a/Firmware/logger/CMakeLists.txt b/Firmware/logger/CMakeLists.txt index 67c9ca06..c678c795 100644 --- a/Firmware/logger/CMakeLists.txt +++ b/Firmware/logger/CMakeLists.txt @@ -20,9 +20,10 @@ target_link_libraries( logger_service PUBLIC UtilsLibrary - PRIVATE + fmt::fmt ) + if( ${TARGET_PLATFORM} STREQUAL "ARM_CORTEX" ) target_compile_definitions( @@ -41,9 +42,4 @@ elseif( ${TARGET_PLATFORM} STREQUAL "FIRMWARE_SIMULATOR" ) PRIVATE LoggerDesktop ) - target_link_libraries( - logger_service - PRIVATE - fmt::fmt - ) endif() \ No newline at end of file diff --git a/Firmware/logger/inc/logger/logger_service.hpp b/Firmware/logger/inc/logger/logger_service.hpp index ec4c2ba5..a647eb5b 100644 --- a/Firmware/logger/inc/logger/logger_service.hpp +++ b/Firmware/logger/inc/logger/logger_service.hpp @@ -8,6 +8,12 @@ #include #include +#if defined(USE_DEVICE_SPECIFIC) +#define FMT_HEADER_ONLY +#endif +#include +#include + enum class LogSeverity { Debug, @@ -29,6 +35,36 @@ enum class LogSeverity #define LOG_ERROR(ARGS) #endif +template <> struct fmt::formatter> +{ + + constexpr auto parse(format_parse_context& ctx) -> decltype(ctx.begin()) + { + + auto it = ctx.begin(), end = ctx.end(); + + if (it != end && *it == 'f') + { + ++it; + if (it != end && *it != '}') + std::terminate(); + } + return it; + } + + template + auto format(const std::span& p, FormatContext& ctx) -> decltype(ctx.out()) + { + + auto tempFormatHolder = std::string_view{ + reinterpret_cast(p.data()), + reinterpret_cast(p.data()) + p.size()}; + auto dataSize = tempFormatHolder.length(); + + return format_to(ctx.out(), "{}", tempFormatHolder); + } +}; + class Logger { diff --git a/Firmware/utils/inc/utils/coroutine/ExecutionQueueCoro.hpp b/Firmware/utils/inc/utils/coroutine/ExecutionQueueCoro.hpp index 9d9e82f1..7fe14cbc 100644 --- a/Firmware/utils/inc/utils/coroutine/ExecutionQueueCoro.hpp +++ b/Firmware/utils/inc/utils/coroutine/ExecutionQueueCoro.hpp @@ -1,5 +1,6 @@ #pragma once #include "Common.hpp" +#include namespace CoroUtils { @@ -27,6 +28,7 @@ struct CoroQueueMainLoop } } +private: template using TQueueStorageType = etl::queue_spsc_atomic; diff --git a/Firmware/utils/inc/utils/coroutine/Task.hpp b/Firmware/utils/inc/utils/coroutine/Task.hpp index e316294a..c9e27801 100644 --- a/Firmware/utils/inc/utils/coroutine/Task.hpp +++ b/Firmware/utils/inc/utils/coroutine/Task.hpp @@ -1,6 +1,8 @@ #pragma once #include "Common.hpp" +#include "ExecutionQueueCoro.hpp" #include + namespace CoroUtils { @@ -28,8 +30,7 @@ template struct Task return stdcoro::suspend_always{}; } - template - void return_value(TResultType&& _value) noexcept + template void return_value(TResultType&& _value) noexcept { m_coroutineResult.emplace(std::forward(_value)); } @@ -63,6 +64,28 @@ template struct Task } }; + auto yield_value(CoroQueueMainLoop& loop) const noexcept + { + struct ScheduleForExecution + { + CoroQueueMainLoop& loop; + + constexpr bool await_ready() const noexcept + { + return false; + } + void await_suspend(std::coroutine_handle<> thisCoroutine) + { + loop.pushToLater(thisCoroutine); + } + constexpr void await_resume() + { + } + }; + + return ScheduleForExecution{loop}; + } + auto final_suspend() noexcept { return final_awaitable{}; @@ -146,6 +169,28 @@ struct VoidTask return VoidTask{stdcoro::coroutine_handle::from_promise(*this)}; } + auto yield_value(CoroQueueMainLoop& loop) const noexcept + { + struct ScheduleForExecution + { + CoroQueueMainLoop& loop; + + constexpr bool await_ready() const noexcept + { + return false; + } + void await_suspend(std::coroutine_handle<> thisCoroutine) + { + loop.pushToLater(thisCoroutine); + } + constexpr void await_resume() + { + } + }; + + return ScheduleForExecution{loop}; + } + auto initial_suspend() noexcept { return stdcoro::suspend_always{}; From bc38f6d06feacd6a76b499ef64ef82f04797b706 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Sun, 27 Mar 2022 00:00:44 +0200 Subject: [PATCH 37/54] Extended Segger RTT buffer --- Firmware/logger/logger_service_impl.cpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/Firmware/logger/logger_service_impl.cpp b/Firmware/logger/logger_service_impl.cpp index 971f212a..261dac9c 100644 --- a/Firmware/logger/logger_service_impl.cpp +++ b/Firmware/logger/logger_service_impl.cpp @@ -145,10 +145,22 @@ class Logger::LoggerImpl { public: + LoggerImpl() + { + SEGGER_RTT_ConfigUpBuffer( + 0, + "SEGGER_MAIN_BUFFER", + seggerBuffer.data(), + kSeggerBufferSize, + SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL); + } + void logString(std::string_view _toLog) const noexcept { SEGGER_RTT_WriteString(0, _toLog.data()); } + static constexpr inline std::uint16_t kSeggerBufferSize = 512; + static inline std::array seggerBuffer{}; }; #endif From f8e5d980a51a6ca28c0a74043434961ee1c7a7f5 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Sat, 2 Apr 2022 02:13:02 +0300 Subject: [PATCH 38/54] Added logging adaptor to spiblockdevice --- Firmware/drivers/board/inc/board/hardware_usings.hpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/Firmware/drivers/board/inc/board/hardware_usings.hpp b/Firmware/drivers/board/inc/board/hardware_usings.hpp index 3474b88c..51070db7 100644 --- a/Firmware/drivers/board/inc/board/hardware_usings.hpp +++ b/Firmware/drivers/board/inc/board/hardware_usings.hpp @@ -10,12 +10,13 @@ #else #include #include +#include +#include #endif #include #include -#include #include namespace Hal @@ -51,8 +52,8 @@ struct BoardSpiFlashDescriptor static constexpr inline std::size_t kEraseSize = 4096; }; -using TSpiFlashBlockDevice = - Filesystem::BlockDevice::SpiFlashBlockDevice; +using TSpiFlashBlockDevice = Filesystem::BlockDevice::LogAdaptorBlockDevice< + Filesystem::BlockDevice::SpiFlashBlockDevice>; using TFilesystem = Platform::Fs::Holder; From 5c9c94a4d4b82351629ff63c213e830c1b8ccbf4 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Sat, 2 Apr 2022 02:13:39 +0300 Subject: [PATCH 39/54] Removed unique_ptr keeping of the WatchBoard --- Firmware/ap_application.cpp | 20 +++---------------- Firmware/ap_application.hpp | 6 +----- .../drivers/board/inc/board/watchboard.hpp | 4 ---- 3 files changed, 4 insertions(+), 26 deletions(-) diff --git a/Firmware/ap_application.cpp b/Firmware/ap_application.cpp index 9073e3e7..088f6992 100644 --- a/Firmware/ap_application.cpp +++ b/Firmware/ap_application.cpp @@ -45,11 +45,6 @@ Graphics::Events::TButtonsEvents toButtonEvent(Buttons::ButtonState _buttonToCon Application::Application() noexcept { LOG_INFO("Application start"); - initBoard(); - LOG_INFO("Complete board init"); - initPeripheral(); - LOG_INFO("Complete peripheral init"); - initServices(); initGraphicsStack(); initBleStack(); @@ -58,11 +53,6 @@ Application::Application() noexcept Application::~Application() noexcept = default; -void Application::initBoard() noexcept -{ - m_pBoardImpl = WatchBoard::createBoard(); -} - void Application::initServices() noexcept { auto bleServiceProvider = ServiceProviders::getFakeServiceCreator(); @@ -71,10 +61,6 @@ void Application::initServices() noexcept m_dateTimeService = bleServiceProvider->getDateTimeService(); } -void Application::initPeripheral() noexcept -{ -} - Application& Application::Instance() { static Application app; @@ -147,8 +133,8 @@ void Application::connectBoardSpecificEvents() noexcept { auto& pMainWindow = m_graphicsService->getMainWindow(); - m_pBoardImpl->getButtonsDriver()->onButtonEvent.connect([&pMainWindow]( - Buttons::ButtonEvent _buttonEvent) { + m_boardImpl.getButtonsDriver()->onButtonEvent.connect([&pMainWindow]( + Buttons::ButtonEvent _buttonEvent) { GsEvents::HardwareButtonId graphicsButton{GsEvents::to_underlying(_buttonEvent.buttonId)}; pMainWindow.getEventDispatcher().postEvent( @@ -164,7 +150,7 @@ void Application::runApplicationLoop() noexcept m_batteryLevelService->startBatteryMeasure(); m_dateTimeService->launchService(); - m_pBoardImpl->ledToggle(); + m_boardImpl.ledToggle(); while (true) { diff --git a/Firmware/ap_application.hpp b/Firmware/ap_application.hpp index bf52ab74..a297cfbe 100644 --- a/Firmware/ap_application.hpp +++ b/Firmware/ap_application.hpp @@ -25,12 +25,8 @@ class Application : public Utils::noncopyable void runApplicationLoop() noexcept; private: - void initBoard() noexcept; - void initServices() noexcept; - void initPeripheral() noexcept; - void initBleStack() noexcept; void initGraphicsStack() noexcept; @@ -48,5 +44,5 @@ class Application : public Utils::noncopyable std::unique_ptr m_heartrateService; std::unique_ptr m_dateTimeService; std::unique_ptr m_graphicsService; - WatchBoard::TBoardPtr m_pBoardImpl; + WatchBoard::Board m_boardImpl; }; diff --git a/Firmware/drivers/board/inc/board/watchboard.hpp b/Firmware/drivers/board/inc/board/watchboard.hpp index 381f0b99..4d5151f4 100644 --- a/Firmware/drivers/board/inc/board/watchboard.hpp +++ b/Firmware/drivers/board/inc/board/watchboard.hpp @@ -43,8 +43,4 @@ class Board : private Utils::noncopyable TFilesystemPtr m_filesystem; TFlashDriverPtr m_pFlashDriver; }; - -using TBoardPtr = std::unique_ptr; -TBoardPtr createBoard() noexcept; - } // namespace WatchBoard From c8eb9d79d5b5c03bc52deed2b1be05867b8e56d4 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Sat, 2 Apr 2022 02:14:26 +0300 Subject: [PATCH 40/54] Extented logger service with the log level disabling --- Firmware/logger/inc/logger/logger_service.hpp | 38 +++++++++++++------ Firmware/logger/logger_service_impl.cpp | 6 ++- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/Firmware/logger/inc/logger/logger_service.hpp b/Firmware/logger/inc/logger/logger_service.hpp index a647eb5b..bcbd2e53 100644 --- a/Firmware/logger/inc/logger/logger_service.hpp +++ b/Firmware/logger/inc/logger/logger_service.hpp @@ -16,19 +16,24 @@ enum class LogSeverity { + Trace, Debug, Info, Warn, - Error + Error, + None }; #define ENABLE_DEBUG_LOGGING #ifdef ENABLE_DEBUG_LOGGING -#define LOG_DEBUG(ARGS) (Logger::Instance().logDebug(LogSeverity::Debug, ARGS)) -#define LOG_INFO(ARGS) (Logger::Instance().logDebug(LogSeverity::Info, ARGS)) -#define LOG_WARN(ARGS) (Logger::Instance().logDebug(LogSeverity::Warn, ARGS)) -#define LOG_ERROR(ARGS) (Logger::Instance().logDebug(LogSeverity::Error, ARGS)) +#define LOG_TRACE(ARGS) (Logger::Instance().logDebug(ARGS)) +#define LOG_DEBUG(ARGS) (Logger::Instance().logDebug(ARGS)) +#define LOG_INFO(ARGS) (Logger::Instance().logDebug(ARGS)) +#define LOG_WARN(ARGS) (Logger::Instance().logDebug(ARGS)) +#define LOG_ERROR(ARGS) (Logger::Instance().logDebug(ARGS)) + #else +#define LOG_TRACE(ARGS) #define LOG_DEBUG(ARGS) #define LOG_INFO(ARGS) #define LOG_WARN(ARGS) @@ -59,7 +64,6 @@ template <> struct fmt::formatter> auto tempFormatHolder = std::string_view{ reinterpret_cast(p.data()), reinterpret_cast(p.data()) + p.size()}; - auto dataSize = tempFormatHolder.length(); return format_to(ctx.out(), "{}", tempFormatHolder); } @@ -91,7 +95,7 @@ class Logger return isCharType; } - template void logDebug(LogSeverity severity, const TToLog& _toLog) noexcept + template void logDebug(const TToLog& _toLog) noexcept { constexpr bool isString = IsStringType(); @@ -101,27 +105,39 @@ class Logger if (auto [p, ec] = std::to_chars(str.data(), str.data() + str.size(), _toLog); ec == std::errc()) { - logDebug(severity, std::string_view(str.data(), p - str.data())); + logDebugChecked(std::string_view(str.data(), p - str.data())); } } else { if constexpr (IsCharType()) - logDebug(severity, static_cast(_toLog)); + logDebugChecked(fmt::format("{}", _toLog)); else - logDebug(severity, static_cast(_toLog)); + logDebugChecked(static_cast(_toLog)); } } - void logDebug(LogSeverity severity, std::string_view _toLog) noexcept; + template constexpr void logDebugChecked(std::string_view _toLog) noexcept + { + if constexpr ( + static_cast>(severity) >= + static_cast>(kCurrentLogLevel)) + { + logDebugImpl(severity, _toLog); + } + } private: Logger() noexcept; ~Logger(); +private: + void logDebugImpl(LogSeverity severity, std::string_view _toLog) noexcept; + private: static constexpr inline std::size_t kImplSize = Platform::LogerImplSize; static constexpr inline std::size_t kImplAlignment = Platform::LogerImplAlignment; + static constexpr inline LogSeverity kCurrentLogLevel = LogSeverity::Debug; private: mutable std::atomic_flag m_loggerReady; diff --git a/Firmware/logger/logger_service_impl.cpp b/Firmware/logger/logger_service_impl.cpp index 261dac9c..766695c4 100644 --- a/Firmware/logger/logger_service_impl.cpp +++ b/Firmware/logger/logger_service_impl.cpp @@ -38,6 +38,8 @@ constexpr const char* const severityToString(LogSeverity severity) switch (severity) { + case LogSeverity::Trace: + return "[TRACE]"; case LogSeverity::Debug: return "[DEBUG]"; case LogSeverity::Info: @@ -46,6 +48,8 @@ constexpr const char* const severityToString(LogSeverity severity) return "[WARN]"; case LogSeverity::Error: return "[ERROR]"; + default: + return ""; } } } // namespace @@ -189,7 +193,7 @@ Logger& Logger::Instance() noexcept return intance; } -void Logger::logDebug(LogSeverity severity, std::string_view _toLog) noexcept +void Logger::logDebugImpl(LogSeverity severity, std::string_view _toLog) noexcept { m_pLoggerImpl->logString(severityToString(severity)); m_pLoggerImpl->logString(_toLog); From d584cad051c4290d4c5858a5f8973a668f987fc2 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Sat, 2 Apr 2022 02:17:55 +0300 Subject: [PATCH 41/54] Added trace logs to the SpiBlockDevice --- .../windbondflash/winbond_flash_templated.hpp | 26 +++++++++++-------- Firmware/filesystem/CMakeLists.txt | 5 ---- .../adaptor_block_device.hpp | 9 +++---- .../block_device_wrapper/spi_block_device.hpp | 3 ++- .../filesystem/filesystem_holder.hpp | 7 +++-- 5 files changed, 26 insertions(+), 24 deletions(-) diff --git a/Firmware/drivers/winbondflash/inc/windbondflash/winbond_flash_templated.hpp b/Firmware/drivers/winbondflash/inc/windbondflash/winbond_flash_templated.hpp index 04875c44..806b7c34 100644 --- a/Firmware/drivers/winbondflash/inc/windbondflash/winbond_flash_templated.hpp +++ b/Firmware/drivers/winbondflash/inc/windbondflash/winbond_flash_templated.hpp @@ -39,14 +39,14 @@ template class WinbondFlashDriver std::span _blockData) noexcept { - LOG_DEBUG("WinbondFlashDriver pageWrite"); + LOG_TRACE("WinbondFlashDriver pageWrite"); constexpr std::uint16_t PageSize = 256; assert(_blockData.size() <= PageSize); co_await eraseSector(_address); - LOG_DEBUG("WinbondFlashDriver XFER WE"); + LOG_TRACE("WinbondFlashDriver XFER WE"); { ChipSelectGuard csGuard{this}; @@ -54,52 +54,54 @@ template class WinbondFlashDriver } while (co_await checkIsBusy()) { - LOG_DEBUG("WinbondFlashDriver wait for write completion"); + LOG_TRACE("WinbondFlashDriver wait for write completion"); co_yield CoroUtils::CoroQueueMainLoop::GetInstance(); } { ChipSelectGuard csGuard{this}; - LOG_DEBUG("WinbondFlashDriver XFER PageProgram"); + LOG_TRACE("WinbondFlashDriver XFER PageProgram"); co_await prepareXferTransaction(std::forward_as_tuple( WindbondCommandSet::PageProgram, static_cast((_address & 0x00'FF'00'00) >> 16), static_cast((_address & 0x00'00'FF'00) >> 8), static_cast(_address & 0x00'00'00'FF))); - LOG_DEBUG("WinbondFlashDriver XFER blockData"); + LOG_TRACE("WinbondFlashDriver XFER blockData"); co_await transmitChunk(std::span(_blockData.data(), _blockData.size())); } while (co_await checkIsBusy()) { - LOG_DEBUG("WinbondFlashDriver wait for write completion"); + LOG_TRACE("WinbondFlashDriver wait for write completion"); co_yield CoroUtils::CoroQueueMainLoop::GetInstance(); } - LOG_DEBUG("WinbondFlashDriver XFER completed write"); + LOG_TRACE("WinbondFlashDriver XFER completed write"); } CoroUtils::Task> requestReadBlock( const std::uint32_t _address, const std::uint16_t _blockSize) noexcept { - constexpr std::uint16_t PageSize = 256; - assert(_blockSize < PageSize); + LOG_TRACE(fmt::format("WinbondFlashDriver requestReadBlock: {},{}", _blockSize, PageSize)); + assert(_blockSize <= PageSize); std::span receivedData{}; { ChipSelectGuard csGuard{this}; + LOG_TRACE("WinbondFlashDriver prepareXferTransaction BEGIN"); co_await prepareXferTransaction(std::forward_as_tuple( WindbondCommandSet::ReadData, static_cast((_address & 0x00'FF'00'00) >> 16), static_cast((_address & 0x00'00'FF'00) >> 8), static_cast(_address & 0x00'00'00'FF))); + LOG_TRACE("WinbondFlashDriver prepareXferTransaction COMPLETION"); auto& transmitBuffer = getSpiBus()->getDmaBufferTransmit(); auto& receiveBuffer = getSpiBus()->getDmaBufferReceive(); @@ -108,13 +110,15 @@ template class WinbondFlashDriver receivedData = co_await xferTransaction( std::span(transmitBuffer.data(), _blockSize), std::span(receiveBuffer.data(), _blockSize)); + + LOG_TRACE("WinbondFlashDriver xferTransaction receive"); } while (co_await checkIsBusy()) { - LOG_DEBUG("WinbondFlashDriver wait for read completion"); + LOG_TRACE("WinbondFlashDriver READ wait for read completion"); co_yield CoroUtils::CoroQueueMainLoop::GetInstance(); } - + LOG_TRACE("WinbondFlashDriver return back"); co_return receivedData; } void requestFastReadBlock(const std::uint32_t _address, const std::uint8_t _blockSize) noexcept diff --git a/Firmware/filesystem/CMakeLists.txt b/Firmware/filesystem/CMakeLists.txt index 32ec92f3..511531c3 100644 --- a/Firmware/filesystem/CMakeLists.txt +++ b/Firmware/filesystem/CMakeLists.txt @@ -34,11 +34,6 @@ target_compile_options( ${COMMON_FLAGS} ) - -if(WIN32 OR UNIX AND ${TARGET_PLATFORM} STREQUAL "FIRMWARE_SIMULATOR" ) - target_link_libraries(watch_filesystem INTERFACE spdlog::spdlog) -endif() - target_link_libraries( watch_filesystem INTERFACE drivers_ih diff --git a/Firmware/filesystem/filesystem/block_device_wrapper/adaptor_block_device.hpp b/Firmware/filesystem/filesystem/block_device_wrapper/adaptor_block_device.hpp index 7c4c21e7..558a78ee 100644 --- a/Firmware/filesystem/filesystem/block_device_wrapper/adaptor_block_device.hpp +++ b/Firmware/filesystem/filesystem/block_device_wrapper/adaptor_block_device.hpp @@ -5,7 +5,6 @@ #include #include -#include namespace Filesystem::BlockDevice { @@ -41,10 +40,10 @@ class LogAdaptorBlockDevice : public BlockDeviceEntity(_pBlockOut), _blockSize))); + fmt::arg("span_data", std::span(static_cast(_pBlockOut), _blockSize)))); } private: diff --git a/Firmware/filesystem/filesystem/block_device_wrapper/spi_block_device.hpp b/Firmware/filesystem/filesystem/block_device_wrapper/spi_block_device.hpp index 5ba84632..8da7bff7 100644 --- a/Firmware/filesystem/filesystem/block_device_wrapper/spi_block_device.hpp +++ b/Firmware/filesystem/filesystem/block_device_wrapper/spi_block_device.hpp @@ -46,7 +46,6 @@ class SpiFlashBlockDevice const std::uint8_t* _blockData, std::uint32_t _blockSize) noexcept { - std::uint32_t requestSize = _blockSize; const std::uint8_t* pBlockRequest = _blockData; std::uint32_t blockAddress{_address}; @@ -71,6 +70,8 @@ class SpiFlashBlockDevice std::uint8_t* pReadBuffer{_pBlockOut}; std::uint32_t blockAddress{_address}; + LOG_DEBUG("FS::SpiBlockDrevice read call"); + while (blockSize > 0) { auto resultBuffer = diff --git a/Firmware/filesystem/filesystem/filesystem_holder.hpp b/Firmware/filesystem/filesystem/filesystem_holder.hpp index 5f7f7382..08b3f62b 100644 --- a/Firmware/filesystem/filesystem/filesystem_holder.hpp +++ b/Firmware/filesystem/filesystem/filesystem_holder.hpp @@ -40,13 +40,13 @@ template class Holder public: Holder() noexcept { - LOG_DEBUG("Filesystem holder c-tor"); + LOG_DEBUG("FS: holder c-tor"); m_fsConfig = createLfsConfig(); } CoroUtils::VoidTask initializeFs() { - LOG_DEBUG("Called to initializeFs"); + LOG_DEBUG("FS: to initializeFs"); auto error = co_await lfs_mount(&m_fsInstance, &m_fsConfig); @@ -89,6 +89,7 @@ template class Holder void* buffer, lfs_size_t size) noexcept { + LOG_DEBUG("FS: read call"); auto pThis = reinterpret_cast(c->context); co_await pThis->getBlockDevice().read( static_cast(buffer), block * c->block_size + off, size); @@ -102,6 +103,7 @@ template class Holder const void* buffer, lfs_size_t size) noexcept { + LOG_DEBUG("FS: prog call"); auto pThis = reinterpret_cast(c->context); co_await pThis->getBlockDevice().write( (block * c->block_size + off), reinterpret_cast(buffer), size); @@ -111,6 +113,7 @@ template class Holder static CoroUtils::Task eraseCall(const lfs_config* c, lfs_block_t block) noexcept { + LOG_DEBUG("FS: erase call"); auto pThis = reinterpret_cast(c->context); co_return LFS_ERR_OK; } From 8af5f8006e2e2087885d38ceff661f6d5a841fd5 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Sat, 2 Apr 2022 02:19:02 +0300 Subject: [PATCH 42/54] Added filesystem init to the watchboard --- Firmware/drivers/board/watchboard.cpp | 41 +++++++++++++-------------- 1 file changed, 19 insertions(+), 22 deletions(-) diff --git a/Firmware/drivers/board/watchboard.cpp b/Firmware/drivers/board/watchboard.cpp index afeb9bc6..620b7023 100644 --- a/Firmware/drivers/board/watchboard.cpp +++ b/Firmware/drivers/board/watchboard.cpp @@ -94,8 +94,8 @@ void Board::initBoard() noexcept ret_code_t errorCode{}; errorCode = app_timer_init(); - LOG_DEBUG(fmt::format("app_timer_init code() {}", errorCode)); - APP_ERROR_CHECK(errorCode); + // LOG_DEBUG(fmt::format("app_timer_init code() {}", errorCode)); + // APP_ERROR_CHECK(errorCode); #endif m_buttonsDriver.initializeHalDependent(); initBoardSpiFlash(); @@ -114,27 +114,29 @@ void Board::initBoardTimer() noexcept void Board::initBoardSpiFlash() noexcept { - LOG_DEBUG("creation of flash driver started"); - m_pFlashDriver = std::make_unique(); + // LOG_DEBUG("creation of flash driver started"); + // m_pFlashDriver = std::make_unique(); - const std::uint32_t JedecId = co_await m_pFlashDriver->requestJEDEDCId(); - LOG_DEBUG(fmt::format("Jedec Id is {:#04x}", JedecId)); + // const std::uint32_t JedecId = co_await m_pFlashDriver->requestJEDEDCId(); + // LOG_DEBUG(fmt::format("Jedec Id is {:#04x}", JedecId)); - const std::span DeviceId = co_await m_pFlashDriver->requestDeviceId(); - LOG_DEBUG(fmt::format("Device id is {:02X}", fmt::join(DeviceId, ""))); + // const std::span DeviceId = co_await m_pFlashDriver->requestDeviceId(); + // LOG_DEBUG(fmt::format("Device id is {:02X}", fmt::join(DeviceId, ""))); - LOG_DEBUG("m_pFlashDriver->requestBlockWrite"); - auto blockTest = std::array{1, 2, 3, 4, 5, 6, 7, 8}; - co_await m_pFlashDriver->pageWrite(0x00, blockTest); - LOG_DEBUG("m_pFlashDriver->compltetedBlockWrite"); + // LOG_DEBUG("m_pFlashDriver->requestBlockWrite"); + // auto blockTest = std::array{1, 2, 3, 4, 5, 6, 7, 8}; + // co_await m_pFlashDriver->pageWrite(0x00, blockTest); + // LOG_DEBUG("m_pFlashDriver->compltetedBlockWrite"); - LOG_DEBUG("m_pFlashDriver->requestReadBlock"); - auto readResult = co_await m_pFlashDriver->requestReadBlock(0x00, blockTest.size()); - LOG_DEBUG(fmt::format("Got read block {}", readResult)); + // LOG_DEBUG("m_pFlashDriver->requestReadBlock"); + // auto readResult = co_await m_pFlashDriver->requestReadBlock(0x00, blockTest.size()); + // LOG_DEBUG(fmt::format("Got read block {}", readResult)); + LOG_DEBUG("Started filesystem creation"); m_filesystem = std::make_unique(); - LOG_DEBUG("Started filesystem initialization"); - CoroUtils::syncWait(m_filesystem->initializeFs()); + + LOG_DEBUG("Started filesystem creation"); + co_await m_filesystem->initializeFs(); LOG_DEBUG("Filesystem is ready"); } @@ -176,9 +178,4 @@ Hal::ButtonsDriver* Board::getButtonsDriver() noexcept return &m_buttonsDriver; } -TBoardPtr createBoard() noexcept -{ - return std::make_unique(); -} - }; // namespace WatchBoard From e4e00fecafca778190f3f5a257e1f4d778c70919 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Sat, 2 Apr 2022 02:19:25 +0300 Subject: [PATCH 43/54] Added assert-dump macro to the lfs_util_segger --- Firmware/3rdparty/littlefs_lib/lfs_util_segger.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Firmware/3rdparty/littlefs_lib/lfs_util_segger.h b/Firmware/3rdparty/littlefs_lib/lfs_util_segger.h index 40c89bf9..267644a0 100644 --- a/Firmware/3rdparty/littlefs_lib/lfs_util_segger.h +++ b/Firmware/3rdparty/littlefs_lib/lfs_util_segger.h @@ -90,7 +90,9 @@ extern "C" // Runtime assertions #ifndef LFS_ASSERT #ifndef LFS_NO_ASSERT -#define LFS_ASSERT(test) assert(test) +#define LFS_ASSERT(test) \ + assert(test); \ + SEGGER_RTT_printf(0, "assert expr:" #test "\n") #else #define LFS_ASSERT(test) #endif From 4373195df1f8a85981b7b0dcc1e93864e7b1dd2c Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Sat, 2 Apr 2022 02:22:13 +0300 Subject: [PATCH 44/54] Changed dump of the display refresh time to the single log line --- Firmware/graphics/gs_lvgl_service.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Firmware/graphics/gs_lvgl_service.cpp b/Firmware/graphics/gs_lvgl_service.cpp index 977bdf0e..f7048f8d 100644 --- a/Firmware/graphics/gs_lvgl_service.cpp +++ b/Firmware/graphics/gs_lvgl_service.cpp @@ -91,8 +91,7 @@ class LvglGraphicsService::GSLvglServiceImpl auto monitorCallback = cbc::obtain_connector([](lv_disp_drv_t* disp_drv, uint32_t time, uint32_t px) { - LOG_DEBUG(fmt::format("Refresh time: {}", time)); - LOG_DEBUG(fmt::format("Refreshed pixels: {}", px)); + LOG_DEBUG(fmt::format("Refresh time: {}, pixels: {}", time, px)); }); m_glDisplayDriver.monitor_cb = monitorCallback; From 3fa7fcac17b7e7ed96647ce0821c6d63a1a486cb Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Sat, 2 Apr 2022 02:26:40 +0300 Subject: [PATCH 45/54] Decreased severity and removed redundant logs --- .../inc/windbondflash/winbond_flash_templated.hpp | 6 +++--- .../filesystem/block_device_wrapper/spi_block_device.hpp | 2 -- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/Firmware/drivers/winbondflash/inc/windbondflash/winbond_flash_templated.hpp b/Firmware/drivers/winbondflash/inc/windbondflash/winbond_flash_templated.hpp index 806b7c34..3ccbc511 100644 --- a/Firmware/drivers/winbondflash/inc/windbondflash/winbond_flash_templated.hpp +++ b/Firmware/drivers/winbondflash/inc/windbondflash/winbond_flash_templated.hpp @@ -186,13 +186,13 @@ template class WinbondFlashDriver { ChipSelectGuard csGuard{this}; - LOG_DEBUG("WinbondFlashDriver checkIsBusy"); + LOG_TRACE("WinbondFlashDriver checkIsBusy"); auto busyStatusRegister = co_await prepareXferTransaction( std::forward_as_tuple(WindbondCommandSet::ReadStatusRegister1), WindbondCommandSet::DummyByte); - LOG_DEBUG("WinbondFlashDriver checkIsBusy completion"); + LOG_TRACE("WinbondFlashDriver checkIsBusy completion"); co_return busyStatusRegister[0] & WindbondCommandSet::Masks::EraseWriteInProgress; } @@ -218,7 +218,7 @@ template class WinbondFlashDriver } while (co_await checkIsBusy()) { - LOG_DEBUG("WinbondFlashDriver wait for the eraseSector completion"); + LOG_TRACE("WinbondFlashDriver wait for the eraseSector completion"); co_yield CoroUtils::CoroQueueMainLoop::GetInstance(); } } diff --git a/Firmware/filesystem/filesystem/block_device_wrapper/spi_block_device.hpp b/Firmware/filesystem/filesystem/block_device_wrapper/spi_block_device.hpp index 8da7bff7..5330dda6 100644 --- a/Firmware/filesystem/filesystem/block_device_wrapper/spi_block_device.hpp +++ b/Firmware/filesystem/filesystem/block_device_wrapper/spi_block_device.hpp @@ -70,8 +70,6 @@ class SpiFlashBlockDevice std::uint8_t* pReadBuffer{_pBlockOut}; std::uint32_t blockAddress{_address}; - LOG_DEBUG("FS::SpiBlockDrevice read call"); - while (blockSize > 0) { auto resultBuffer = From d06259f10a773c0b1435ea18f88e23f7ce178ff7 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Sat, 2 Apr 2022 02:28:35 +0300 Subject: [PATCH 46/54] Removed redundant logs --- Firmware/filesystem/filesystem/filesystem_holder.hpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Firmware/filesystem/filesystem/filesystem_holder.hpp b/Firmware/filesystem/filesystem/filesystem_holder.hpp index 08b3f62b..b74ec342 100644 --- a/Firmware/filesystem/filesystem/filesystem_holder.hpp +++ b/Firmware/filesystem/filesystem/filesystem_holder.hpp @@ -50,7 +50,7 @@ template class Holder auto error = co_await lfs_mount(&m_fsInstance, &m_fsConfig); - LOG_DEBUG(fmt::format("lfs_mount error is ", error)); + LOG_DEBUG(fmt::format("lfs_mount error is {}", error)); if (error) { co_await lfs_format(&m_fsInstance, &m_fsConfig); @@ -89,7 +89,6 @@ template class Holder void* buffer, lfs_size_t size) noexcept { - LOG_DEBUG("FS: read call"); auto pThis = reinterpret_cast(c->context); co_await pThis->getBlockDevice().read( static_cast(buffer), block * c->block_size + off, size); @@ -103,7 +102,6 @@ template class Holder const void* buffer, lfs_size_t size) noexcept { - LOG_DEBUG("FS: prog call"); auto pThis = reinterpret_cast(c->context); co_await pThis->getBlockDevice().write( (block * c->block_size + off), reinterpret_cast(buffer), size); @@ -113,7 +111,6 @@ template class Holder static CoroUtils::Task eraseCall(const lfs_config* c, lfs_block_t block) noexcept { - LOG_DEBUG("FS: erase call"); auto pThis = reinterpret_cast(c->context); co_return LFS_ERR_OK; } From 76166eaf1afb6aee0edfa193bd98b8691c75ee18 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Sat, 2 Apr 2022 20:00:42 +0300 Subject: [PATCH 47/54] Implemented colorful logging to the RTT logger backend --- .../3rdparty/littlefs_lib/lfs_util_segger.h | 4 +- Firmware/drivers/board/watchboard.cpp | 9 +- Firmware/drivers/spi/CMakeLists.txt | 2 - .../spi/inc/backends/spi_backend_desktop.hpp | 3 +- Firmware/filesystem/CMakeLists.txt | 5 - .../coroutine/coroutine_thoughts.cpp | 14 +-- Firmware/logger/logger_service_impl.cpp | 105 ++++++++++++++++-- 7 files changed, 113 insertions(+), 29 deletions(-) diff --git a/Firmware/3rdparty/littlefs_lib/lfs_util_segger.h b/Firmware/3rdparty/littlefs_lib/lfs_util_segger.h index 267644a0..93f51bc2 100644 --- a/Firmware/3rdparty/littlefs_lib/lfs_util_segger.h +++ b/Firmware/3rdparty/littlefs_lib/lfs_util_segger.h @@ -91,8 +91,8 @@ extern "C" #ifndef LFS_ASSERT #ifndef LFS_NO_ASSERT #define LFS_ASSERT(test) \ - assert(test); \ - SEGGER_RTT_printf(0, "assert expr:" #test "\n") + SEGGER_RTT_printf(0, "%s assert expr: %s", RTT_CTRL_TEXT_YELLOW, #test "\n"); \ + assert(test) #else #define LFS_ASSERT(test) #endif diff --git a/Firmware/drivers/board/watchboard.cpp b/Firmware/drivers/board/watchboard.cpp index 620b7023..70a9b240 100644 --- a/Firmware/drivers/board/watchboard.cpp +++ b/Firmware/drivers/board/watchboard.cpp @@ -89,7 +89,7 @@ void Board::initBoard() noexcept /* Configure board. */ bsp_board_init(BSP_INIT_LEDS); - LOG_DEBUG("Hello from E73 Mod Board!"); + LOG_INFO("Hello from E73 Mod Board!"); ret_code_t errorCode{}; @@ -132,12 +132,12 @@ void Board::initBoardSpiFlash() noexcept // auto readResult = co_await m_pFlashDriver->requestReadBlock(0x00, blockTest.size()); // LOG_DEBUG(fmt::format("Got read block {}", readResult)); - LOG_DEBUG("Started filesystem creation"); + LOG_INFO("Started filesystem creation"); m_filesystem = std::make_unique(); - LOG_DEBUG("Started filesystem creation"); + LOG_INFO("Completed filesystem creation"); co_await m_filesystem->initializeFs(); - LOG_DEBUG("Filesystem is ready"); + LOG_INFO("Filesystem is ready"); } Board::Board() noexcept @@ -153,7 +153,6 @@ void Board::ledToggle() noexcept while (true) { co_await 300ms; - // LOG_DEBUG("LED TIMER EXPIRED"); bsp_board_led_invert(0); co_await 100ms; bsp_board_led_invert(0); diff --git a/Firmware/drivers/spi/CMakeLists.txt b/Firmware/drivers/spi/CMakeLists.txt index 971da45d..5b09c00e 100644 --- a/Firmware/drivers/spi/CMakeLists.txt +++ b/Firmware/drivers/spi/CMakeLists.txt @@ -5,8 +5,6 @@ add_library( if( ${TARGET_PLATFORM} STREQUAL "ARM_CORTEX" ) target_link_libraries( spi INTERFACE NordicSDK::Common ) -elseif( ${TARGET_PLATFORM} STREQUAL "FIRMWARE_SIMULATOR") - target_link_libraries( spi INTERFACE fmt::fmt ) endif() target_compile_options( diff --git a/Firmware/drivers/spi/inc/backends/spi_backend_desktop.hpp b/Firmware/drivers/spi/inc/backends/spi_backend_desktop.hpp index 45b922bb..5ce556ea 100644 --- a/Firmware/drivers/spi/inc/backends/spi_backend_desktop.hpp +++ b/Firmware/drivers/spi/inc/backends/spi_backend_desktop.hpp @@ -15,6 +15,7 @@ #include #include +#include #define USE_THREADING_ASYNC_BACKEND @@ -41,7 +42,7 @@ class SpiBusDesktopBackend using namespace std::chrono_literals; std::unique_lock(m_transactionBufferGuard); - fmt::print("[Desktop SPI simultator]{}\n", m_dataBuffer); + LOG_DEBUG(fmt::format("[Desktop SPI simultator]{}\n", m_dataBuffer)); m_newDataArrived.store(false); m_transactionCompleted(); diff --git a/Firmware/filesystem/CMakeLists.txt b/Firmware/filesystem/CMakeLists.txt index 511531c3..6b25ded4 100644 --- a/Firmware/filesystem/CMakeLists.txt +++ b/Firmware/filesystem/CMakeLists.txt @@ -1,7 +1,3 @@ -if(WIN32 OR UNIX AND ${TARGET_PLATFORM} STREQUAL "FIRMWARE_SIMULATOR") - find_package(spdlog REQUIRED) -endif() - add_library(watch_filesystem INTERFACE filesystem/filesystem_holder.hpp @@ -19,7 +15,6 @@ target_include_directories(watch_filesystem INTERFACE ${CMAKE_CURRENT_LIST_DIR} target_link_libraries(watch_filesystem INTERFACE littlefs - fmt::fmt ) target_link_options( diff --git a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp index e5887b3b..9058feec 100644 --- a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp +++ b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp @@ -27,7 +27,7 @@ #include -#include +#include using TSpiBus = Interface::SpiTemplated::SpiBus; using TFlashDriver = ExternalFlash::WinbondFlashDriver; @@ -54,30 +54,30 @@ CoroUtils::VoidTask simpleRwTest( std::string_view fileName, std::string_view fileData) { - spdlog::warn("simpleRwTest begin"); + LOG_WARN("simpleRwTest begin"); auto lfs = filesystem.fsInstance(); { - spdlog::warn("FILE open begin"); + LOG_WARN("FILE open begin"); auto filename = std::move(co_await filesystem.openFile(fileName)); co_await filename.write( std::span(reinterpret_cast(fileData.data()), fileData.size())); - spdlog::warn("FILE open finalize"); + LOG_WARN("FILE open finalize"); } std::vector readFrom; readFrom.resize(fileData.size()); { - spdlog::warn("FILE read begin"); + LOG_WARN("FILE read begin"); auto holdedFile = std::move(co_await filesystem.openFile(fileName)); auto resultRead = co_await holdedFile.read(std::span(readFrom.data(), fileData.size())); - spdlog::warn("FILE read finalize"); + LOG_WARN("FILE read finalize"); } auto kCompareStringView{ std::string_view{reinterpret_cast(readFrom.data()), readFrom.size()}}; assert(fileData == kCompareStringView); - spdlog::warn("simpleRwTest finalize"); + LOG_WARN("simpleRwTest finalize"); } CoroUtils::VoidTask fileTest(TFilesystem& filesystem) { diff --git a/Firmware/logger/logger_service_impl.cpp b/Firmware/logger/logger_service_impl.cpp index 766695c4..74e33923 100644 --- a/Firmware/logger/logger_service_impl.cpp +++ b/Firmware/logger/logger_service_impl.cpp @@ -159,9 +159,78 @@ class Logger::LoggerImpl SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL); } - void logString(std::string_view _toLog) const noexcept + auto formatMessage(std::span formatBuffer, LogSeverity severity, std::string_view _toLog) + const noexcept + { + switch (severity) + { + case LogSeverity::Trace: + return fmt::format_to_n( + formatBuffer.data(), + formatBuffer.size(), + "{} {} {}\n", + RTT_CTRL_TEXT_WHITE, + severityToString(severity), + _toLog.data()); + break; + case LogSeverity::Debug: + return fmt::format_to_n( + formatBuffer.data(), + formatBuffer.size(), + "{} {} {}\n", + RTT_CTRL_TEXT_BRIGHT_WHITE, + severityToString(severity), + _toLog.data()); + break; + case LogSeverity::Info: + return fmt::format_to_n( + formatBuffer.data(), + formatBuffer.size(), + "{} {} {}\n", + RTT_CTRL_TEXT_MAGENTA, + severityToString(severity), + _toLog.data()); + break; + case LogSeverity::Warn: + return fmt::format_to_n( + formatBuffer.data(), + formatBuffer.size(), + "{} {} {}\n", + RTT_CTRL_TEXT_BRIGHT_YELLOW, + severityToString(severity), + _toLog.data()); + break; + case LogSeverity::Error: + return fmt::format_to_n( + formatBuffer.data(), + formatBuffer.size(), + "{} {} {}\n", + RTT_CTRL_TEXT_BRIGHT_RED, + severityToString(severity), + _toLog.data()); + break; + case LogSeverity::None: + break; + default: + break; + } + + std::terminate(); + } + void logString(LogSeverity severity, std::string_view _toLog) const noexcept + { + std::array formatBuffer{}; + auto formatResult = formatMessage( + std::span(formatBuffer.data(), formatBuffer.size() - 1), severity, _toLog); + formatBuffer[formatResult.size + 1] = '\0'; + auto formatString = + std::string_view(formatBuffer.data(), formatBuffer.data() + formatResult.size + 1); + + SEGGER_RTT_Write(0, formatString.data(), formatString.size()); + } + + void completeMessage() { - SEGGER_RTT_WriteString(0, _toLog.data()); } static constexpr inline std::uint16_t kSeggerBufferSize = 512; static inline std::array seggerBuffer{}; @@ -173,9 +242,33 @@ class Logger::LoggerImpl { public: - void logString(std::string_view _toLog) const noexcept + void logString(LogSeverity severity, std::string_view _toLog) const noexcept { - fmt::print(fg(fmt::color::steel_blue), "{}", _toLog.data()); + + switch (severity) + { + case LogSeverity::Trace: + fmt::print( + fg(fmt::color::white_smoke), "{} {}\n", severityToString(severity), _toLog.data()); + break; + case LogSeverity::Debug: + fmt::print(fg(fmt::color::white), "{} {}\n", severityToString(severity), _toLog.data()); + break; + case LogSeverity::Info: + fmt::print(fg(fmt::color::blue), "{} {}\n", severityToString(severity), _toLog.data()); + break; + case LogSeverity::Warn: + fmt::print( + fg(fmt::color::yellow), "{} {}\n", severityToString(severity), _toLog.data()); + break; + case LogSeverity::Error: + fmt::print(fg(fmt::color::red), "{} {}\n", severityToString(severity), _toLog.data()); + break; + case LogSeverity::None: + break; + default: + break; + } #if defined USE_MSVC_DEBUG_OUT OutputDebugString(_toLog.data()); #endif @@ -195,7 +288,5 @@ Logger& Logger::Instance() noexcept void Logger::logDebugImpl(LogSeverity severity, std::string_view _toLog) noexcept { - m_pLoggerImpl->logString(severityToString(severity)); - m_pLoggerImpl->logString(_toLog); - m_pLoggerImpl->logString(CaretReset); + m_pLoggerImpl->logString(severity, _toLog); } \ No newline at end of file From 6d6c66209c5635d42a4bf392f8362e3c369ec211 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Sat, 2 Apr 2022 20:16:14 +0300 Subject: [PATCH 48/54] Updated toolchain to 11.2 --- .github/workflows/build.yml | 12 ++++++------ Firmware/cmake/base.cmake | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index ee75b4e5..3e217a23 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -69,21 +69,21 @@ jobs: id: cache-gcc-toolchain uses: actions/cache@v2 with: - path: ${{ github.workspace }}/gcc_toolchain_10_3 - key: ${{runner.os}}-toolchain-v10_3 + path: ${{ github.workspace }}/gcc_toolchain_11_2 + key: ${{runner.os}}-toolchain-v11_2 - name: Get the latest arm-gcc-none-eabi-gcc uses: wei/wget@v1 if: steps.cache-gcc-toolchain.outputs.cache-hit != 'true' id: download-arm-gcc with: - args: "https://developer.arm.com/-/media/Files/downloads/gnu-rm/10.3-2021.07/gcc-arm-none-eabi-10.3-2021.07-x86_64-linux.tar.bz2" + args: "https://developer.arm.com/-/media/Files/downloads/gnu/11.2-2022.02/binrel/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi.tar.xz" - name: Unpack arm-gcc-compiler if: steps.cache-gcc-toolchain.outputs.cache-hit != 'true' run: | - mkdir gcc_toolchain_10_3 - tar -xjf gcc-arm-none-eabi-10.3-2021.07-x86_64-linux.tar.bz2 --directory ${{ github.workspace }}/gcc_toolchain_10_3 + mkdir gcc_toolchain_11_2 + tar -xJf gcc-arm-11.2-2022.02-x86_64-arm-none-eabi.tar.xz --directory ${{ github.workspace }}/gcc_toolchain_11_2 - name: Cache NordicSDK id: cache-nordic-sdk @@ -113,7 +113,7 @@ jobs: cmakeListsOrSettingsJson: CMakeListsTxtAdvanced cmakeListsTxtPath: ${{ github.workspace }}/Firmware/CMakeLists.txt cmakeBuildType: Debug - cmakeAppendedArgs: '-DTARGET_PLATFORM:STRING="ARM_CORTEX" -DEXECUTE_MCU_FLASHING=OFF -DCMAKE_BUILD_TYPE:STRING=Debug -DREDUCE_LVGL_BINARY_SIZE=ON -DPACKAGE_TESTS=OFF -DNRF5_SDK_PATH=${{ github.workspace }}/Nrf52SDKv16_0 -DARM_NONE_EABI_TOOLCHAIN_PATH:PATH=${{ github.workspace }}/gcc_toolchain_10_3/gcc-arm-none-eabi-10.3-2021.07' + cmakeAppendedArgs: '-DTARGET_PLATFORM:STRING="ARM_CORTEX" -DEXECUTE_MCU_FLASHING=OFF -DCMAKE_BUILD_TYPE:STRING=Debug -DREDUCE_LVGL_BINARY_SIZE=ON -DPACKAGE_TESTS=OFF -DNRF5_SDK_PATH=${{ github.workspace }}/Nrf52SDKv16_0 -DARM_NONE_EABI_TOOLCHAIN_PATH:PATH=${{ github.workspace }}/gcc_toolchain_11_2/gcc-arm-11.2-2022.02-x86_64-arm-none-eabi' buildWithCMake: true # # Runs a set of commands using the runners shell diff --git a/Firmware/cmake/base.cmake b/Firmware/cmake/base.cmake index 41335db0..01097c0c 100644 --- a/Firmware/cmake/base.cmake +++ b/Firmware/cmake/base.cmake @@ -1,6 +1,6 @@ if( NOT ARM_NONE_EABI_TOOLCHAIN_PATH ) #set(ARM_NONE_EABI_TOOLCHAIN_PATH "C:/gcc_none_eabi_9_2_1") - set(ARM_NONE_EABI_TOOLCHAIN_PATH "C:/gcc_arm_none_eabi_10_3") + set(ARM_NONE_EABI_TOOLCHAIN_PATH "C:/gcc_arm_none_eabi_11_2") message(STATUS "No ARM_NONE_EABI_TOOLCHAIN_PATH specified, using default: " ${ARM_NONE_EABI_TOOLCHAIN_PATH}) else() message(STATUS " ARM_NONE_EABI_TOOLCHAIN_PATH specified using: " ${ARM_NONE_EABI_TOOLCHAIN_PATH}) From 48417b7499374a8a784aaac003433767faaad9f6 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Mon, 30 May 2022 02:10:42 +0300 Subject: [PATCH 49/54] [coroutine][filesystem]added coroutine loop executor for testing purouses --- Firmware/firmware_tests/CMakeLists.txt | 2 + .../firmware_tests/coroutine/CMakeLists.txt | 15 ++-- .../coroutine/coroutine_thoughts.cpp | 9 ++- .../windond_flash/flash_driver_test_suite.cpp | 80 ++++++++++++++----- .../drivers/windond_flash/flash_fixture.hpp | 11 +++ .../filesystem/filesystem_fixture.hpp | 12 +++ .../coroutine_loop_executor.hpp | 35 ++++++++ Firmware/logger/inc/logger/logger_service.hpp | 2 +- 8 files changed, 134 insertions(+), 32 deletions(-) create mode 100644 Firmware/firmware_tests/testing_common/inc/testing_common/coroutine_loop_executor.hpp diff --git a/Firmware/firmware_tests/CMakeLists.txt b/Firmware/firmware_tests/CMakeLists.txt index 00465aef..380e6de6 100644 --- a/Firmware/firmware_tests/CMakeLists.txt +++ b/Firmware/firmware_tests/CMakeLists.txt @@ -13,6 +13,7 @@ enable_testing() find_package(GTest REQUIRED) add_subdirectory(coroutine) add_subdirectory(article_example) +add_subdirectory(testing_common) add_executable( ${PROJECT_NAME} @@ -67,6 +68,7 @@ target_link_libraries( watch_filesystem buttons_driver windbond_spi_flash_driver + testing_common ) target_compile_features( diff --git a/Firmware/firmware_tests/coroutine/CMakeLists.txt b/Firmware/firmware_tests/coroutine/CMakeLists.txt index e727bf8e..ff35633c 100644 --- a/Firmware/firmware_tests/coroutine/CMakeLists.txt +++ b/Firmware/firmware_tests/coroutine/CMakeLists.txt @@ -28,12 +28,15 @@ target_compile_features( cxx_std_20 ) -if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") - set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /fsanitize=address") -else() - set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address") - set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address") - set (CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address") + if( ${ENABLE_SANITIZE_BUILD} ) + + if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") + set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /fsanitize=address") + else() + set (CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address") + set (CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address") + set (CMAKE_LINKER_FLAGS_DEBUG "${CMAKE_LINKER_FLAGS_DEBUG} -fno-omit-frame-pointer -fsanitize=address") + endif() endif() target_link_libraries( diff --git a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp index 9058feec..875a8bb7 100644 --- a/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp +++ b/Firmware/firmware_tests/coroutine/coroutine_thoughts.cpp @@ -19,11 +19,11 @@ #include #include "st7789_draft.hpp" -#include -#include #include -#include #include +#include +#include +#include #include @@ -43,7 +43,8 @@ using TLogHeapBlockDevice = Filesystem::BlockDevice::kReadSize, Filesystem::BlockDevice::kEraseSize>>; -using TCombinedBlockDevice = Filesystem::BlockDevice::CombinerBlockDevice; +using TCombinedBlockDevice = + Filesystem::BlockDevice::CombinerBlockDevice; using TFilesystem = Platform::Fs::Holder; diff --git a/Firmware/firmware_tests/drivers/windond_flash/flash_driver_test_suite.cpp b/Firmware/firmware_tests/drivers/windond_flash/flash_driver_test_suite.cpp index 9e4f7160..fa9257a7 100644 --- a/Firmware/firmware_tests/drivers/windond_flash/flash_driver_test_suite.cpp +++ b/Firmware/firmware_tests/drivers/windond_flash/flash_driver_test_suite.cpp @@ -9,8 +9,43 @@ #include #include -using ::testing::Return; using ::testing::ContainerEq; +using ::testing::Return; + +namespace Testing::FlashCommandStubs +{ +constexpr std::size_t WriteEnableCommandLength = 1; +constexpr const std::array writeEnableCommand{ + WindbondCommandSet::WriteEnable}; + +constexpr std::size_t ReadStatusCommandLength = 2; +constexpr const std::array readStatusRegisterCommand{ + WindbondCommandSet::ReadStatusRegister1, + WindbondCommandSet::DummyByte}; + + +constexpr std::uint32_t address{0x10'00}; + + +constexpr std::size_t ProgramPageCommandLength = 4; +constexpr const std::array pageProgramCommand{ + WindbondCommandSet::PageProgram, + static_cast(address & 0x00'FF'00'00 >> 16), + static_cast(address & 0x00'00'FF'00 >> 8), + static_cast(address & 0x00'00'00'FF)}; + +} + +namespace Testing::Utils +{ +template +constexpr std::span make_span(const TByteSequence& toSpan) +{ + return std::span( + reinterpret_cast(toSpan.data()), toSpan.size()); +} +} + TEST_F(FlashDriverTest, RequestJedecId) { @@ -21,7 +56,8 @@ TEST_F(FlashDriverTest, RequestJedecId) EXPECT_CALL(spiMockAccess(), receivedData) .Times(1) - .WillOnce(Return(std::span(reinterpret_cast(ExpectedStream.data()), ExpectedStream.size()))); + .WillOnce(Return(std::span( + reinterpret_cast(ExpectedStream.data()), ExpectedStream.size()))); auto fToJedecId = [](const TDataStream& _jedecId) { std::uint32_t result{}; @@ -49,32 +85,34 @@ TEST_F(FlashDriverTest, RequestWriteBlock) auto TransmitData{std::array{0xEF, 0xFF, 0x18, 0x19, 0x20, 0x21, 0x22}}; - constexpr std::uint32_t address{0x10'00}; - - constexpr std::size_t WriteEnableCommandLength = 1; - constexpr const std::array writeEnableCommand {WindbondCommandSet::WriteEnable}; - constexpr std::size_t ProgramPageCommandLength = 4; - constexpr const std::array pageProgramCommand{ - WindbondCommandSet::PageProgram, - static_cast(address & 0x00'FF'00'00 >> 16), - static_cast(address & 0x00'00'FF'00 >> 8), - static_cast(address & 0x00'00'00'FF) - }; testing::Sequence sequence; // https://gist.github.com/cppengineer/f1b6bc0f04ac7c29e963364f2c564a5e - const auto writeEnableSpan = - std::span(writeEnableCommand.data(), writeEnableCommand.size()); + const auto writeEnableSpan = Testing::Utils::make_span(Testing::FlashCommandStubs::writeEnableCommand); + + TDataStream ExpectedStream{std::byte(0xEF), std::byte(0x40), std::byte(0x18)}; + + + EXPECT_CALL(spiMockAccess(), receivedData) + .Times(2) + .WillOnce(Return(Testing::Utils::make_span(ExpectedStream))); + + const auto ProgramCommandSpan = + Testing::Utils::make_span(Testing::FlashCommandStubs::pageProgramCommand); - const auto ProgramCommandSpan = std::span(pageProgramCommand.data(), pageProgramCommand.size()); EXPECT_CALL(spiMockAccess(), sentData) .With(SpanChecker(writeEnableSpan)) .Times(1) .InSequence(sequence); + EXPECT_CALL(spiMockAccess(), sentData) + .With(SpanChecker(Testing::FlashCommandStubs::readStatusRegisterCommand)) + .Times(1) + .InSequence(sequence); + EXPECT_CALL(spiMockAccess(), sentData) .With(SpanChecker(ProgramCommandSpan)) .Times(1) @@ -84,7 +122,9 @@ TEST_F(FlashDriverTest, RequestWriteBlock) .Times(1) .InSequence(sequence); - auto task = flashDriver.pageWrite(address, std::span(TransmitData.data(), TransmitData.size())); + auto task = flashDriver.pageWrite( + Testing::FlashCommandStubs::address, + Testing::Utils::make_span(TransmitData)); CoroUtils::syncWait(task); } @@ -96,8 +136,7 @@ TEST_F(FlashDriverTest, RequestReadBlock) using TStream = std::array; - auto ReceiveData{ - TStream{0xEF, 0xFF, 0x18, 0x19, 0x20, 0x21, 0x22}}; + auto ReceiveData{TStream{0xEF, 0xFF, 0x18, 0x19, 0x20, 0x21, 0x22}}; auto Dummy{TStream{}}; @@ -121,8 +160,7 @@ TEST_F(FlashDriverTest, RequestReadBlock) const auto DummySpan = std::span(Dummy.data(), Dummy.size()); - const auto ReadDataSpan = - std::span(readCommand.data(), readCommand.size()); + const auto ReadDataSpan = std::span(readCommand.data(), readCommand.size()); EXPECT_CALL(spiMockAccess(), sentData) .With(SpanChecker(ReadDataSpan)) diff --git a/Firmware/firmware_tests/drivers/windond_flash/flash_fixture.hpp b/Firmware/firmware_tests/drivers/windond_flash/flash_fixture.hpp index 6eb8c691..870049f1 100644 --- a/Firmware/firmware_tests/drivers/windond_flash/flash_fixture.hpp +++ b/Firmware/firmware_tests/drivers/windond_flash/flash_fixture.hpp @@ -13,6 +13,7 @@ // TODO Fix include more clearly #include "../spi/spi_fake_backend.hpp" #include "../spi/mock_gpio.hpp" +#include class FlashDriverTest : public ::testing::Test { @@ -25,8 +26,15 @@ class FlashDriverTest : public ::testing::Test protected: void SetUp() override { + m_coroLoopExecutor.startCoroLoop(); } + void TearDown() override + { + m_coroLoopExecutor.stopCoroutineLoop(); + } + + decltype(auto) getMockGpio() { return flashDriver.getSpiBus()->getBackendImpl().accesToCsPin(); @@ -44,4 +52,7 @@ class FlashDriverTest : public ::testing::Test protected: TFlashTestDriver flashDriver; + +private: + Testing::Common::CoroutineLoopExecutor m_coroLoopExecutor; }; diff --git a/Firmware/firmware_tests/filesystem/filesystem_fixture.hpp b/Firmware/firmware_tests/filesystem/filesystem_fixture.hpp index f2c7ce6a..c1effa56 100644 --- a/Firmware/firmware_tests/filesystem/filesystem_fixture.hpp +++ b/Firmware/firmware_tests/filesystem/filesystem_fixture.hpp @@ -18,6 +18,8 @@ #include "../drivers/spi/spi_fake_backend.hpp" #include "filesystem_test_data.hpp" +#include + using TFlashTestDriver = ExternalFlash::WinbondFlashDriver< Interface::SpiTemplated::SpiBus>; @@ -62,16 +64,26 @@ template class FilesystemTopLevelTestFixture : public ::te public: FilesystemTopLevelTestFixture() : m_params{std::get>(kFilesystemTestParams)} + { } protected: void SetUp() override { + m_coroLoopExecutor.startCoroLoop(); CoroUtils::syncWait(m_testFilesystem.initializeFs()); } + void TearDown() override + { + m_coroLoopExecutor.stopCoroutineLoop(); + } + protected: TestParamPlaceholder m_params; Filesystem m_testFilesystem; + +private: + Testing::Common::CoroutineLoopExecutor m_coroLoopExecutor; }; \ No newline at end of file diff --git a/Firmware/firmware_tests/testing_common/inc/testing_common/coroutine_loop_executor.hpp b/Firmware/firmware_tests/testing_common/inc/testing_common/coroutine_loop_executor.hpp new file mode 100644 index 00000000..d89174c7 --- /dev/null +++ b/Firmware/firmware_tests/testing_common/inc/testing_common/coroutine_loop_executor.hpp @@ -0,0 +1,35 @@ +#pragma once + +#include +#include +#include +#include + +namespace Testing::Common +{ +class CoroutineLoopExecutor +{ +public: + void startCoroLoop() + { + + m_coroLoopWorker = std::make_unique([stopSource = m_stopSource.get_token()] { + while (!stopSource.stop_requested()) + { + CoroUtils::CoroQueueMainLoop::GetInstance().processQueue(); + } + }); + } + + void stopCoroutineLoop() + { + m_stopSource.request_stop(); + } + +private: + std::stop_source m_stopSource; + std::unique_ptr m_coroLoopWorker; + +}; + +} \ No newline at end of file diff --git a/Firmware/logger/inc/logger/logger_service.hpp b/Firmware/logger/inc/logger/logger_service.hpp index bcbd2e53..941110ea 100644 --- a/Firmware/logger/inc/logger/logger_service.hpp +++ b/Firmware/logger/inc/logger/logger_service.hpp @@ -65,7 +65,7 @@ template <> struct fmt::formatter> reinterpret_cast(p.data()), reinterpret_cast(p.data()) + p.size()}; - return format_to(ctx.out(), "{}", tempFormatHolder); + return fmt::format_to(ctx.out(), "{}", tempFormatHolder); } }; From 584a3746e672aea01099a0f029e33759706fbf26 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Fri, 3 Jun 2022 02:00:02 +0300 Subject: [PATCH 50/54] [filesystem] Added erase flash cmd expectation to tests --- .../drivers/spi/spi_fake_backend.hpp | 3 ++- .../windond_flash/flash_driver_test_suite.cpp | 21 ++++++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/Firmware/firmware_tests/drivers/spi/spi_fake_backend.hpp b/Firmware/firmware_tests/drivers/spi/spi_fake_backend.hpp index 3c4052d3..27de6a73 100644 --- a/Firmware/firmware_tests/drivers/spi/spi_fake_backend.hpp +++ b/Firmware/firmware_tests/drivers/spi/spi_fake_backend.hpp @@ -20,7 +20,8 @@ class SpiBusBackendStub void sendChunk(const std::uint8_t* _pBuffer, const size_t _bufferSize) noexcept { BusTransactionsTransmit.emplace_back(_pBuffer, _bufferSize); - m_spiMocker.sentData(std::span(_pBuffer,_bufferSize)); + auto kChunk{std::span(_pBuffer, _bufferSize)}; + m_spiMocker.sentData(kChunk); m_completedTransaction(); } diff --git a/Firmware/firmware_tests/drivers/windond_flash/flash_driver_test_suite.cpp b/Firmware/firmware_tests/drivers/windond_flash/flash_driver_test_suite.cpp index fa9257a7..578c7a3b 100644 --- a/Firmware/firmware_tests/drivers/windond_flash/flash_driver_test_suite.cpp +++ b/Firmware/firmware_tests/drivers/windond_flash/flash_driver_test_suite.cpp @@ -23,10 +23,8 @@ constexpr const std::array readStatusRegi WindbondCommandSet::ReadStatusRegister1, WindbondCommandSet::DummyByte}; - constexpr std::uint32_t address{0x10'00}; - constexpr std::size_t ProgramPageCommandLength = 4; constexpr const std::array pageProgramCommand{ WindbondCommandSet::PageProgram, @@ -34,7 +32,12 @@ constexpr const std::array pageProgramCo static_cast(address & 0x00'00'FF'00 >> 8), static_cast(address & 0x00'00'00'FF)}; -} +constexpr const std::array erase4KSectorCommand{ + WindbondCommandSet::SectorErase4KB, + static_cast((address & 0x00'FF'00'00) >> 16), + static_cast((address & 0x00'00'FF'00) >> 8), + static_cast(address & 0x00'00'00'FF)}; +} // namespace Testing::FlashCommandStubs namespace Testing::Utils { @@ -80,8 +83,8 @@ MATCHER_P(SpanChecker, spanItem, "Span content equals") TEST_F(FlashDriverTest, RequestWriteBlock) { - EXPECT_CALL(getMockGpio(), setGpioLow()).Times(1); - EXPECT_CALL(getMockGpio(), setGpioHigh()).Times(1); + EXPECT_CALL(getMockGpio(), setGpioLow()).Times(2); + EXPECT_CALL(getMockGpio(), setGpioHigh()).Times(2); auto TransmitData{std::array{0xEF, 0xFF, 0x18, 0x19, 0x20, 0x21, 0x22}}; @@ -103,6 +106,14 @@ TEST_F(FlashDriverTest, RequestWriteBlock) const auto ProgramCommandSpan = Testing::Utils::make_span(Testing::FlashCommandStubs::pageProgramCommand); + const auto kEraseSectorCommandSpan = + Testing::Utils::make_span(Testing::FlashCommandStubs::erase4KSectorCommand); + + EXPECT_CALL(spiMockAccess(), sentData) + .With(SpanChecker(kEraseSectorCommandSpan)) + .Times(1) + .InSequence(sequence); + EXPECT_CALL(spiMockAccess(), sentData) .With(SpanChecker(writeEnableSpan)) .Times(1) From 7465ea43d244a758cecd4cacad7cf7c6e8aac38e Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Mon, 15 Aug 2022 23:22:49 +0300 Subject: [PATCH 51/54] [firmware][tests] added missed CMakeLists.txt for the testing_common target --- Firmware/firmware_tests/testing_common/CMakeLists.txt | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 Firmware/firmware_tests/testing_common/CMakeLists.txt diff --git a/Firmware/firmware_tests/testing_common/CMakeLists.txt b/Firmware/firmware_tests/testing_common/CMakeLists.txt new file mode 100644 index 00000000..17807932 --- /dev/null +++ b/Firmware/firmware_tests/testing_common/CMakeLists.txt @@ -0,0 +1,5 @@ + +add_library( testing_common INTERFACE ) + +target_link_libraries(testing_common INTERFACE UtilsLibrary) +target_include_directories(testing_common INTERFACE ${CMAKE_CURRENT_LIST_DIR}/inc) From 1de6108d85d1f87d8643ee26c764cba19705f11d Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Wed, 17 Aug 2022 11:18:26 +0300 Subject: [PATCH 52/54] [firmware][testing] fixed flash_driver_test_suite spi tests --- .../windbondflash/winbond_flash_templated.hpp | 31 ++--- .../windond_flash/flash_driver_test_suite.cpp | 118 +++++++++++------- 2 files changed, 89 insertions(+), 60 deletions(-) diff --git a/Firmware/drivers/winbondflash/inc/windbondflash/winbond_flash_templated.hpp b/Firmware/drivers/winbondflash/inc/windbondflash/winbond_flash_templated.hpp index 3ccbc511..5080d33e 100644 --- a/Firmware/drivers/winbondflash/inc/windbondflash/winbond_flash_templated.hpp +++ b/Firmware/drivers/winbondflash/inc/windbondflash/winbond_flash_templated.hpp @@ -35,7 +35,7 @@ template class WinbondFlashDriver public: CoroUtils::VoidTask pageWrite( - const std::uint32_t _address, + std::uint32_t _address, std::span _blockData) noexcept { @@ -44,10 +44,6 @@ template class WinbondFlashDriver assert(_blockData.size() <= PageSize); - co_await eraseSector(_address); - - LOG_TRACE("WinbondFlashDriver XFER WE"); - { ChipSelectGuard csGuard{this}; co_await prepareXferTransaction(std::forward_as_tuple(WindbondCommandSet::WriteEnable)); @@ -58,6 +54,10 @@ template class WinbondFlashDriver co_yield CoroUtils::CoroQueueMainLoop::GetInstance(); } + co_await eraseSector(_address); + + LOG_TRACE("WinbondFlashDriver XFER WE"); + { ChipSelectGuard csGuard{this}; @@ -69,7 +69,7 @@ template class WinbondFlashDriver static_cast(_address & 0x00'00'00'FF))); LOG_TRACE("WinbondFlashDriver XFER blockData"); - co_await transmitChunk(std::span(_blockData.data(), _blockData.size())); + co_await transmitChunk(_blockData); } while (co_await checkIsBusy()) @@ -82,13 +82,20 @@ template class WinbondFlashDriver } CoroUtils::Task> requestReadBlock( - const std::uint32_t _address, - const std::uint16_t _blockSize) noexcept + std::uint32_t _address, + std::uint16_t _blockSize) noexcept { constexpr std::uint16_t PageSize = 256; LOG_TRACE(fmt::format("WinbondFlashDriver requestReadBlock: {},{}", _blockSize, PageSize)); assert(_blockSize <= PageSize); + + while (co_await checkIsBusy()) + { + LOG_TRACE("WinbondFlashDriver READ wait for read completion"); + co_yield CoroUtils::CoroQueueMainLoop::GetInstance(); + } + std::span receivedData{}; { @@ -113,15 +120,11 @@ template class WinbondFlashDriver LOG_TRACE("WinbondFlashDriver xferTransaction receive"); } - while (co_await checkIsBusy()) - { - LOG_TRACE("WinbondFlashDriver READ wait for read completion"); - co_yield CoroUtils::CoroQueueMainLoop::GetInstance(); - } + LOG_TRACE("WinbondFlashDriver return back"); co_return receivedData; } - void requestFastReadBlock(const std::uint32_t _address, const std::uint8_t _blockSize) noexcept + void requestFastReadBlock(std::uint32_t _address, const std::uint8_t _blockSize) noexcept { } diff --git a/Firmware/firmware_tests/drivers/windond_flash/flash_driver_test_suite.cpp b/Firmware/firmware_tests/drivers/windond_flash/flash_driver_test_suite.cpp index 578c7a3b..1291bf77 100644 --- a/Firmware/firmware_tests/drivers/windond_flash/flash_driver_test_suite.cpp +++ b/Firmware/firmware_tests/drivers/windond_flash/flash_driver_test_suite.cpp @@ -18,18 +18,18 @@ constexpr std::size_t WriteEnableCommandLength = 1; constexpr const std::array writeEnableCommand{ WindbondCommandSet::WriteEnable}; -constexpr std::size_t ReadStatusCommandLength = 2; +constexpr std::size_t ReadStatusCommandLength = 1; constexpr const std::array readStatusRegisterCommand{ - WindbondCommandSet::ReadStatusRegister1, - WindbondCommandSet::DummyByte}; + WindbondCommandSet::ReadStatusRegister1}; constexpr std::uint32_t address{0x10'00}; constexpr std::size_t ProgramPageCommandLength = 4; + constexpr const std::array pageProgramCommand{ WindbondCommandSet::PageProgram, - static_cast(address & 0x00'FF'00'00 >> 16), - static_cast(address & 0x00'00'FF'00 >> 8), + static_cast((address & 0x00'FF'00'00) >> 16), + static_cast((address & 0x00'00'FF'00) >> 8), static_cast(address & 0x00'00'00'FF)}; constexpr const std::array erase4KSectorCommand{ @@ -44,11 +44,9 @@ namespace Testing::Utils template constexpr std::span make_span(const TByteSequence& toSpan) { - return std::span( - reinterpret_cast(toSpan.data()), toSpan.size()); + return std::span(reinterpret_cast(toSpan.data()), toSpan.size()); } -} - +} // namespace Testing::Utils TEST_F(FlashDriverTest, RequestJedecId) { @@ -83,67 +81,82 @@ MATCHER_P(SpanChecker, spanItem, "Span content equals") TEST_F(FlashDriverTest, RequestWriteBlock) { - EXPECT_CALL(getMockGpio(), setGpioLow()).Times(2); - EXPECT_CALL(getMockGpio(), setGpioHigh()).Times(2); + EXPECT_CALL(getMockGpio(), setGpioLow()).Times(6); + EXPECT_CALL(getMockGpio(), setGpioHigh()).Times(6); auto TransmitData{std::array{0xEF, 0xFF, 0x18, 0x19, 0x20, 0x21, 0x22}}; - - testing::Sequence sequence; // https://gist.github.com/cppengineer/f1b6bc0f04ac7c29e963364f2c564a5e - const auto writeEnableSpan = Testing::Utils::make_span(Testing::FlashCommandStubs::writeEnableCommand); + const auto writeEnableSpan = + Testing::Utils::make_span(Testing::FlashCommandStubs::writeEnableCommand); TDataStream ExpectedStream{std::byte(0xEF), std::byte(0x40), std::byte(0x18)}; - + TDataStream kDummyByte{std::byte(0x00)}; EXPECT_CALL(spiMockAccess(), receivedData) - .Times(2) - .WillOnce(Return(Testing::Utils::make_span(ExpectedStream))); - - const auto ProgramCommandSpan = - Testing::Utils::make_span(Testing::FlashCommandStubs::pageProgramCommand); + .Times(3) + .WillOnce(Return(Testing::Utils::make_span(kDummyByte))); const auto kEraseSectorCommandSpan = Testing::Utils::make_span(Testing::FlashCommandStubs::erase4KSectorCommand); - EXPECT_CALL(spiMockAccess(), sentData) - .With(SpanChecker(kEraseSectorCommandSpan)) - .Times(1) - .InSequence(sequence); + auto fIsBusyChecker = [this, &sequence, kDummyByte] { + EXPECT_CALL(spiMockAccess(), sentData) + .With(SpanChecker(Testing::FlashCommandStubs::readStatusRegisterCommand)) + .Times(1) + .InSequence(sequence); - EXPECT_CALL(spiMockAccess(), sentData) - .With(SpanChecker(writeEnableSpan)) - .Times(1) - .InSequence(sequence); + EXPECT_CALL(spiMockAccess(), sentData) + .With(SpanChecker(Testing::Utils::make_span(kDummyByte))) + .Times(1) + .InSequence(sequence); + }; - EXPECT_CALL(spiMockAccess(), sentData) - .With(SpanChecker(Testing::FlashCommandStubs::readStatusRegisterCommand)) - .Times(1) - .InSequence(sequence); + { - EXPECT_CALL(spiMockAccess(), sentData) - .With(SpanChecker(ProgramCommandSpan)) - .Times(1) - .InSequence(sequence); - EXPECT_CALL(spiMockAccess(), sentData) - .With(SpanChecker(std::span(TransmitData.data(), TransmitData.size()))) - .Times(1) - .InSequence(sequence); + EXPECT_CALL(spiMockAccess(), sentData) + .With(SpanChecker(writeEnableSpan)) + .Times(1) + .InSequence(sequence); + fIsBusyChecker(); + } + + { + EXPECT_CALL(spiMockAccess(), sentData) + .With(SpanChecker(kEraseSectorCommandSpan)) + .Times(1) + .InSequence(sequence); + fIsBusyChecker(); + } + + { + + EXPECT_CALL(spiMockAccess(), sentData) + .With(SpanChecker(Testing::FlashCommandStubs::pageProgramCommand)) + .Times(1) + .InSequence(sequence); + + EXPECT_CALL(spiMockAccess(), sentData) + .With(SpanChecker(Testing::Utils::make_span(TransmitData))) + .Times(1) + .InSequence(sequence); + + fIsBusyChecker(); + } auto task = flashDriver.pageWrite( - Testing::FlashCommandStubs::address, - Testing::Utils::make_span(TransmitData)); + Testing::FlashCommandStubs::address, Testing::Utils::make_span(TransmitData)); CoroUtils::syncWait(task); } TEST_F(FlashDriverTest, RequestReadBlock) { - EXPECT_CALL(getMockGpio(), setGpioLow()).Times(1); - EXPECT_CALL(getMockGpio(), setGpioHigh()).Times(1); + EXPECT_CALL(getMockGpio(), setGpioLow()).Times(2); + EXPECT_CALL(getMockGpio(), setGpioHigh()).Times(2); using TStream = std::array; @@ -151,8 +164,10 @@ TEST_F(FlashDriverTest, RequestReadBlock) auto Dummy{TStream{}}; + TDataStream kDummyByte{std::byte(0x00)}; + EXPECT_CALL(spiMockAccess(), receivedData) - .Times(1) + .WillOnce(Return(Testing::Utils::make_span(kDummyByte))) .WillOnce(Return(std::span( reinterpret_cast(ReceiveData.data()), ReceiveData.size()))); @@ -173,17 +188,28 @@ TEST_F(FlashDriverTest, RequestReadBlock) const auto ReadDataSpan = std::span(readCommand.data(), readCommand.size()); + EXPECT_CALL(spiMockAccess(), sentData) + .With(SpanChecker(Testing::FlashCommandStubs::readStatusRegisterCommand)) + .Times(1) + .InSequence(sequence); + + EXPECT_CALL(spiMockAccess(), sentData) + .With(SpanChecker(Testing::Utils::make_span(kDummyByte))) + .Times(1) + .InSequence(sequence); + EXPECT_CALL(spiMockAccess(), sentData) .With(SpanChecker(ReadDataSpan)) .Times(1) .InSequence(sequence); + EXPECT_CALL(spiMockAccess(), sentData) .With(SpanChecker(std::span(DummySpan.data(), DummySpan.size()))) .Times(1) .InSequence(sequence); auto task = flashDriver.requestReadBlock(address, ReceiveData.size()); - auto readSpan = CoroUtils::syncWait(task); + auto readSpan{CoroUtils::syncWait(task)}; EXPECT_TRUE(std::ranges::equal(readSpan, ReceiveData)); } \ No newline at end of file From fbd73e53c83a0408fcc3348beb9066d4d621d3df Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Wed, 17 Aug 2022 11:33:13 +0300 Subject: [PATCH 53/54] [firmware][filesystem] added lfs_util_desktop.h for the firmware simulator configuration --- Firmware/3rdparty/littlefs_lib/CMakeLists.txt | 6 +- .../3rdparty/littlefs_lib/lfs_util_desktop.h | 236 ++++++++++++++++++ 2 files changed, 240 insertions(+), 2 deletions(-) create mode 100644 Firmware/3rdparty/littlefs_lib/lfs_util_desktop.h diff --git a/Firmware/3rdparty/littlefs_lib/CMakeLists.txt b/Firmware/3rdparty/littlefs_lib/CMakeLists.txt index bcb059d2..be3a0235 100644 --- a/Firmware/3rdparty/littlefs_lib/CMakeLists.txt +++ b/Firmware/3rdparty/littlefs_lib/CMakeLists.txt @@ -5,7 +5,7 @@ add_library(littlefs) target_sources(littlefs PRIVATE littlefs/lfs.cpp littlefs/lfs_util.cpp -) + "lfs_util_desktop.h") target_include_directories(littlefs PUBLIC littlefs ) @@ -35,7 +35,9 @@ target_compile_options( target_include_directories(littlefs PUBLIC ${CMAKE_CURRENT_LIST_DIR}) if( ${TARGET_PLATFORM} STREQUAL "ARM_CORTEX" ) - target_include_directories(littlefs PRIVATE ${CMAKE_CURRENT_LIST_DIR} ) target_precompile_headers(littlefs PRIVATE ${CMAKE_CURRENT_LIST_DIR}/lfs_util_segger.h) target_link_libraries(littlefs PRIVATE NordicSDK::Common) +elseif( ${TARGET_PLATFORM} STREQUAL "FIRMWARE_SIMULATOR") + target_precompile_headers(littlefs PRIVATE ${CMAKE_CURRENT_LIST_DIR}/lfs_util_desktop.h) + target_link_libraries(littlefs PUBLIC logger_service) endif() diff --git a/Firmware/3rdparty/littlefs_lib/lfs_util_desktop.h b/Firmware/3rdparty/littlefs_lib/lfs_util_desktop.h new file mode 100644 index 00000000..664d1c66 --- /dev/null +++ b/Firmware/3rdparty/littlefs_lib/lfs_util_desktop.h @@ -0,0 +1,236 @@ +/* + * lfs utility functions + * + * Copyright (c) 2017, Arm Limited. All rights reserved. + * SPDX-License-Identifier: BSD-3-Clause + */ +#ifndef LFS_UTIL_H +#define LFS_UTIL_H + +// Users can override lfs_util.h with their own configuration by defining +// LFS_CONFIG as a header file to include (-DLFS_CONFIG=lfs_config.h). +// +// If LFS_CONFIG is used, none of the default utils will be emitted and must be +// provided by the config file. To start, I would suggest copying lfs_util.h +// and modifying as needed. +#ifdef LFS_CONFIG +#define LFS_STRINGIZE(x) LFS_STRINGIZE2(x) +#define LFS_STRINGIZE2(x) #x +#include LFS_STRINGIZE(LFS_CONFIG) +#else + +// System includes +#include +#include +#include +#include +#include +#ifndef LFS_NO_MALLOC +#include +#endif +#ifndef LFS_NO_ASSERT +#include +#endif +#if !defined(LFS_NO_DEBUG) || \ + !defined(LFS_NO_WARN) || \ + !defined(LFS_NO_ERROR) || \ + defined(LFS_YES_TRACE) +#include +#endif + +#ifdef __cplusplus +extern "C" +{ +#endif + + +// Macros, may be replaced by system specific wrappers. Arguments to these +// macros must not have side-effects as the macros can be removed for a smaller +// code footprint + +// Logging functions +#ifndef LFS_TRACE +#ifdef LFS_YES_TRACE +#define LFS_TRACE(fmt,...) printf("%s:%d:trace: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__, "") +#else +#define LFS_TRACE(...) +#endif +#endif + +#ifndef LFS_DEBUG +#ifndef LFS_NO_DEBUG +#define LFS_DEBUG(fmt,...) printf("%s:%d:debug: " fmt "%s\n", __VA_ARGS__, "") +#else +#define LFS_DEBUG(...) +#endif +#endif + +#ifndef LFS_WARN +#ifndef LFS_NO_WARN +#define LFS_WARN(fmt,...) printf("%s:%d:warn: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__, "") +#else +#define LFS_WARN(...) +#endif +#endif + +#ifndef LFS_ERROR +#ifndef LFS_NO_ERROR +#define LFS_ERROR(fmt,...) printf("%s:%d:error: " fmt "%s\n", __FILE__, __LINE__, __VA_ARGS__, "") +#else +#define LFS_ERROR(...) +#endif +#endif + +// Runtime assertions +#ifndef LFS_ASSERT +#ifndef LFS_NO_ASSERT +#define LFS_ASSERT(test) assert(test) +#else +#define LFS_ASSERT(test) +#endif +#endif + + +// Builtin functions, these may be replaced by more efficient +// toolchain-specific implementations. LFS_NO_INTRINSICS falls back to a more +// expensive basic C implementation for debugging purposes + +// Min/max functions for unsigned 32-bit numbers +static inline uint32_t lfs_max(uint32_t a, uint32_t b) { + return (a > b) ? a : b; +} + +static inline uint32_t lfs_min(uint32_t a, uint32_t b) { + return (a < b) ? a : b; +} + +// Align to nearest multiple of a size +static inline uint32_t lfs_aligndown(uint32_t a, uint32_t alignment) { + return a - (a % alignment); +} + +static inline uint32_t lfs_alignup(uint32_t a, uint32_t alignment) { + return lfs_aligndown(a + alignment-1, alignment); +} + +// Find the smallest power of 2 greater than or equal to a +static inline uint32_t lfs_npw2(uint32_t a) { +#if !defined(LFS_NO_INTRINSICS) && (defined(__GNUC__) || defined(__CC_ARM)) + return 32 - __builtin_clz(a-1); +#else + uint32_t r = 0; + uint32_t s; + a -= 1; + s = (a > 0xffff) << 4; a >>= s; r |= s; + s = (a > 0xff ) << 3; a >>= s; r |= s; + s = (a > 0xf ) << 2; a >>= s; r |= s; + s = (a > 0x3 ) << 1; a >>= s; r |= s; + return (r | (a >> 1)) + 1; +#endif +} + +// Count the number of trailing binary zeros in a +// lfs_ctz(0) may be undefined +static inline uint32_t lfs_ctz(uint32_t a) { +#if !defined(LFS_NO_INTRINSICS) && defined(__GNUC__) + return __builtin_ctz(a); +#else + return lfs_npw2((a & -a) + 1) - 1; +#endif +} + +// Count the number of binary ones in a +static inline uint32_t lfs_popc(uint32_t a) { +#if !defined(LFS_NO_INTRINSICS) && (defined(__GNUC__) || defined(__CC_ARM)) + return __builtin_popcount(a); +#else + a = a - ((a >> 1) & 0x55555555); + a = (a & 0x33333333) + ((a >> 2) & 0x33333333); + return (((a + (a >> 4)) & 0xf0f0f0f) * 0x1010101) >> 24; +#endif +} + +// Find the sequence comparison of a and b, this is the distance +// between a and b ignoring overflow +static inline int lfs_scmp(uint32_t a, uint32_t b) { + return (int)(unsigned)(a - b); +} + +// Convert between 32-bit little-endian and native order +static inline uint32_t lfs_fromle32(uint32_t a) { +#if !defined(LFS_NO_INTRINSICS) && ( \ + (defined( BYTE_ORDER ) && defined( ORDER_LITTLE_ENDIAN ) && BYTE_ORDER == ORDER_LITTLE_ENDIAN ) || \ + (defined(__BYTE_ORDER ) && defined(__ORDER_LITTLE_ENDIAN ) && __BYTE_ORDER == __ORDER_LITTLE_ENDIAN ) || \ + (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) + return a; +#elif !defined(LFS_NO_INTRINSICS) && ( \ + (defined( BYTE_ORDER ) && defined( ORDER_BIG_ENDIAN ) && BYTE_ORDER == ORDER_BIG_ENDIAN ) || \ + (defined(__BYTE_ORDER ) && defined(__ORDER_BIG_ENDIAN ) && __BYTE_ORDER == __ORDER_BIG_ENDIAN ) || \ + (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) + return __builtin_bswap32(a); +#else + return (((uint8_t*)&a)[0] << 0) | + (((uint8_t*)&a)[1] << 8) | + (((uint8_t*)&a)[2] << 16) | + (((uint8_t*)&a)[3] << 24); +#endif +} + +static inline uint32_t lfs_tole32(uint32_t a) { + return lfs_fromle32(a); +} + +// Convert between 32-bit big-endian and native order +static inline uint32_t lfs_frombe32(uint32_t a) { +#if !defined(LFS_NO_INTRINSICS) && ( \ + (defined( BYTE_ORDER ) && defined( ORDER_LITTLE_ENDIAN ) && BYTE_ORDER == ORDER_LITTLE_ENDIAN ) || \ + (defined(__BYTE_ORDER ) && defined(__ORDER_LITTLE_ENDIAN ) && __BYTE_ORDER == __ORDER_LITTLE_ENDIAN ) || \ + (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)) + return __builtin_bswap32(a); +#elif !defined(LFS_NO_INTRINSICS) && ( \ + (defined( BYTE_ORDER ) && defined( ORDER_BIG_ENDIAN ) && BYTE_ORDER == ORDER_BIG_ENDIAN ) || \ + (defined(__BYTE_ORDER ) && defined(__ORDER_BIG_ENDIAN ) && __BYTE_ORDER == __ORDER_BIG_ENDIAN ) || \ + (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)) + return a; +#else + return (((uint8_t*)&a)[0] << 24) | + (((uint8_t*)&a)[1] << 16) | + (((uint8_t*)&a)[2] << 8) | + (((uint8_t*)&a)[3] << 0); +#endif +} + +static inline uint32_t lfs_tobe32(uint32_t a) { + return lfs_frombe32(a); +} + +// Calculate CRC-32 with polynomial = 0x04c11db7 +uint32_t lfs_crc(uint32_t crc, const void *buffer, size_t size); + +// Allocate memory, only used if buffers are not provided to littlefs +// Note, memory must be 64-bit aligned +static inline void *lfs_malloc(size_t size) { +#ifndef LFS_NO_MALLOC + return malloc(size); +#else + (void)size; + return NULL; +#endif +} + +// Deallocate memory, only used if buffers are not provided to littlefs +static inline void lfs_free(void *p) { +#ifndef LFS_NO_MALLOC + free(p); +#else + (void)p; +#endif +} + + +#ifdef __cplusplus +} /* extern "C" */ +#endif + +#endif +#endif From d6edf6cca71a95e1675d9d7c7bc2e8b05d853d02 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko Date: Wed, 17 Aug 2022 11:33:46 +0300 Subject: [PATCH 54/54] [firmware][graphics] increased LV_HEAP_SIZE to 18KB --- Firmware/graphics/lvgl_lib/lvgl_library/lv_conf.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Firmware/graphics/lvgl_lib/lvgl_library/lv_conf.h b/Firmware/graphics/lvgl_lib/lvgl_library/lv_conf.h index ad79f40d..98ab177a 100644 --- a/Firmware/graphics/lvgl_lib/lvgl_library/lv_conf.h +++ b/Firmware/graphics/lvgl_lib/lvgl_library/lv_conf.h @@ -48,7 +48,7 @@ #define LV_MEM_CUSTOM 0 #if LV_MEM_CUSTOM == 0 /*Size of the memory available for `lv_mem_alloc()` in bytes (>= 2kB)*/ -# define LV_MEM_SIZE (17U * 1024U) /*[bytes]*/ +# define LV_MEM_SIZE (18U * 1024U) /*[bytes]*/ /*Set an address for the memory pool instead of allocating it as a normal array. Can be in external SRAM too.*/ # define LV_MEM_ADR 0 /*0: unused*/