/* * 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 \": 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 \": Removes file or directory\r\n", lfs_rm_handler, 1); SHELL_COMMAND_DEFINE(mkdir, "\r\n\"mkdir \": Creates a new directory\r\n", lfs_mkdir_handler, 1); SHELL_COMMAND_DEFINE(write, "\r\n\"write \": Writes/appends text to a file\r\n", lfs_write_handler, 2); SHELL_COMMAND_DEFINE(cat, "\r\n\"cat \": 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 } }