From 6ba293860c200fbf1d2c4f4fa5ac239503444f11 Mon Sep 17 00:00:00 2001 From: "Luigi F. Cruz" Date: Sat, 28 Jan 2023 15:04:43 -0800 Subject: [PATCH] Add littlefs lib and example. --- apps/CMakeLists.txt | 3 +- apps/filesystem/CMakeLists.txt | 14 ++++++ apps/filesystem/test.c | 85 ++++++++++++++++++++++++++++++++++ lib/CMakeLists.txt | 1 + lib/littlefs/CMakeLists.txt | 14 ++++++ lib/littlefs/lfs_rp2040.c | 30 ++++++++++++ lib/littlefs/lfs_rp2040.h | 28 +++++++++++ 7 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 apps/filesystem/CMakeLists.txt create mode 100644 apps/filesystem/test.c create mode 100644 lib/littlefs/CMakeLists.txt create mode 100644 lib/littlefs/lfs_rp2040.c create mode 100644 lib/littlefs/lfs_rp2040.h diff --git a/apps/CMakeLists.txt b/apps/CMakeLists.txt index 25da388..ba776dd 100644 --- a/apps/CMakeLists.txt +++ b/apps/CMakeLists.txt @@ -2,4 +2,5 @@ add_subdirectory(tcp_server) add_subdirectory(adc_dma_chain) add_subdirectory(piccolosdr) -add_subdirectory(barometer) \ No newline at end of file +add_subdirectory(barometer) +add_subdirectory(filesystem) \ No newline at end of file diff --git a/apps/filesystem/CMakeLists.txt b/apps/filesystem/CMakeLists.txt new file mode 100644 index 0000000..3582ba1 --- /dev/null +++ b/apps/filesystem/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.12) + +project(pico-filesystem) + +add_executable(filesystem test.c) + +target_link_libraries(filesystem LINK_PUBLIC littlefs) + +pico_add_extra_outputs(filesystem) + +pico_enable_stdio_usb(filesystem 1) +pico_enable_stdio_uart(filesystem 0) + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) \ No newline at end of file diff --git a/apps/filesystem/test.c b/apps/filesystem/test.c new file mode 100644 index 0000000..26cbea1 --- /dev/null +++ b/apps/filesystem/test.c @@ -0,0 +1,85 @@ +#include +#include + +#include "hardware/flash.h" +#include "pico/stdio.h" +#include "pico/stdlib.h" + +#include +#include + +// variables used by the filesystem +lfs_t lfs; +lfs_file_t file; + +// configuration of the filesystem is provided by this struct +const struct lfs_config cfg = { + // block device operations + .read = lfs_rp2040_read, + .prog = lfs_rp2040_prog, + .erase = lfs_rp2040_erase, + .sync = lfs_rp2040_sync, + + // block device configuration + .read_size = FLASH_PAGE_SIZE, + .prog_size = FLASH_PAGE_SIZE, + .block_size = FLASH_SECTOR_SIZE, + .block_count = 128, + .cache_size = FLASH_PAGE_SIZE, + + .lookahead_size = 16, + .block_cycles = 500, +}; + +uint storage_get_flash_capacity() { + uint8_t rxbuf[4]; + uint8_t txbuf[] = {0x9f}; + flash_do_cmd(txbuf, rxbuf, 4); + return 1 << rxbuf[3]; +} + +// entry point +int main(void) { + stdio_init_all(); + + while (getchar_timeout_us(0) != 'X') { + sleep_ms(10); + } + + printf("%d\n", storage_get_flash_capacity()); + + printf("Hello from Pi Pico!\n"); + + // mount the filesystem + int err = lfs_mount(&lfs, &cfg); + + printf("%d\n\n", err); + + return 0; + + // reformat if we can't mount the filesystem + // this should only happen on the first boot + if (err) { + lfs_format(&lfs, &cfg); + lfs_mount(&lfs, &cfg); + } + + // read current count + uint32_t boot_count = 0; + lfs_file_open(&lfs, &file, "boot_count", LFS_O_RDWR | LFS_O_CREAT); + lfs_file_read(&lfs, &file, &boot_count, sizeof(boot_count)); + + // update boot count + boot_count += 1; + lfs_file_rewind(&lfs, &file); + lfs_file_write(&lfs, &file, &boot_count, sizeof(boot_count)); + + // remember the storage is not updated until the file is closed successfully + lfs_file_close(&lfs, &file); + + // release any resources we were using + lfs_unmount(&lfs); + + // print the boot count + printf("boot_count: %d\n", boot_count); +} diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index cf23198..f9cce72 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -1,3 +1,4 @@ add_subdirectory(bmp180) add_subdirectory(bmp390) add_subdirectory(usb_network_stack) +add_subdirectory(littlefs) diff --git a/lib/littlefs/CMakeLists.txt b/lib/littlefs/CMakeLists.txt new file mode 100644 index 0000000..35d4758 --- /dev/null +++ b/lib/littlefs/CMakeLists.txt @@ -0,0 +1,14 @@ +cmake_minimum_required(VERSION 3.12) + +add_library(littlefs ./lfs_rp2040.c + ./littlefs/lfs.c + ./littlefs/lfs_util.c) + +target_link_libraries(littlefs + pico_stdlib + pico_stdio + hardware_flash +) + +target_include_directories(littlefs PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/littlefs) \ No newline at end of file diff --git a/lib/littlefs/lfs_rp2040.c b/lib/littlefs/lfs_rp2040.c new file mode 100644 index 0000000..7eedf1e --- /dev/null +++ b/lib/littlefs/lfs_rp2040.c @@ -0,0 +1,30 @@ +#include "lfs_rp2040.h" + +// Read a region in a block. Negative error codes are propagated +// to the user. +int lfs_rp2040_read(const struct lfs_config *c, lfs_block_t block, + lfs_off_t off, void *buffer, lfs_size_t size) { + return 0; +} + +// Program a region in a block. The block must have previously +// been erased. Negative error codes are propagated to the user. +// May return LFS_ERR_CORRUPT if the block should be considered bad. +int lfs_rp2040_prog(const struct lfs_config *c, lfs_block_t block, + lfs_off_t off, const void *buffer, lfs_size_t size) { + return 0; +} + +// Erase a block. A block must be erased before being programmed. +// The state of an erased block is undefined. Negative error codes +// are propagated to the user. +// May return LFS_ERR_CORRUPT if the block should be considered bad. +int lfs_rp2040_erase(const struct lfs_config *c, lfs_block_t block) { + return 0; +} + +// Sync the state of the underlying block device. Negative error codes +// are propagated to the user. +int lfs_rp2040_sync(const struct lfs_config *c) { + return 0; +} \ No newline at end of file diff --git a/lib/littlefs/lfs_rp2040.h b/lib/littlefs/lfs_rp2040.h new file mode 100644 index 0000000..6aa4c29 --- /dev/null +++ b/lib/littlefs/lfs_rp2040.h @@ -0,0 +1,28 @@ +#ifndef LFS_RP2040_H +#define LFS_RP2040_H + +#include +#include + +// Read a region in a block. Negative error codes are propagated +// to the user. +int lfs_rp2040_read(const struct lfs_config *c, lfs_block_t block, + lfs_off_t off, void *buffer, lfs_size_t size); + +// Program a region in a block. The block must have previously +// been erased. Negative error codes are propagated to the user. +// May return LFS_ERR_CORRUPT if the block should be considered bad. +int lfs_rp2040_prog(const struct lfs_config *c, lfs_block_t block, + lfs_off_t off, const void *buffer, lfs_size_t size); + +// Erase a block. A block must be erased before being programmed. +// The state of an erased block is undefined. Negative error codes +// are propagated to the user. +// May return LFS_ERR_CORRUPT if the block should be considered bad. +int lfs_rp2040_erase(const struct lfs_config *c, lfs_block_t block); + +// Sync the state of the underlying block device. Negative error codes +// are propagated to the user. +int lfs_rp2040_sync(const struct lfs_config *c); + +#endif \ No newline at end of file