Skip to content
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

LFS Telecommand to list files / directories [Issue #7] #216

Open
wants to merge 27 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 18 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
fcb05fc
Replaced all flash driver code for NAND chip
Saksham-P Jul 22, 2024
a44e5ac
Updated memory module configuration
Saksham-P Jul 22, 2024
ae68581
Changes to flash_driver and flash_telecommand_defs
KaleF07 Sep 7, 2024
159e961
Minor changes to flash telecommands
KaleF07 Sep 7, 2024
3022e02
Cleaned code from testing
KaleF07 Sep 11, 2024
3c8b3ac
Removed Unblock_block_lock telecommand,
KaleF07 Sep 13, 2024
8259399
Update LFS_benchmark_write_read to write many files
parker-research Sep 17, 2024
a132979
Fixed improper page addressing issue
KaleF07 Oct 2, 2024
60eb9ee
Minor changes based on PR review
KaleF07 Oct 3, 2024
477a97e
Merge branch 'main' into saksham-LFS-i7
Saksham-P Oct 4, 2024
4da1c31
Merge branch 'main' into saksham-LFS-i7
Saksham-P Oct 6, 2024
70bea08
Created List Directory telecommand
Saksham-P Oct 6, 2024
e72168f
Merge branch 'main' into saksham-LFS-i7
Saksham-P Oct 13, 2024
9ef3de5
Added Telecommand to make a directory
Saksham-P Oct 16, 2024
95bea18
Added offset and count for list directory function
Saksham-P Oct 18, 2024
4d44129
Merge branch 'main' into saksham-LFS-i7
Saksham-P Oct 19, 2024
00a0ae9
Added documentation for list directory telecommand
Saksham-P Oct 20, 2024
b33e043
Added Name into Contributors list
Saksham-P Oct 20, 2024
7970e94
Updated List Directory Algorithm
Saksham-P Oct 26, 2024
7f1e54f
Merge branch 'main' into saksham-LFS-i7
Saksham-P Nov 6, 2024
1b2d053
Added LOG_message for littlefs_helper functions
Saksham-P Nov 13, 2024
4bbf381
Merge branch 'main' into saksham-LFS-i7
Saksham-P Nov 20, 2024
80631bc
Converted to Space Indenting
Saksham-P Dec 4, 2024
faa3def
Converted all Debugs to LOG_message
Saksham-P Dec 4, 2024
2834e27
Merge branch 'main' into saksham-LFS-i7
Saksham-P Dec 4, 2024
e88f624
Updated LOG to use long int instead of int
Saksham-P Dec 4, 2024
913278c
Merge branch 'main' into saksham-LFS-i7
Saksham-P Dec 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ Please add your name to the list below in your first Pull Request!
* Marko V.
* Vaibhav K.
* Muhammad Ali
* Saksham P.

## License and Libraries

Expand Down
4 changes: 2 additions & 2 deletions firmware/Core/Inc/littlefs/littlefs_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
6 changes: 6 additions & 0 deletions firmware/Core/Inc/telecommands/lfs_telecommand_defs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
122 changes: 76 additions & 46 deletions firmware/Core/Src/littlefs/littlefs_helper.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@


/*-----------------------------INCLUDES-----------------------------*/
#include <stdint.h>

Expand Down Expand Up @@ -39,7 +37,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,
Expand All @@ -57,22 +55,21 @@ struct lfs_file_config LFS_file_cfg = {

// -----------------------------LITTLEFS FUNCTIONS-----------------------------


/**
* @brief Formats Memory Module so it can successfully mount LittleFS
* @param None
* @retval 0 on success, negative LFS error codes on failure
*/
int8_t LFS_format()
{
int8_t result = lfs_format(&LFS_filesystem, &LFS_cfg);
if (result < 0)
int8_t format_result = lfs_format(&LFS_filesystem, &LFS_cfg);
if (format_result < 0)
{
DEBUG_uart_print_str("Error formatting!\n");
return result;
LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_CRITICAL, LOG_all_sinks_except(LOG_SINK_FILE), "Error formatting FLASH memory!");
return format_result;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please convert this file's indentation to use spaces instead of tabs. There's a few places it's mixed in this repo, but in general, we prefer spaces. Ideally, never mix in the same file.

}

DEBUG_uart_print_str("Formatting successful!\n");
LOG_message(LOG_SYSTEM_LFS, LOG_SEVERITY_NORMAL, LOG_all_sinks_except(LOG_SINK_FILE), "FLASH Memory formatting successful!");
return 0;
}

Expand All @@ -83,20 +80,21 @@ int8_t LFS_format()
*/
int8_t LFS_mount()
{
if (LFS_is_lfs_mounted) {
DEBUG_uart_print_str("LittleFS already mounted!\n");
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");
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;
}
Expand All @@ -110,56 +108,80 @@ int8_t LFS_unmount()
{
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;
}

// Unmount LittleFS to release any resources used by LittleFS
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 Pointer to cstring holding the root directory to open and read
Saksham-P marked this conversation as resolved.
Show resolved Hide resolved
* @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)
{
// Check if LFS is mounted
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;
}

// 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;
DEBUG_uart_print_str("Name \t bytes\n");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is gonna be awfully difficult to read when the satellite's in space ;)

Please use the logging function to display this info.

while (read_dir_result > 0)
Saksham-P marked this conversation as resolved.
Show resolved Hide resolved
{
struct lfs_info info;
read_dir_result = lfs_dir_read(&LFS_filesystem, &dir, &info);

if (offset > 0) {
offset--;
continue;
}

if (count == 0) {
break;
} else {
count--;
}

DEBUG_uart_print_str(info.name);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please switch all this to LOG_message

DEBUG_uart_print_str(", ");
// TODO: The info struct contains information about directory contents
if (info.type == LFS_TYPE_REG)
{
DEBUG_uart_print_str("\t");
DEBUG_uart_print_uint32(info.size);
DEBUG_uart_print_str(" bytes");
}
DEBUG_uart_print_str("\n");
}
DEBUG_uart_print_str("\n");

if (read_dir_result < 0)
{
Expand All @@ -180,54 +202,62 @@ int8_t LFS_list_directory(const char root_directory[])
}

/**
* @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");
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_SINK_ALL,
"Directory %d already exists.",
make_dir_result
);
} else {
LOG_message(
LOG_SYSTEM_LFS, LOG_SEVERITY_WARNING, LOG_SINK_ALL,
"Error %d creating directory.",
make_dir_result
);
}
return make_dir_result;
}

DEBUG_uart_print_str("Successfully removed file/directory.\n");
DEBUG_uart_print_str("Successfully created directory.\n");
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[])
NuclearTea marked this conversation as resolved.
Show resolved Hide resolved
{
if (!LFS_is_lfs_mounted)
{
DEBUG_uart_print_str("LittleFS not mounted.\n");
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;
DEBUG_uart_print_str("Error removing file/directory.\n");
return remove_result;
}

DEBUG_uart_print_str("Successfully created directory.\n");
DEBUG_uart_print_str("Successfully removed file/directory.\n");
return 0;
}

Expand Down
79 changes: 78 additions & 1 deletion firmware/Core/Src/telecommands/lfs_telecommand_defs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down Expand Up @@ -48,6 +47,84 @@ 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;
}

// snprintf(response_output_buf, response_output_buf_len, "LittleFS Successfully Unounted!\n");
Saksham-P marked this conversation as resolved.
Show resolved Hide resolved
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;
}

// snprintf(response_output_buf, response_output_buf_len, "LittleFS Successfully Unounted!\n");
Saksham-P marked this conversation as resolved.
Show resolved Hide resolved
return 0;
}

/// @brief Telecommand: Write data to a file in LittleFS
/// @param args_str
/// - Arg 0: File path as string
Expand Down
12 changes: 12 additions & 0 deletions firmware/Core/Src/telecommands/telecommand_definitions.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,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,
Expand Down