diff --git a/README.md b/README.md index 645dfc367..db770f0d2 100644 --- a/README.md +++ b/README.md @@ -18,7 +18,8 @@ Please add your name to the list below in your first Pull Request! * Kale F. * Marko V. * Vaibhav K. -* Muhammad Ali. +* Muhammad Ali +* Saksham P. * Alex O. * Fardin M. diff --git a/firmware/Core/Inc/config/static_config.h b/firmware/Core/Inc/config/static_config.h index 51dfeb119..a971228a9 100644 --- a/firmware/Core/Inc/config/static_config.h +++ b/firmware/Core/Inc/config/static_config.h @@ -8,8 +8,4 @@ /// Default: 0 (disabled) static const uint8_t FLASH_enable_hot_path_debug_logs = 0; -/// Whether to enable hot-path debug success logging in the LittleFS drivers. -/// Default: 0 (disabled) -static const uint8_t LFS_enable_hot_path_debug_logs = 0; - #endif /* __INCLUDE_GUARD__STATIC_CONFIG_H__ */ diff --git a/firmware/Core/Inc/littlefs/littlefs_helper.h b/firmware/Core/Inc/littlefs/littlefs_helper.h index 26caca3f0..8874e6e6b 100644 --- a/firmware/Core/Inc/littlefs/littlefs_helper.h +++ b/firmware/Core/Inc/littlefs/littlefs_helper.h @@ -24,9 +24,9 @@ extern uint8_t LFS_is_lfs_mounted; int8_t LFS_format(); int8_t LFS_mount(); int8_t LFS_unmount(); -int8_t LFS_list_directory(const char root_directory[]); -int8_t LFS_delete_file(const char file_name[]); +int8_t LFS_list_directory(const char root_directory[], uint16_t offset, int16_t count); int8_t LFS_make_directory(const char dir_name[]); +int8_t LFS_delete_file(const char file_name[]); int8_t LFS_write_file(const char file_name[], uint8_t *write_buffer, uint32_t write_buffer_len); int8_t LFS_append_file(const char file_name[], uint8_t *write_buffer, uint32_t write_buffer_len); lfs_ssize_t LFS_read_file(const char file_name[], lfs_soff_t offset, uint8_t *read_buffer, uint32_t read_buffer_len); diff --git a/firmware/Core/Inc/telecommands/lfs_telecommand_defs.h b/firmware/Core/Inc/telecommands/lfs_telecommand_defs.h index cc0cdf810..cb0342046 100644 --- a/firmware/Core/Inc/telecommands/lfs_telecommand_defs.h +++ b/firmware/Core/Inc/telecommands/lfs_telecommand_defs.h @@ -14,6 +14,12 @@ uint8_t TCMDEXEC_fs_mount(const char *args_str, TCMD_TelecommandChannel_enum_t t uint8_t TCMDEXEC_fs_unmount(const char *args_str, TCMD_TelecommandChannel_enum_t tcmd_channel, char *response_output_buf, uint16_t response_output_buf_len); +uint8_t TCMDEXEC_fs_list_directory(const char *args_str, TCMD_TelecommandChannel_enum_t tcmd_channel, + char *response_output_buf, uint16_t response_output_buf_len); + +uint8_t TCMDEXEC_fs_make_directory(const char *args_str, TCMD_TelecommandChannel_enum_t tcmd_channel, + char *response_output_buf, uint16_t response_output_buf_len); + uint8_t TCMDEXEC_fs_write_file(const char *args_str, TCMD_TelecommandChannel_enum_t tcmd_channel, char *response_output_buf, uint16_t response_output_buf_len); diff --git a/firmware/Core/Src/littlefs/littlefs_helper.c b/firmware/Core/Src/littlefs/littlefs_helper.c index cca4483aa..93b556a7c 100644 --- a/firmware/Core/Src/littlefs/littlefs_helper.c +++ b/firmware/Core/Src/littlefs/littlefs_helper.c @@ -1,13 +1,9 @@ - - /*-----------------------------INCLUDES-----------------------------*/ #include #include "littlefs/littlefs_helper.h" #include "littlefs/lfs.h" #include "littlefs/littlefs_driver.h" -#include "debug_tools/debug_uart.h" -#include "config/static_config.h" #include "log/log.h" /*-----------------------------VARIABLES-----------------------------*/ @@ -39,7 +35,7 @@ struct lfs_config LFS_cfg = { // block device configuration .read_size = FLASH_CHIP_PAGE_SIZE_BYTES, .prog_size = FLASH_CHIP_PAGE_SIZE_BYTES, - .block_size = FLASH_CHIP_BLOCK_SIZE_BYTES, // FIXME: Clarify block Size 256KiB or 1KiB + .block_size = FLASH_CHIP_BLOCK_SIZE_BYTES, .block_count = (FLASH_CHIP_SIZE_BYTES / FLASH_CHIP_BLOCK_SIZE_BYTES), .block_cycles = 100, // TODO: ASK ABOUT THIS (HOW FREQUENT ARE WE USING THE MODULE), .cache_size = FLASH_CHIP_PAGE_SIZE_BYTES, @@ -57,7 +53,6 @@ struct lfs_file_config LFS_file_cfg = { // -----------------------------LITTLEFS FUNCTIONS----------------------------- - /** * @brief Formats Memory Module so it can successfully mount LittleFS * @param None @@ -65,15 +60,14 @@ struct lfs_file_config LFS_file_cfg = { */ int8_t LFS_format() { - int8_t result = lfs_format(&LFS_filesystem, &LFS_cfg); - if (result < 0) - { - DEBUG_uart_print_str("Error formatting!\n"); - return result; - } - - DEBUG_uart_print_str("Formatting successful!\n"); - return 0; + int8_t format_result = lfs_format(&LFS_filesystem, &LFS_cfg); + if (format_result < 0) { + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "Error formatting FLASH memory!"); + return format_result; + } + + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_NORMAL, LOG_all_sinks_except(LOG_SINK_FILE), "LittleFS Memory formatting successful!"); + return 0; } /** @@ -83,20 +77,20 @@ int8_t LFS_format() */ int8_t LFS_mount() { - if (LFS_is_lfs_mounted) { - DEBUG_uart_print_str("LittleFS already mounted!\n"); - return 1; - } + if (LFS_is_lfs_mounted) { + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_WARNING, LOG_all_sinks_except(LOG_SINK_FILE), "LittleFS already mounted!"); + return 1; + } // Variable to store status of LittleFS mounting int8_t mount_result = lfs_mount(&LFS_filesystem, &LFS_cfg); - if (mount_result < 0) - { - DEBUG_uart_print_str("Mounting unsuccessful\n"); + if (mount_result < 0) { + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "Error mounting LittleFS!"); return mount_result; } - DEBUG_uart_print_str("Mounting successful\n"); + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_NORMAL, LOG_all_sinks_except(LOG_SINK_FILE), "LittleFS mounting successful!"); + LFS_is_lfs_mounted = 1; return 0; } @@ -108,9 +102,8 @@ int8_t LFS_mount() */ int8_t LFS_unmount() { - if (!LFS_is_lfs_mounted) - { - DEBUG_uart_print_str("LittleFS not mounted.\n"); + if (!LFS_is_lfs_mounted) { + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "LittleFS not mounted!"); return 1; } @@ -118,116 +111,142 @@ int8_t LFS_unmount() const int8_t unmount_result = lfs_unmount(&LFS_filesystem); if (unmount_result < 0) { - DEBUG_uart_print_str("Error un-mounting.\n"); + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "Error un-mounting LittleFS!"); return unmount_result; } - DEBUG_uart_print_str("Successfully un-mounted LittleFS.\n"); + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_NORMAL, LOG_all_sinks_except(LOG_SINK_FILE), "LittleFS un-mounting successful!"); LFS_is_lfs_mounted = 0; return 0; } /** * @brief Lists contents of LittleFS Directory - * @param root_directory Pointer to cstring holding the root directory to open and read + * @param root_directory cstring holding the root directory to open and read + * @param offset Number of entries to skip before listing directory + * @param count Number of entries to list in total (if 0, prints all entries) * @retval 0 on success, 1 if LFS is unmounted, negative LFS error codes on failure */ -int8_t LFS_list_directory(const char root_directory[]) +int8_t LFS_list_directory(const char root_directory[], uint16_t offset, int16_t count) { - if (!LFS_is_lfs_mounted) - { - DEBUG_uart_print_str("LittleFS not mounted.\n"); + // Check if LFS is mounted + if (!LFS_is_lfs_mounted) { + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_WARNING, LOG_all_sinks_except(LOG_SINK_FILE), "LittleFS not mounted."); return 1; } + // Try to open the directory lfs_dir_t dir; int8_t open_dir_result = lfs_dir_open(&LFS_filesystem, &dir, root_directory); if (open_dir_result < 0) { - DEBUG_uart_print_str("Error opening a directory.\n"); + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "Error opening directory: %s", root_directory); return open_dir_result; } - // result is positive on success, 0 at the end of directory, or negative on failure. + if (count == 0) { + count = -1; + } + + // result is positive on success, 0 at the end of directory, or negative on failure. int8_t read_dir_result = 1; - while (read_dir_result >= 0) + struct lfs_info info; + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_NORMAL, LOG_all_sinks_except(LOG_SINK_FILE), "Name \t\t Bytes"); + while (read_dir_result > 0) { - struct lfs_info info; read_dir_result = lfs_dir_read(&LFS_filesystem, &dir, &info); - DEBUG_uart_print_str(info.name); - DEBUG_uart_print_str(", "); - // TODO: The info struct contains information about directory contents - } - DEBUG_uart_print_str("\n"); - - if (read_dir_result < 0) - { - DEBUG_uart_print_str("Error reading directory contents.\n"); - return read_dir_result; + if (read_dir_result < 0) + { + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "Error reading content from directory: %s", root_directory); + break; + } + + if (offset > 0) { + offset--; + continue; + } + + if (count == 0) { + break; + } else { + count--; + } + + if (info.type == LFS_TYPE_REG) + { + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_NORMAL, LOG_all_sinks_except(LOG_SINK_FILE), "%s\t%ld bytes", info.name, info.size); + } else if (info.type == LFS_TYPE_DIR){ + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_NORMAL, LOG_all_sinks_except(LOG_SINK_FILE), "%s/", info.name); + } } - DEBUG_uart_print_str("Successfully Listed Directory Contents.\n"); - int8_t close_dir_result = lfs_dir_close(&LFS_filesystem, &dir); if (close_dir_result < 0) { - DEBUG_uart_print_str("Error closing directory.\n"); + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "Error closing directory: %s", root_directory); return close_dir_result; } - return 0; + if (read_dir_result < 0) { + return read_dir_result; + } else { + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_NORMAL, LOG_all_sinks_except(LOG_SINK_FILE), "Successfully listed contents from directory: %s", root_directory); + return 0; + } } /** - * @brief Removes / deletes the file specified - * @param file_name Pointer to cstring holding the file name to remove + * @brief Creates directory + * @param dir_name Pointer to cstring holding the name of the directory * @retval 0 on success, 1 if LFS is unmounted, negative LFS error codes on failure */ -int8_t LFS_delete_file(const char file_name[]) +int8_t LFS_make_directory(const char dir_name[]) { if (!LFS_is_lfs_mounted) { - DEBUG_uart_print_str("LittleFS not mounted.\n"); + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_WARNING, LOG_all_sinks_except(LOG_SINK_FILE), "LittleFS not mounted!"); return 1; } - int8_t remove_result = lfs_remove(&LFS_filesystem, file_name); - if (remove_result < 0) + const int8_t make_dir_result = lfs_mkdir(&LFS_filesystem, dir_name); + if (make_dir_result < 0) { - DEBUG_uart_print_str("Error removing file/directory.\n"); - return remove_result; + if (make_dir_result == LFS_ERR_EXIST) { + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_WARNING, LOG_all_sinks_except(LOG_SINK_FILE), + "Directory %s already exists.", dir_name); + } else { + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_WARNING, LOG_all_sinks_except(LOG_SINK_FILE), + "Recieved error: %d while creating directory: %s.", make_dir_result, dir_name); + } + return make_dir_result; } - DEBUG_uart_print_str("Successfully removed file/directory.\n"); + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_NORMAL, LOG_all_sinks_except(LOG_SINK_FILE), "Successfully created directory: %s", dir_name); return 0; } /** - * @brief Creates directory - * @param dir_name Pointer to cstring holding the name of the directory + * @brief Removes / deletes the file specified + * @param file_name Pointer to cstring holding the file name to remove * @retval 0 on success, 1 if LFS is unmounted, negative LFS error codes on failure */ -int8_t LFS_make_directory(const char dir_name[]) +int8_t LFS_delete_file(const char file_name[]) { if (!LFS_is_lfs_mounted) { - DEBUG_uart_print_str("LittleFS not mounted.\n"); + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_WARNING, LOG_all_sinks_except(LOG_SINK_FILE), "LittleFS not mounted."); return 1; } - const int8_t make_dir_result = lfs_mkdir(&LFS_filesystem, dir_name); - if (make_dir_result < 0) + int8_t remove_result = lfs_remove(&LFS_filesystem, file_name); + if (remove_result < 0) { - LOG_message( - LOG_SYSTEM_LFS, LOG_SEVERITY_WARNING, LOG_SINK_ALL, - "Error %d creating directory.", - make_dir_result - ); - return make_dir_result; + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_WARNING, LOG_all_sinks_except(LOG_SINK_FILE), "Error removing file / directory: %s", file_name); + return remove_result; } - DEBUG_uart_print_str("Successfully created directory.\n"); + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_NORMAL, LOG_all_sinks_except(LOG_SINK_FILE), "Successfully removed file / directory: %s", file_name); return 0; } @@ -242,7 +261,7 @@ int8_t LFS_write_file(const char file_name[], uint8_t *write_buffer, uint32_t wr { if (!LFS_is_lfs_mounted) { - DEBUG_uart_print_str("LittleFS not mounted.\n"); + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_WARNING, LOG_all_sinks_except(LOG_SINK_FILE), "LittleFS not mounted."); return 1; } @@ -250,43 +269,34 @@ int8_t LFS_write_file(const char file_name[], uint8_t *write_buffer, uint32_t wr lfs_file_t file; const int8_t open_result = lfs_file_opencfg(&LFS_filesystem, &file, file_name, LFS_O_WRONLY | LFS_O_CREAT | LFS_O_TRUNC, &LFS_file_cfg); - if (open_result < 0) - { - DEBUG_uart_print_str("Error opening/creating file.\n"); - return open_result; - } - - if (LFS_enable_hot_path_debug_logs) { - DEBUG_uart_print_str("Opened/created a file named: '"); - DEBUG_uart_print_str(file_name); - DEBUG_uart_print_str("'\n"); - } - - // Write data to file - const int8_t write_result = lfs_file_write(&LFS_filesystem, &file, write_buffer, write_buffer_len); - if (write_result < 0) - { - DEBUG_uart_print_str("Error writing to file!\n"); - return write_result; - } - - if (LFS_enable_hot_path_debug_logs) { - DEBUG_uart_print_str("Successfully wrote data to file!\n"); - } - - // Close the File, the storage is not updated until the file is closed successfully - const int8_t close_result = lfs_file_close(&LFS_filesystem, &file); - if (close_result < 0) - { - DEBUG_uart_print_str("Error closing the file!\n"); - return close_result; - } - - if (LFS_enable_hot_path_debug_logs) { - DEBUG_uart_print_str("Successfully closed the file!\n"); - } - - return 0; + if (open_result < 0) + { + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_WARNING, LOG_all_sinks_except(LOG_SINK_FILE), "Error opening / creating file: %s", file_name); + return open_result; + } + + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_NORMAL, LOG_all_sinks_except(LOG_SINK_FILE), "Opened/created file: %s", file_name); + + // Write data to file + const int8_t write_result = lfs_file_write(&LFS_filesystem, &file, write_buffer, write_buffer_len); + if (write_result < 0) + { + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_WARNING, LOG_all_sinks_except(LOG_SINK_FILE), "Error writing to file: %s", file_name); + return write_result; + } + + // Close the File, the storage is not updated until the file is closed successfully + const int8_t close_result = lfs_file_close(&LFS_filesystem, &file); + if (close_result < 0) + { + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_WARNING, LOG_all_sinks_except(LOG_SINK_FILE), "Error closing file: %s", file_name); + return close_result; + } + + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_WARNING, LOG_all_sinks_except(LOG_SINK_FILE), "Successfully closed file: %s", file_name); + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_WARNING, LOG_all_sinks_except(LOG_SINK_FILE), "Successfully wrote data to file: %s", file_name); + + return 0; } /** @@ -307,34 +317,32 @@ int8_t LFS_append_file(const char file_name[], uint8_t *write_buffer, uint32_t w lfs_file_t file; const int8_t open_result = lfs_file_opencfg(&LFS_filesystem, &file, file_name, LFS_O_WRONLY | LFS_O_CREAT | LFS_O_APPEND, &LFS_file_cfg); - if (open_result < 0) - { - LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "Error opening file"); - return open_result; - } - + if (open_result < 0) + { + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "Error opening file: %s", file_name); + return open_result; + } + const int8_t seek_result = lfs_file_seek(&LFS_filesystem, &file, 0, LFS_SEEK_END); if (seek_result < 0) { - LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "Error seeking within file"); + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "Error seeking within file: %s", file_name); return seek_result; } - const int8_t write_result = lfs_file_write(&LFS_filesystem, &file, write_buffer, write_buffer_len); - if (write_result < 0) - { - LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "Error writing to file"); - return write_result; - } - - // Close the File, the storage is not updated until the file is closed successfully - const int8_t close_result = lfs_file_close(&LFS_filesystem, &file); - if (close_result < 0) - { - LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "Error closing file"); - return close_result; - } - - return 0; + const int8_t write_result = lfs_file_write(&LFS_filesystem, &file, write_buffer, write_buffer_len); + if (write_result < 0) { + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "Error writing to file %s", file_name); + return write_result; + } + + // Close the File, the storage is not updated until the file is closed successfully + const int8_t close_result = lfs_file_close(&LFS_filesystem, &file); + if (close_result < 0) { + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "Error closing file: %s", file_name); + return close_result; + } + + return 0; } /** @@ -348,51 +356,47 @@ int8_t LFS_append_file(const char file_name[], uint8_t *write_buffer, uint32_t w */ lfs_ssize_t LFS_read_file(const char file_name[], lfs_soff_t offset, uint8_t *read_buffer, uint32_t read_buffer_len) { - lfs_file_t file; - const int8_t open_result = lfs_file_opencfg(&LFS_filesystem, &file, file_name, LFS_O_RDONLY, &LFS_file_cfg); - if (open_result < 0) - { + if (!LFS_is_lfs_mounted) + { + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "LittleFS not mounted"); + return 1; + } + + lfs_file_t file; + const int8_t open_result = lfs_file_opencfg(&LFS_filesystem, &file, file_name, LFS_O_RDONLY, &LFS_file_cfg); + if (open_result < 0) + { // TODO: confirm behaviour is desired: this assumes filesystem as a // whole as an issue, so does not send log message to file - LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "Error opening file to read"); - return open_result; - } - - if (LFS_enable_hot_path_debug_logs) { - LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_SINK_ALL, "Opened file to read: %s", file_name); + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "Error opening file to read: %s", file_name); + return open_result; } + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_NORMAL, LOG_all_sinks_except(LOG_SINK_FILE), "Opened file to read: %s", file_name); const lfs_soff_t seek_result = lfs_file_seek(&LFS_filesystem, &file, offset, LFS_SEEK_SET); - if (seek_result < 0) - { - LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "Error seeking within file"); - return seek_result; - } - - const lfs_ssize_t read_result = lfs_file_read(&LFS_filesystem, &file, read_buffer, read_buffer_len); - if (read_result < 0) - { - LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "Error reading file"); - return read_result; - } - - if (LFS_enable_hot_path_debug_logs) { - LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_SINK_ALL, "Successfully read file"); - } - - // Close the File, the storage is not updated until the file is closed successfully - const int8_t close_result = lfs_file_close(&LFS_filesystem, &file); - if (close_result < 0) - { - LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "Error closing file"); - return close_result; - } - - if (LFS_enable_hot_path_debug_logs) { - LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "Successfully close file"); - } - - return read_result; + if (seek_result < 0) + { + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "Error seeking within file: %s", file_name); + return seek_result; + } + + const lfs_ssize_t read_result = lfs_file_read(&LFS_filesystem, &file, read_buffer, read_buffer_len); + if (read_result < 0) + { + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "Error reading file: %s", file_name); + return read_result; + } + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_NORMAL, LOG_all_sinks_except(LOG_SINK_FILE), "Successfully read file: %s", file_name); + + // Close the File, the storage is not updated until the file is closed successfully + const int8_t close_result = lfs_file_close(&LFS_filesystem, &file); + if (close_result < 0) { + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "Error closing file: %s", file_name); + return close_result; + } + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_NORMAL, LOG_all_sinks_except(LOG_SINK_FILE), "Successfully closed file: %s", file_name); + + return read_result; } /** @@ -403,18 +407,26 @@ lfs_ssize_t LFS_read_file(const char file_name[], lfs_soff_t offset, uint8_t *re */ lfs_ssize_t LFS_file_size(const char file_name[]) { - lfs_file_t file; - const int8_t open_result = lfs_file_opencfg(&LFS_filesystem, &file, file_name, LFS_O_RDONLY, &LFS_file_cfg); + if (!LFS_is_lfs_mounted) { + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "LittleFS not mounted"); + return 1; + } + + lfs_file_t file; + const int8_t open_result = lfs_file_opencfg(&LFS_filesystem, &file, file_name, LFS_O_RDONLY, &LFS_file_cfg); if (open_result < 0) { - LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "Error opening file"); + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "Error opening file: %s", file_name); return open_result; } + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_NORMAL, LOG_all_sinks_except(LOG_SINK_FILE), "Successfully opened file: %s", file_name); + const lfs_ssize_t size = lfs_file_size(&LFS_filesystem, &file); + const int8_t close_result = lfs_file_close(&LFS_filesystem, &file); - if (close_result < 0) { - LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "Error closing file"); - return close_result; - } + if (close_result < 0) { + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "Error closing file: %s", file_name); + return close_result; + } + LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_NORMAL, LOG_all_sinks_except(LOG_SINK_FILE), "Successfully closed file: %s", file_name); return size; -} - +} \ No newline at end of file diff --git a/firmware/Core/Src/telecommands/lfs_telecommand_defs.c b/firmware/Core/Src/telecommands/lfs_telecommand_defs.c index ae1699cd4..74ed94f45 100644 --- a/firmware/Core/Src/telecommands/lfs_telecommand_defs.c +++ b/firmware/Core/Src/telecommands/lfs_telecommand_defs.c @@ -11,7 +11,6 @@ #include "telecommands/telecommand_definitions.h" #include "telecommands/telecommand_args_helpers.h" - uint8_t TCMDEXEC_fs_format_storage(const char *args_str, TCMD_TelecommandChannel_enum_t tcmd_channel, char *response_output_buf, uint16_t response_output_buf_len) { int8_t result = LFS_format(); @@ -48,6 +47,82 @@ uint8_t TCMDEXEC_fs_unmount(const char *args_str, TCMD_TelecommandChannel_enum_t return 0; } +/// @brief Telecommand: List all the files and directories within a given directory +/// @param args_str +/// - Arg 0: Root Directory path as string +/// - Arg 1: (Offset) Number of entries to skip at the beginning +/// - Arg 2: (Count) Number entries to display +uint8_t TCMDEXEC_fs_list_directory(const char *args_str, TCMD_TelecommandChannel_enum_t tcmd_channel, + char *response_output_buf, uint16_t response_output_buf_len) { + + char arg_root_directory_path[64] = {0}; //TODO: Directory name could be up to 255 bytes by default + const uint8_t parse_directory_path_result = TCMD_extract_string_arg(args_str, 0, arg_root_directory_path, sizeof(arg_root_directory_path)); + if (parse_directory_path_result != 0) { + // error parsing + snprintf( + response_output_buf, + response_output_buf_len, + "Error parsing directory path arg: Error %d", parse_directory_path_result); + return 1; + } + + uint64_t arg_listing_offset = 0; + const uint8_t parse_listing_offset_result = TCMD_extract_uint64_arg(args_str, strlen(args_str), 1, &arg_listing_offset); + if (parse_listing_offset_result != 0) { + // error parsing + snprintf( + response_output_buf, + response_output_buf_len, + "Error parsing offset arg: Error %d", parse_listing_offset_result); + return 1; + } + + uint64_t arg_listing_count = 0; + const uint8_t parse_listing_count_result = TCMD_extract_uint64_arg(args_str, strlen(args_str), 2, &arg_listing_count); + if (parse_listing_count_result != 0) { + // error parsing + snprintf( + response_output_buf, + response_output_buf_len, + "Error parsing count arg: Error %d", parse_listing_count_result); + return 1; + } + + int8_t list_directory_result = LFS_list_directory(arg_root_directory_path, (uint16_t) arg_listing_offset, (int16_t) arg_listing_count); + if (list_directory_result < 0) { + snprintf(response_output_buf, response_output_buf_len, "LittleFS List Directory Error: %d\n", list_directory_result); + return 1; + } + + return 0; +} + +/// @brief Telecommand: Create a directory +/// @param args_str +/// - Arg 0: Directory Name as string +uint8_t TCMDEXEC_fs_make_directory(const char *args_str, TCMD_TelecommandChannel_enum_t tcmd_channel, + char *response_output_buf, uint16_t response_output_buf_len) { + + char arg_root_directory_path[64] = {0}; //TODO: Directory name could be up to 255 bytes by default + const uint8_t parse_directory_path_result = TCMD_extract_string_arg(args_str, 0, arg_root_directory_path, sizeof(arg_root_directory_path)); + if (parse_directory_path_result != 0) { + // error parsing + snprintf( + response_output_buf, + response_output_buf_len, + "Error parsing directory path arg: Error %d", parse_directory_path_result); + return 1; + } + + int8_t make_directory_result = LFS_make_directory(arg_root_directory_path); + if (make_directory_result < 0) { + snprintf(response_output_buf, response_output_buf_len, "LittleFS Make Directory Error: %d\n", make_directory_result); + return 1; + } + + return 0; +} + /// @brief Telecommand: Write data to a file in LittleFS /// @param args_str /// - Arg 0: File path as string diff --git a/firmware/Core/Src/telecommands/telecommand_definitions.c b/firmware/Core/Src/telecommands/telecommand_definitions.c index 5cb3feef7..33a31c4a5 100644 --- a/firmware/Core/Src/telecommands/telecommand_definitions.c +++ b/firmware/Core/Src/telecommands/telecommand_definitions.c @@ -251,6 +251,18 @@ const TCMD_TelecommandDefinition_t TCMD_telecommand_definitions[] = { .number_of_args = 0, .readiness_level = TCMD_READINESS_LEVEL_FOR_OPERATION, }, + { + .tcmd_name = "fs_list_directory", + .tcmd_func = TCMDEXEC_fs_list_directory, + .number_of_args = 3, + .readiness_level = TCMD_READINESS_LEVEL_FOR_OPERATION, + }, + { + .tcmd_name = "fs_make_directory", + .tcmd_func = TCMDEXEC_fs_make_directory, + .number_of_args = 1, + .readiness_level = TCMD_READINESS_LEVEL_FOR_OPERATION, + }, { .tcmd_name = "fs_write_file", .tcmd_func = TCMDEXEC_fs_write_file,