MCUXpresso_MIMXRT1052xxxxB/boards/evkbimxrt1050/littlefs_examples/littlefs_shell/littlefs_shell.c

396 lines
11 KiB
C

/*
* Copyright (c) 2016, Freescale Semiconductor, Inc.
* Copyright 2016-2021 NXP
* All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "fsl_common.h"
#include "fsl_debug_console.h"
#include "fsl_component_serial_manager.h"
#include "fsl_shell.h"
#include "lfs.h"
#include "lfs_mflash.h"
#include "pin_mux.h"
#include "clock_config.h"
#include "board.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define SHELL_Printf PRINTF
/*******************************************************************************
* Prototypes
******************************************************************************/
/* SHELL LFS command handlers */
static shell_status_t lfs_format_handler(shell_handle_t shellHandle, int32_t argc, char **argv);
static shell_status_t lfs_mount_handler(shell_handle_t shellHandle, int32_t argc, char **argv);
static shell_status_t lfs_unmount_handler(shell_handle_t shellHandle, int32_t argc, char **argv);
static shell_status_t lfs_cd_handler(shell_handle_t shellHandle, int32_t argc, char **argv);
static shell_status_t lfs_ls_handler(shell_handle_t shellHandle, int32_t argc, char **argv);
static shell_status_t lfs_rm_handler(shell_handle_t shellHandle, int32_t argc, char **argv);
static shell_status_t lfs_mkdir_handler(shell_handle_t shellHandle, int32_t argc, char **argv);
static shell_status_t lfs_write_handler(shell_handle_t shellHandle, int32_t argc, char **argv);
static shell_status_t lfs_cat_handler(shell_handle_t shellHandle, int32_t argc, char **argv);
/*******************************************************************************
* Variables
******************************************************************************/
lfs_t lfs;
struct lfs_config cfg;
int lfs_mounted;
SHELL_COMMAND_DEFINE(format,
"\r\n\"format yes\": Formats the filesystem\r\n",
lfs_format_handler,
SHELL_IGNORE_PARAMETER_COUNT);
SHELL_COMMAND_DEFINE(mount, "\r\n\"mount\": Mounts the filesystem\r\n", lfs_mount_handler, 0);
SHELL_COMMAND_DEFINE(unmount, "\r\n\"unmount\": Unmounts the filesystem\r\n", lfs_unmount_handler, 0);
SHELL_COMMAND_DEFINE(umount, "", lfs_unmount_handler, 0); // unmount alias
SHELL_COMMAND_DEFINE(cd, "", lfs_cd_handler, SHELL_IGNORE_PARAMETER_COUNT);
SHELL_COMMAND_DEFINE(ls,
"\r\n\"ls <path>\": Lists directory content\r\n",
lfs_ls_handler,
SHELL_IGNORE_PARAMETER_COUNT);
SHELL_COMMAND_DEFINE(dir, "", lfs_ls_handler, SHELL_IGNORE_PARAMETER_COUNT); // ls alias
SHELL_COMMAND_DEFINE(rm, "\r\n\"rm <path>\": Removes file or directory\r\n", lfs_rm_handler, 1);
SHELL_COMMAND_DEFINE(mkdir, "\r\n\"mkdir <path>\": Creates a new directory\r\n", lfs_mkdir_handler, 1);
SHELL_COMMAND_DEFINE(write, "\r\n\"write <path> <text>\": Writes/appends text to a file\r\n", lfs_write_handler, 2);
SHELL_COMMAND_DEFINE(cat, "\r\n\"cat <path>\": Prints file content\r\n", lfs_cat_handler, 1);
SDK_ALIGN(static uint8_t s_shellHandleBuffer[SHELL_HANDLE_SIZE], 4);
static shell_handle_t s_shellHandle;
extern serial_handle_t g_serialHandle;
/*******************************************************************************
* Code
******************************************************************************/
static shell_status_t lfs_format_handler(shell_handle_t shellHandle, int32_t argc, char **argv)
{
int res;
if (lfs_mounted)
{
SHELL_Printf("LFS is mounted, please unmount it first.\r\n");
return kStatus_SHELL_Success;
}
if (argc != 2 || strcmp(argv[1], "yes"))
{
SHELL_Printf("Are you sure? Please issue command \"format yes\" to proceed.\r\n");
return kStatus_SHELL_Success;
}
res = lfs_format(&lfs, &cfg);
if (res)
{
PRINTF("\rError formatting LFS: %d\r\n", res);
}
return kStatus_SHELL_Success;
}
static shell_status_t lfs_mount_handler(shell_handle_t shellHandle, int32_t argc, char **argv)
{
int res;
if (lfs_mounted)
{
SHELL_Printf("LFS already mounted\r\n");
return kStatus_SHELL_Success;
}
res = lfs_mount(&lfs, &cfg);
if (res)
{
PRINTF("\rError mounting LFS\r\n");
}
else
{
lfs_mounted = 1;
}
return kStatus_SHELL_Success;
}
static shell_status_t lfs_unmount_handler(shell_handle_t shellHandle, int32_t argc, char **argv)
{
int res;
if (!lfs_mounted)
{
SHELL_Printf("LFS not mounted\r\n");
return kStatus_SHELL_Success;
}
res = lfs_unmount(&lfs);
if (res)
{
PRINTF("\rError unmounting LFS: %i\r\n", res);
}
lfs_mounted = 0;
return kStatus_SHELL_Success;
}
static shell_status_t lfs_cd_handler(shell_handle_t shellHandle, int32_t argc, char **argv)
{
SHELL_Printf(
"There is no concept of current directory in this example.\r\nPlease always specify the full path.\r\n");
return kStatus_SHELL_Success;
}
static shell_status_t lfs_ls_handler(shell_handle_t shellHandle, int32_t argc, char **argv)
{
int res;
char *path;
lfs_dir_t dir;
struct lfs_info info;
int files;
int dirs;
if (!lfs_mounted)
{
SHELL_Printf("LFS not mounted\r\n");
return kStatus_SHELL_Success;
}
if (argc > 2)
{
SHELL_Printf("Invalid number of parameters\r\n");
return kStatus_SHELL_Success;
}
if (argc < 2)
{
path = "/";
}
else
{
path = argv[1];
}
/* open the directory */
res = lfs_dir_open(&lfs, &dir, path);
if (res)
{
PRINTF("\rError opening directory: %i\r\n", res);
return kStatus_SHELL_Success;
}
PRINTF(" Directory of %s\r\n", path);
files = 0;
dirs = 0;
/* iterate until end of directory */
while ((res = lfs_dir_read(&lfs, &dir, &info)) != 0)
{
if (res < 0)
{
/* break the loop in case of an error */
PRINTF("\rError reading directory: %i\r\n", res);
break;
}
if (info.type == LFS_TYPE_REG)
{
SHELL_Printf("%8d %s\r\n", info.size, info.name);
files++;
}
else if (info.type == LFS_TYPE_DIR)
{
SHELL_Printf("% DIR %s\r\n", info.name);
dirs++;
}
else
{
SHELL_Printf("%???\r\n");
}
}
res = lfs_dir_close(&lfs, &dir);
if (res)
{
PRINTF("\rError closing directory: %i\r\n", res);
return kStatus_SHELL_Success;
}
PRINTF(" %d File(s), %d Dir(s)\r\n", files, dirs);
return kStatus_SHELL_Success;
}
static shell_status_t lfs_rm_handler(shell_handle_t shellHandle, int32_t argc, char **argv)
{
int res;
if (!lfs_mounted)
{
SHELL_Printf("LFS not mounted\r\n");
return kStatus_SHELL_Success;
}
res = lfs_remove(&lfs, argv[1]);
if (res)
{
PRINTF("\rError while removing: %i\r\n", res);
}
return kStatus_SHELL_Success;
}
static shell_status_t lfs_mkdir_handler(shell_handle_t shellHandle, int32_t argc, char **argv)
{
int res;
if (!lfs_mounted)
{
SHELL_Printf("LFS not mounted\r\n");
return kStatus_SHELL_Success;
}
res = lfs_mkdir(&lfs, argv[1]);
if (res)
{
PRINTF("\rError creating directory: %i\r\n", res);
}
return kStatus_SHELL_Success;
}
static shell_status_t lfs_write_handler(shell_handle_t shellHandle, int32_t argc, char **argv)
{
int res;
lfs_file_t file;
if (!lfs_mounted)
{
SHELL_Printf("LFS not mounted\r\n");
return kStatus_SHELL_Success;
}
res = lfs_file_open(&lfs, &file, argv[1], LFS_O_WRONLY | LFS_O_APPEND | LFS_O_CREAT);
if (res)
{
PRINTF("\rError opening file: %i\r\n", res);
return kStatus_SHELL_Success;
}
res = lfs_file_write(&lfs, &file, argv[2], strlen(argv[2]));
if (res > 0)
res = lfs_file_write(&lfs, &file, "\r\n", 2);
if (res < 0)
{
PRINTF("\rError writing file: %i\r\n", res);
}
res = lfs_file_close(&lfs, &file);
if (res)
{
PRINTF("\rError closing file: %i\r\n", res);
}
return kStatus_SHELL_Success;
}
static shell_status_t lfs_cat_handler(shell_handle_t shellHandle, int32_t argc, char **argv)
{
int res;
lfs_file_t file;
uint8_t buf[16];
if (!lfs_mounted)
{
SHELL_Printf("LFS not mounted\r\n");
return kStatus_SHELL_Success;
}
res = lfs_file_open(&lfs, &file, argv[1], LFS_O_RDONLY);
if (res)
{
PRINTF("\rError opening file: %i\r\n", res);
return kStatus_SHELL_Success;
}
do
{
res = lfs_file_read(&lfs, &file, buf, sizeof(buf));
if (res < 0)
{
PRINTF("\rError reading file: %i\r\n", res);
break;
}
SHELL_Write(s_shellHandle, (char *)buf, res);
} while (res);
res = lfs_file_close(&lfs, &file);
if (res)
{
PRINTF("\rError closing file: %i\r\n", res);
}
return kStatus_SHELL_Success;
}
int main(void)
{
status_t status;
BOARD_ConfigMPU();
BOARD_InitBootPins();
BOARD_InitBootClocks();
BOARD_InitDebugConsole();
// Set flexspi root clock to 166MHZ.
const clock_usb_pll_config_t g_ccmConfigUsbPll = {.loopDivider = 0U};
CLOCK_InitUsb1Pll(&g_ccmConfigUsbPll);
CLOCK_InitUsb1Pfd(kCLOCK_Pfd0, 26); /* Set PLL3 PFD0 clock 332MHZ. */
CLOCK_SetMux(kCLOCK_FlexspiMux, 0x3); /* Choose PLL3 PFD0 clock as flexspi source clock. */
CLOCK_SetDiv(kCLOCK_FlexspiDiv, 3); /* flexspi clock 83M, DDR mode, internal clock 42M. */
lfs_get_default_config(&cfg);
status = lfs_storage_init(&cfg);
if (status != kStatus_Success)
{
PRINTF("LFS storage init failed: %i\r\n", status);
return status;
}
/* Init SHELL */
s_shellHandle = &s_shellHandleBuffer[0];
SHELL_Init(s_shellHandle, g_serialHandle, "LFS>> ");
SHELL_RegisterCommand(s_shellHandle, SHELL_COMMAND(format));
SHELL_RegisterCommand(s_shellHandle, SHELL_COMMAND(mount));
SHELL_RegisterCommand(s_shellHandle, SHELL_COMMAND(unmount));
SHELL_RegisterCommand(s_shellHandle, SHELL_COMMAND(umount));
SHELL_RegisterCommand(s_shellHandle, SHELL_COMMAND(cd));
SHELL_RegisterCommand(s_shellHandle, SHELL_COMMAND(ls));
SHELL_RegisterCommand(s_shellHandle, SHELL_COMMAND(dir));
SHELL_RegisterCommand(s_shellHandle, SHELL_COMMAND(rm));
SHELL_RegisterCommand(s_shellHandle, SHELL_COMMAND(mkdir));
SHELL_RegisterCommand(s_shellHandle, SHELL_COMMAND(write));
SHELL_RegisterCommand(s_shellHandle, SHELL_COMMAND(cat));
while (1)
{
#if !(defined(SHELL_NON_BLOCKING_MODE) && (SHELL_NON_BLOCKING_MODE > 0U))
SHELL_Task(s_shellHandle);
#endif
}
}