-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Using littlefs #438
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Using littlefs #438
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
659f84c
add submodule littlefs
joaquimorg e7e783f
base fs
joaquimorg ea1d09e
Merge branch 'develop' of
joaquimorg d81fd2c
Save settings using littlefs
joaquimorg 2985d00
Merge branch 'develop' of https://github.com/JF002/InfiniTime into li…
joaquimorg 982f2b9
Small fixes and suggestions from PR
joaquimorg 2814b28
Merge branch 'develop' of https://github.com/JF002/InfiniTime into li…
joaquimorg 3b4de93
More small fixes from PR suggestions
joaquimorg 787ccae
Code clean up
joaquimorg 6f9ec98
Merge branch 'develop' of https://github.com/JF002/InfiniTime into li…
joaquimorg 1e34523
Change SpiNorFlash functions to be private in FS
joaquimorg File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,6 @@ | ||
| [submodule "src/libs/lvgl"] | ||
| path = src/libs/lvgl | ||
| url = https://github.com/joaquimorg/lvgl.git | ||
| [submodule "src/libs/littlefs"] | ||
| path = src/libs/littlefs | ||
| url = https://github.com/littlefs-project/littlefs.git |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,197 @@ | ||
| #include "FS.h" | ||
| #include <cstring> | ||
| #include <littlefs/lfs.h> | ||
| #include <lvgl/lvgl.h> | ||
|
|
||
| using namespace Pinetime::Controllers; | ||
|
|
||
| FS::FS(Pinetime::Drivers::SpiNorFlash& driver) : | ||
| flashDriver{ driver }, | ||
| lfsConfig{ | ||
| .context = this, | ||
| .read = SectorRead, | ||
| .prog = SectorProg, | ||
| .erase = SectorErase, | ||
| .sync = SectorSync, | ||
|
|
||
| .read_size = 16, | ||
| .prog_size = 8, | ||
| .block_size = blockSize, | ||
| .block_count = size / blockSize, | ||
| .block_cycles = 1000u, | ||
|
|
||
| .cache_size = 16, | ||
| .lookahead_size = 16, | ||
|
|
||
| .name_max = 50, | ||
| .attr_max = 50, | ||
| } | ||
| { } | ||
|
|
||
|
|
||
| void FS::Init() { | ||
|
|
||
| // try mount | ||
| int err = lfs_mount(&lfs, &lfsConfig); | ||
|
|
||
| // reformat if we can't mount the filesystem | ||
| // this should only happen on the first boot | ||
| if (err != LFS_ERR_OK) { | ||
| lfs_format(&lfs, &lfsConfig); | ||
| err = lfs_mount(&lfs, &lfsConfig); | ||
| if (err != LFS_ERR_OK) { | ||
| return; | ||
| } | ||
| } | ||
|
|
||
| #ifndef PINETIME_IS_RECOVERY | ||
| VerifyResource(); | ||
| LVGLFileSystemInit(); | ||
| #endif | ||
|
|
||
| } | ||
|
|
||
| void FS::VerifyResource() { | ||
| // validate the resource metadata | ||
| resourcesValid = true; | ||
| } | ||
|
|
||
| int FS::FileOpen(lfs_file_t* file_p, const char* fileName, const int flags) { | ||
| return lfs_file_open(&lfs, file_p, fileName, flags); | ||
| } | ||
|
|
||
| int FS::FileClose(lfs_file_t* file_p) { | ||
| return lfs_file_close(&lfs, file_p); | ||
| } | ||
|
|
||
| int FS::FileRead(lfs_file_t* file_p, uint8_t* buff, uint32_t size) { | ||
| return lfs_file_read(&lfs, file_p, buff, size); | ||
| } | ||
|
|
||
| int FS::FileWrite(lfs_file_t* file_p, const uint8_t* buff, uint32_t size) { | ||
| return lfs_file_write(&lfs, file_p, buff, size); | ||
| } | ||
|
|
||
| int FS::FileSeek(lfs_file_t* file_p, uint32_t pos) { | ||
| return lfs_file_seek(&lfs, file_p, pos, LFS_SEEK_SET); | ||
| } | ||
|
|
||
| int FS::FileDelete(const char* fileName) { | ||
| return lfs_remove(&lfs, fileName); | ||
| } | ||
|
|
||
|
|
||
| int FS::DirCreate(const char* path) { | ||
| return lfs_mkdir(&lfs, path); | ||
| } | ||
|
|
||
| // Delete directory and all files inside | ||
| int FS::DirDelete(const char* path) { | ||
|
|
||
| lfs_dir_t lfs_dir; | ||
| lfs_info entryInfo; | ||
|
|
||
| int err; | ||
| err = lfs_dir_open(&lfs, &lfs_dir, path); | ||
| if (err) { | ||
| return err; | ||
| } | ||
| while (lfs_dir_read(&lfs, &lfs_dir, &entryInfo)) { | ||
| lfs_remove(&lfs, entryInfo.name); | ||
| } | ||
| lfs_dir_close(&lfs, &lfs_dir); | ||
| return LFS_ERR_OK; | ||
| } | ||
|
|
||
| /* | ||
|
|
||
| ----------- Interface between littlefs and SpiNorFlash ----------- | ||
|
|
||
| */ | ||
| int FS::SectorSync(const struct lfs_config* c) { | ||
| return 0; | ||
| } | ||
|
|
||
| int FS::SectorErase(const struct lfs_config* c, lfs_block_t block) { | ||
| Pinetime::Controllers::FS& lfs = *(static_cast<Pinetime::Controllers::FS*>(c->context)); | ||
| const size_t address = startAddress + (block * blockSize); | ||
| lfs.flashDriver.SectorErase(address); | ||
| return lfs.flashDriver.EraseFailed() ? -1 : 0; | ||
| } | ||
|
|
||
| int FS::SectorProg(const struct lfs_config* c, lfs_block_t block, lfs_off_t off, const void* buffer, lfs_size_t size) { | ||
| Pinetime::Controllers::FS& lfs = *(static_cast<Pinetime::Controllers::FS*>(c->context)); | ||
| const size_t address = startAddress + (block * blockSize) + off; | ||
| lfs.flashDriver.Write(address, (uint8_t*) buffer, size); | ||
| return lfs.flashDriver.ProgramFailed() ? -1 : 0; | ||
| } | ||
|
|
||
| int FS::SectorRead(const struct lfs_config* c, lfs_block_t block, lfs_off_t off, void* buffer, lfs_size_t size) { | ||
| Pinetime::Controllers::FS& lfs = *(static_cast<Pinetime::Controllers::FS*>(c->context)); | ||
| const size_t address = startAddress + (block * blockSize) + off; | ||
| lfs.flashDriver.Read(address, static_cast<uint8_t*>(buffer), size); | ||
| return 0; | ||
| } | ||
|
|
||
| /* | ||
|
|
||
| ----------- LVGL filesystem integration ----------- | ||
|
|
||
| */ | ||
|
|
||
| namespace { | ||
| lv_fs_res_t lvglOpen(lv_fs_drv_t* drv, void* file_p, const char* path, lv_fs_mode_t mode) { | ||
|
|
||
| lfs_file_t* file = static_cast<lfs_file_t*>(file_p); | ||
| FS* filesys = static_cast<FS*>(drv->user_data); | ||
| filesys->FileOpen(file, path, LFS_O_RDONLY); | ||
|
|
||
| if (file->type == 0) { | ||
| return LV_FS_RES_FS_ERR; | ||
| } | ||
| else { | ||
| return LV_FS_RES_OK; | ||
| } | ||
| } | ||
|
|
||
| lv_fs_res_t lvglClose(lv_fs_drv_t* drv, void* file_p) { | ||
| FS* filesys = static_cast<FS*>(drv->user_data); | ||
| lfs_file_t* file = static_cast<lfs_file_t*>(file_p); | ||
| filesys->FileClose(file); | ||
|
|
||
| return LV_FS_RES_OK; | ||
| } | ||
|
|
||
| lv_fs_res_t lvglRead(lv_fs_drv_t* drv, void* file_p, void* buf, uint32_t btr, uint32_t* br) { | ||
| FS* filesys = static_cast<FS*>(drv->user_data); | ||
| lfs_file_t* file = static_cast<lfs_file_t*>(file_p); | ||
| filesys->FileRead(file, static_cast<uint8_t*>(buf), btr); | ||
| *br = btr; | ||
| return LV_FS_RES_OK; | ||
| } | ||
|
|
||
| lv_fs_res_t lvglSeek(lv_fs_drv_t* drv, void* file_p, uint32_t pos) { | ||
| FS* filesys = static_cast<FS*>(drv->user_data); | ||
| lfs_file_t* file = static_cast<lfs_file_t*>(file_p); | ||
| filesys->FileSeek(file, pos); | ||
| return LV_FS_RES_OK; | ||
| } | ||
| } | ||
|
|
||
| void FS::LVGLFileSystemInit() { | ||
|
|
||
| lv_fs_drv_t fs_drv; | ||
| lv_fs_drv_init(&fs_drv); | ||
|
|
||
| fs_drv.file_size = sizeof(lfs_file_t); | ||
| fs_drv.letter = 'F'; | ||
| fs_drv.open_cb = lvglOpen; | ||
| fs_drv.close_cb = lvglClose; | ||
| fs_drv.read_cb = lvglRead; | ||
| fs_drv.seek_cb = lvglSeek; | ||
|
|
||
| fs_drv.user_data = this; | ||
|
|
||
| lv_fs_drv_register(&fs_drv); | ||
|
|
||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,71 @@ | ||
| #pragma once | ||
|
|
||
| #include <cstdint> | ||
| #include "drivers/SpiNorFlash.h" | ||
| #include <littlefs/lfs.h> | ||
|
|
||
| namespace Pinetime { | ||
| namespace Controllers { | ||
| class FS { | ||
| public: | ||
| FS(Pinetime::Drivers::SpiNorFlash&); | ||
|
|
||
| void Init(); | ||
| void LVGLFileSystemInit(); | ||
|
|
||
| int FileOpen(lfs_file_t* file_p, const char* fileName, const int flags); | ||
| int FileClose(lfs_file_t* file_p); | ||
| int FileRead(lfs_file_t* file_p, uint8_t* buff, uint32_t size); | ||
| int FileWrite(lfs_file_t* file_p, const uint8_t* buff, uint32_t size); | ||
| int FileSeek(lfs_file_t* file_p, uint32_t pos); | ||
|
|
||
| int FileDelete(const char* fileName); | ||
|
|
||
| int DirCreate(const char* path); | ||
| int DirDelete(const char* path); | ||
|
|
||
| void VerifyResource(); | ||
|
|
||
| private: | ||
|
|
||
| Pinetime::Drivers::SpiNorFlash& flashDriver; | ||
|
|
||
| /* | ||
| * External Flash MAP (4 MBytes) | ||
| * | ||
| * 0x000000 +---------------------------------------+ | ||
| * | Bootloader Assets | | ||
| * | 256 KBytes | | ||
| * | | | ||
| * 0x040000 +---------------------------------------+ | ||
| * | OTA | | ||
| * | 464 KBytes | | ||
| * | | | ||
| * | | | ||
| * | | | ||
| * 0x0B4000 +---------------------------------------+ | ||
| * | File System | | ||
| * | | | ||
| * | | | ||
| * | | | ||
| * | | | ||
| * 0x400000 +---------------------------------------+ | ||
| * | ||
| */ | ||
| static constexpr size_t startAddress = 0x0B4000; | ||
| static constexpr size_t size = 0x3C0000; | ||
| static constexpr size_t blockSize = 4096; | ||
|
|
||
| bool resourcesValid = false; | ||
| const struct lfs_config lfsConfig; | ||
|
|
||
| lfs_t lfs; | ||
|
|
||
| static int SectorSync(const struct lfs_config* c); | ||
| static int SectorErase(const struct lfs_config* c, lfs_block_t block); | ||
| static int SectorProg(const struct lfs_config* c, lfs_block_t block, lfs_off_t off, const void* buffer, lfs_size_t size); | ||
| static int SectorRead(const struct lfs_config* c, lfs_block_t block, lfs_off_t off, void* buffer, lfs_size_t size); | ||
|
|
||
| }; | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.