diff --git a/Lab20 Mass Storage/applications/console/.vscode/launch.json b/Lab20 Mass Storage/applications/console/.vscode/launch.json new file mode 100644 index 0000000..f9afc43 --- /dev/null +++ b/Lab20 Mass Storage/applications/console/.vscode/launch.json @@ -0,0 +1,30 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + + { + "name": "GDB attach to openocd", + "type": "cppdbg", + "request": "launch", + "program": "${workspaceFolder}\\console.elf", + "args": [], + "stopAtEntry": true, + "cwd": "${workspaceFolder}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + "miDebuggerPath": "gdb-multiarch.exe", + "miDebuggerServerAddress": "127.0.0.1:3333" + } + ] +} \ No newline at end of file diff --git a/Lab20 Mass Storage/applications/console/.vscode/settings.json b/Lab20 Mass Storage/applications/console/.vscode/settings.json new file mode 100644 index 0000000..6c141c7 --- /dev/null +++ b/Lab20 Mass Storage/applications/console/.vscode/settings.json @@ -0,0 +1,3 @@ +{ + "makefile.makefilePath": "." +} \ No newline at end of file diff --git a/Lab20 Mass Storage/applications/console/console.code-workspace b/Lab20 Mass Storage/applications/console/console.code-workspace new file mode 100644 index 0000000..b17a714 --- /dev/null +++ b/Lab20 Mass Storage/applications/console/console.code-workspace @@ -0,0 +1,34 @@ +{ + "folders": [ + { + "path": "." + }, + { + "path": "../../boards" + }, + { + "path": "../../fat" + }, + { + "path": "../../include" + }, + { + "path": "../../system" + }, + { + "path": "../../usb" + } + ], + "settings": { + "makefile.launchConfigurations": [ + { + "cwd": "e:\\Source\\computersystems\\Lab20 Mass Storage\\applications\\console", + "binaryPath": "e:\\Source\\computersystems\\Lab20 Mass Storage\\applications\\console\\console.elf", + "binaryArgs": [] + } + ], + "files.associations": { + "system.h": "c" + } + } +} \ No newline at end of file diff --git a/Lab20 Mass Storage/applications/console/main.c b/Lab20 Mass Storage/applications/console/main.c index cb453d8..cc15904 100644 --- a/Lab20 Mass Storage/applications/console/main.c +++ b/Lab20 Mass Storage/applications/console/main.c @@ -119,7 +119,7 @@ i8 MountedPartition = 0; i8 PartitionToMount = -1; struct partition partitions[4]; -void read_sector_callback(u8 *buffer, int buffLen, void *unused) +static void read_sector_callback(u8 *buffer, int buffLen, void *unused) { int i; @@ -222,20 +222,12 @@ int MountFilesystem(char *command) else PartitionToMount = 0; - // Create the polling task and initialize the FAT file system -#if ENABLE_OS - TaskNew(MAX_TASKS - 4, FatPoll, NULL); -#endif - FatInit(); - -/* // Seek to first block, the MBR MassStorageSeek(0); // Read the Master Boot Record (MBR) if (MassStorageRead(ReadSector, 512, read_sector_callback, NULL) <= 0) puts("MassStorageRead failed"); -*/ } else puts("USB not initialized"); @@ -243,7 +235,7 @@ int MountFilesystem(char *command) return TASK_FINISHED; } -int ReadFilesystem(const char *command) +int ReadBlock(const char *command) { if (UsbUp) { diff --git a/Lab20 Mass Storage/boards/.vscode/launch.json b/Lab20 Mass Storage/boards/.vscode/launch.json new file mode 100644 index 0000000..566d859 --- /dev/null +++ b/Lab20 Mass Storage/boards/.vscode/launch.json @@ -0,0 +1,41 @@ +{ + "configurations": [ + { + "name": "(gdb) Launch", + "type": "cppdbg", + "request": "launch", + "program": "enter program name, for example ${workspaceFolder}/a.exe", + "args": [], + "stopAtEntry": false, + "cwd": "${fileDirname}", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "miDebuggerPath": "/path/to/gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + }, + { + "description": "Set Disassembly Flavor to Intel", + "text": "-gdb-set disassembly-flavor intel", + "ignoreFailures": true + } + ] + }, + { + "name": "(Windows) Launch", + "type": "cppvsdbg", + "request": "launch", + "program": "enter program name, for example ${workspaceFolder}/a.exe", + "args": [], + "stopAtEntry": false, + "cwd": "${fileDirname}", + "environment": [], + "console": "externalTerminal" + } + ], + "version": "2.0.0" +} \ No newline at end of file diff --git a/Lab20 Mass Storage/boards/peripherals/dwc/transfer.c b/Lab20 Mass Storage/boards/peripherals/dwc/transfer.c index 21722e8..4715262 100644 --- a/Lab20 Mass Storage/boards/peripherals/dwc/transfer.c +++ b/Lab20 Mass Storage/boards/peripherals/dwc/transfer.c @@ -639,7 +639,7 @@ void TransferStageDataAttach(TransferStageData *transfer, u32 channel, assert (transfer->bufferPointer != 0); else transfer->bufferPointer = &transfer->TempBuffer; - assert (((u32) transfer->bufferPointer & 3) == 0); + assert (((uintptr_t)transfer->bufferPointer & 3) == 0); if (transfer->splitTransaction) { diff --git a/Lab20 Mass Storage/boards/rpi/board.c b/Lab20 Mass Storage/boards/rpi/board.c index 6973472..f178c91 100644 --- a/Lab20 Mass Storage/boards/rpi/board.c +++ b/Lab20 Mass Storage/boards/rpi/board.c @@ -620,3 +620,31 @@ u32 __aeabi_uidiv(u32 value, u32 divisor) // Use the division modulus, ignoring/truncating the remainder return __aeabi_uidivmod(value, divisor); }; + +// ARM EABI signed integer division support for GCC +i32 __aeabi_idiv(i32 value, i32 divisor) +{ + u32 v, div; + int result; + + // Remove the negative attributes and convert to u32 + if (divisor < 0) + div = (u32)-divisor; + else + div = (u32)divisor; + if (value < 0) + v = (u32)-value; + else + v = (u32)value; + + // Use the division modulus, ignoring/truncating the remainder + result = (i32)__aeabi_uidivmod(v, div); + + // Add back the negative attribute + if (divisor < 0) + result = -result; + if (value < 0) + result = -result; + + return result; +}; diff --git a/Lab20 Mass Storage/fat/asyncfatfs.c b/Lab20 Mass Storage/fat/asyncfatfs.c index b349122..c082976 100644 --- a/Lab20 Mass Storage/fat/asyncfatfs.c +++ b/Lab20 Mass Storage/fat/asyncfatfs.c @@ -427,6 +427,8 @@ typedef enum { } afatfsInitializationPhase_e; typedef struct afatfs_t { + uint8_t cache[AFATFS_SECTOR_SIZE * AFATFS_NUM_CACHE_SECTORS]; + afatfsCacheBlockDescriptor_t cacheDescriptor[AFATFS_NUM_CACHE_SECTORS]; fatFilesystemType_e filesystemType; afatfsFilesystemState_e filesystemState; @@ -440,8 +442,6 @@ typedef struct afatfs_t { } initState; #endif - uint8_t cache[AFATFS_SECTOR_SIZE * AFATFS_NUM_CACHE_SECTORS]; - afatfsCacheBlockDescriptor_t cacheDescriptor[AFATFS_NUM_CACHE_SECTORS]; uint32_t cacheTimer; int cacheDirtyEntries; // The number of cache entries in the AFATFS_CACHE_STATE_DIRTY state @@ -1617,8 +1617,6 @@ static afatfsOperationStatus_e afatfs_appendRegularFreeCluster(afatfsFilePtr_t f return afatfs_appendRegularFreeClusterContinue(file); } -#ifdef AFATFS_USE_FREEFILE - /** * Size of a AFATFS supercluster in bytes */ @@ -1628,6 +1626,7 @@ uint32_t afatfs_superClusterSize() return afatfs_fatEntriesPerSector() * afatfs_clusterSize(); } +#ifdef AFATFS_USE_FREEFILE /** * Continue to attempt to add a supercluster to the end of the given file. * diff --git a/Lab20 Mass Storage/fat/asyncfatfs.h b/Lab20 Mass Storage/fat/asyncfatfs.h index ebae21d..f12ae64 100644 --- a/Lab20 Mass Storage/fat/asyncfatfs.h +++ b/Lab20 Mass Storage/fat/asyncfatfs.h @@ -55,6 +55,7 @@ uint32_t afatfs_fwrite(afatfsFilePtr_t file, const uint8_t *buffer, uint32_t len uint32_t afatfs_fread(afatfsFilePtr_t file, uint8_t *buffer, uint32_t len); afatfsOperationStatus_e afatfs_fseek(afatfsFilePtr_t file, int32_t offset, afatfsSeek_e whence); bool afatfs_ftell(afatfsFilePtr_t file, uint32_t *position); +bool afatfs_feof(afatfsFilePtr_t file); bool afatfs_mkdir(const char *filename, afatfsFileCallback_t complete); bool afatfs_chdir(afatfsFilePtr_t dirHandle); diff --git a/Lab20 Mass Storage/fat/fat.c b/Lab20 Mass Storage/fat/fat.c new file mode 100644 index 0000000..cf7ecb5 --- /dev/null +++ b/Lab20 Mass Storage/fat/fat.c @@ -0,0 +1,389 @@ +/*...................................................................*/ +/* */ +/* Module: fat.c */ +/* Version: 2024.0 */ +/* Purpose: Interface to FAT shell commands */ +/* */ +/*...................................................................*/ +/* */ +/* Copyright 2024, Sean Lawless */ +/* */ +/* ALL RIGHTS RESERVED */ +/* */ +/* Redistribution and use in source, binary or derived forms, with */ +/* or without modification, are permitted provided that the */ +/* following conditions are met: */ +/* */ +/* 1. Redistributions in any form, including but not limited to */ +/* source code, binary, or derived works, must include the above */ +/* copyright notice, this list of conditions and the following */ +/* disclaimer. */ +/* */ +/* 2. Any change or addition to this copyright notice requires the */ +/* prior written permission of the above copyright holder. */ +/* */ +/* THIS SOFTWARE IS PROVIDED ''AS IS''. ANY EXPRESS OR IMPLIED */ +/* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES */ +/* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE */ +/* DISCLAIMED. IN NO EVENT SHALL ANY AUTHOR AND/OR COPYRIGHT HOLDER */ +/* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, */ +/* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED */ +/* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, */ +/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON */ +/* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, */ +/* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY */ +/* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */ +/* POSSIBILITY OF SUCH DAMAGE. */ +/*...................................................................*/ +#include +#include +#include +#include "sdcard.h" + +#ifdef ENABLE_FAT + +#include "asyncfatfs.h" + +/*...................................................................*/ +/* Global Variables */ +/*...................................................................*/ + +static char CWD[256]; // Current Working Directory +static char CDDir[16]; // Change subdirectory in progress +static afatfsFilePtr_t openDirectory; +static afatfsFinder_t finder; +typedef enum { + READ_INIT, + READ_OPEN, + READ_READ, + READ_END +} fatState; +fatState readState = READ_INIT; + +/*...................................................................*/ +/* Local function definitions */ +/*...................................................................*/ + +/*...................................................................*/ +/* read_directory_callback: Callback to open and read directory */ +/* */ +/* input: file = the AsyncFATFS file pointer */ +/* */ +/*...................................................................*/ +static void read_directory_callback(afatfsFilePtr_t file) +{ + openDirectory = file; + + if (openDirectory) + { + if (readState == READ_OPEN) + { + readState = READ_READ; + afatfs_findFirst(openDirectory, &finder); + } + + else + { + afatfsOperationStatus_e status; + fatDirectoryEntry_t *dirEntry; + status = afatfs_findNext(openDirectory, &finder, &dirEntry); + + if (status == AFATFS_OPERATION_SUCCESS) + { + // If no more directory entries, move state to end directory read + if ((dirEntry == NULL) || (dirEntry->attrib == 0)) + { + readState = READ_END; + } + + // If a valid file entry, convert and output the FAT name + else if ((dirEntry->filename[0] != FAT_DELETED_FILE_MARKER) && + !(dirEntry->attrib & (FAT_FILE_ATTRIBUTE_VOLUME_ID | FAT_FILE_ATTRIBUTE_SYSTEM))) + { + char filename[16]; + fat_convertFATStyleToFilename(dirEntry->filename, filename); + printf("%s\n", filename); + } + } + + // If failure, end the read directory operation + else if (status == AFATFS_OPERATION_FAILURE) + { + readState = READ_END; + printf("Reading directory failed\n"); + } + } + } + + // If fopen failed, end the read directory operation + else + { + readState = READ_END; + printf("Opening directory failed\n"); + } +} + +/*...................................................................*/ +/* read_file_callback: Callback to open and read a file */ +/* */ +/* input: file = the AsyncFATFS directory file pointer */ +/* */ +/*...................................................................*/ +static void read_file_callback(afatfsFilePtr_t file) +{ + openDirectory = file; + u8 buffer[SECTOR_SIZE + 1]; + + if (openDirectory) + { + if (readState == READ_OPEN) + readState = READ_READ; + + uint32_t length; + length = afatfs_fread(openDirectory, buffer, SECTOR_SIZE); + + if (length > 0) + { + buffer[length] = '\0'; + printf("%s", buffer); + } + else if (afatfs_feof(openDirectory)) + { + puts(""); + readState = READ_END; + } + } + + // If fopen failed, end the read directory operation + else + { + readState = READ_END; + printf("Opening directory failed\n"); + } +} + +/*...................................................................*/ +/* change_dir_callback: Callback on change directory completion */ +/* */ +/* input: file = the AsyncFATFS directory file pointer */ +/* */ +/*...................................................................*/ +static void change_dir_callback(afatfsFilePtr_t dir) +{ + if (dir) + { + afatfs_chdir(dir); + afatfs_fclose(dir, NULL); + strcat(CWD, CDDir); + strcat(CWD, "/"); + } + else + { + printf("Opening directory failed\n"); + } +} + +/*...................................................................*/ +/* Global function definitions */ +/*...................................................................*/ + +/*...................................................................*/ +/* ReadDirectory: Set up command as a read directory state machine */ +/* */ +/* input: command = the entire command */ +/* */ +/* return: TASK_IDLE until complete/error, then TASK_FINISHED */ +/*...................................................................*/ +int ReadDirectory(const char *command) +{ + if ((UsbUp) && + (afatfs_getFilesystemState() == AFATFS_FILESYSTEM_STATE_READY)) + { + if (readState == READ_INIT) + { + const char *arg1 = strchr(command, ' '), *dir; + + // If argument and too long, display error and finish task + if (arg1 && (strlen(arg1) > 16)) + { + puts("USB not up or FAT not mounted."); + return TASK_FINISHED; + } + + // Otherwise if argument skip the space to directory name + else if (arg1) + dir = &arg1[1]; + + // Otherwise use '.' for current directory + else + dir = "."; + + // Set read state to open and fopen the file with callback + readState = READ_OPEN; + afatfs_fopen(dir, "r", read_directory_callback); + } + else if (openDirectory && (readState == READ_READ)) + read_directory_callback(openDirectory); + } + else + { + puts("USB not up or FAT not mounted."); + return TASK_FINISHED; + } + + // If done close the file, clear the state variables and return finished + if (readState == READ_END) + { + afatfs_fclose(openDirectory, NULL); + openDirectory = NULL; + readState = READ_INIT; + return TASK_FINISHED; + } + else + return TASK_IDLE; +} + +/*...................................................................*/ +/* PrintWorkingDirectory: Output the current working directory */ +/* */ +/* input: command = the entire command */ +/* */ +/* return: TASK_FINISHED */ +/*...................................................................*/ +int PrintWorkingDirectory(const char *command) +{ + puts(CWD); + return TASK_FINISHED; +} + +/*...................................................................*/ +/* ChangeDirectory: Change current working directory */ +/* */ +/* input: command = the entire command */ +/* */ +/* return: TASK_FINISHED, change happens asynchronously in callback */ +/*...................................................................*/ +int ChangeDirectory(const char *command) +{ + if ((UsbUp) && + (afatfs_getFilesystemState() == AFATFS_FILESYSTEM_STATE_READY)) + { + const char *arg1 = strchr(command, ' '); + + if (!arg1 || (strlen(arg1) > 16)) + { + puts("new directory name required and 12 or less characters."); + return TASK_FINISHED; + } + + strcpy(CDDir, &arg1[1]); + if ((strcmp(CDDir, "/") == 0) || (strcmp(CDDir, "..") == 0)) + { + afatfs_chdir(NULL); + strcpy(CWD, "/"); + } + else + afatfs_fopen(CDDir, "r", change_dir_callback); + } + else + puts("USB not up or FAT not mounted."); + return TASK_FINISHED; +} + +// +/*...................................................................*/ +/* ReadFile: Set up command as a read file state machine */ +/* */ +/* input: command = the entire command */ +/* */ +/* return: TASK_IDLE until complete/error, then TASK_FINISHED */ +/*...................................................................*/ +int ReadFile(const char *command) +{ + if ((UsbUp) && + (afatfs_getFilesystemState() == AFATFS_FILESYSTEM_STATE_READY)) + { + if (readState == READ_INIT) + { + const char *arg1 = strchr(command, ' '), *file; + + // If no argument or length too long, display error and finish + if (!arg1 || (strlen(arg1) > 16)) + { + puts("filename required and <= 16 characters."); + return TASK_FINISHED; + } + + // Skip the space to file name + file = &arg1[1]; + + // Set read state to open and fopen the file with callback + readState = READ_OPEN; + afatfs_fopen(file, "r", read_file_callback); + } + else if (openDirectory && (readState == READ_READ)) + read_file_callback(openDirectory); + } + else + { + puts("USB not up or FAT not mounted."); + return TASK_FINISHED; + } + + // If done close the file, clear the state variables and return finished + if (readState == READ_END) + { + afatfs_fclose(openDirectory, NULL); + openDirectory = NULL; + readState = READ_INIT; + return TASK_FINISHED; + } + else + return TASK_IDLE; +} + +/*..................................................................*/ +/* FatPoll: poll the FAT file system */ +/* */ +/* returns: exit error */ +/*..................................................................*/ +int FatPoll(void *unused) +{ + afatfs_poll(); + return TASK_IDLE; +} + +/*..................................................................*/ +/* FatInit: initialize the FAT file system */ +/* */ +/*..................................................................*/ +void FatInit() +{ + strcpy(CWD, "/"); + afatfs_init(); +} + +/*...................................................................*/ +/* MountFAT: Initialize FAT file system */ +/* */ +/* input: command = the entire command */ +/* */ +/* return: TASK_FINISHED */ +/*...................................................................*/ +int MountFAT(char *command) +{ + if (UsbUp) + { + // Create the polling task and initialize the FAT file system +#if ENABLE_OS + TaskNew(MAX_TASKS - 4, FatPoll, NULL); +#endif + FatInit(); + } + else + puts("USB not initialized"); + + return TASK_FINISHED; +} + +#endif diff --git a/Lab20 Mass Storage/fat/fat_standard.c b/Lab20 Mass Storage/fat/fat_standard.c index c82141d..430f18a 100644 --- a/Lab20 Mass Storage/fat/fat_standard.c +++ b/Lab20 Mass Storage/fat/fat_standard.c @@ -75,4 +75,39 @@ void fat_convertFilenameToFATStyle(const char *filename, uint8_t *fatFilename) } } +/** + * Convert the FAT format stored on disk to the style filename given as "prefix.ext". + * + * filename must point to a buffer which is FAT_FILENAME_LENGTH + 1 bytes long. The buffer IS null-terminated. + */ +void fat_convertFATStyleToFilename(const char *fatFilename, char *filename) +{ + for (int i = 0; i < 8; i++) { + if (*fatFilename == ' ') { //*filename == '\0' || *filename == '.') { + *filename = '\0'; + } else { + *filename = *fatFilename; + filename++; + } + fatFilename++; + } + + if (*fatFilename != ' ') + { + *filename = '.'; + ++filename; + } + + for (int i = 0; i < 3; i++) { + if (*fatFilename == ' ') { + *filename = '\0'; + } else { + *filename = *fatFilename; + fatFilename++; + } + filename++; + } + *filename = '\0'; +} + #endif /* ENABLE_FAT */ diff --git a/Lab20 Mass Storage/fat/fat_standard.h b/Lab20 Mass Storage/fat/fat_standard.h index 26ab631..23e4323 100644 --- a/Lab20 Mass Storage/fat/fat_standard.h +++ b/Lab20 Mass Storage/fat/fat_standard.h @@ -122,3 +122,4 @@ bool fat_isDirectoryEntryTerminator(fatDirectoryEntry_t *entry); bool fat_isDirectoryEntryEmpty(fatDirectoryEntry_t *entry); void fat_convertFilenameToFATStyle(const char *filename, uint8_t *fatFilename); +void fat_convertFATStyleToFilename(const char *fatFilename, char *filename); diff --git a/Lab20 Mass Storage/fat/sdcard.c b/Lab20 Mass Storage/fat/sdcard.c index e51b780..c5ea53e 100644 --- a/Lab20 Mass Storage/fat/sdcard.c +++ b/Lab20 Mass Storage/fat/sdcard.c @@ -48,7 +48,7 @@ int MassStorageRead(void *buffer, u32 count, void (callback)(u8 *buffer, int buffLen), void *callback_payload); */ -#define MAX_OPERATIONS 1 +#define MAX_OPERATIONS 8 typedef struct OpCallback { @@ -206,20 +206,4 @@ bool sdcard_poll() */ //void sdcard_setProfilerCallback(sdcard_profilerCallback_c callback); -/*..................................................................*/ -/* FatPoll: poll the FAT file system */ -/* */ -/* returns: exit error */ -/*..................................................................*/ -int FatPoll(void *unused) -{ - afatfs_poll(); - return TASK_FINISHED; -} - -void FatInit() -{ - afatfs_init(); -} - #endif /* ENABLE_FAT */ diff --git a/Lab20 Mass Storage/fat/sdcard.h b/Lab20 Mass Storage/fat/sdcard.h index 6bd1341..50353e4 100644 --- a/Lab20 Mass Storage/fat/sdcard.h +++ b/Lab20 Mass Storage/fat/sdcard.h @@ -4,6 +4,8 @@ //#include //#include +#define SECTOR_SIZE 512 + typedef struct sdcard_metadata_t { uint8_t manufacturerID; uint16_t oemID; diff --git a/Lab20 Mass Storage/include/string.h b/Lab20 Mass Storage/include/string.h index 3a08464..88ebf39 100644 --- a/Lab20 Mass Storage/include/string.h +++ b/Lab20 Mass Storage/include/string.h @@ -53,8 +53,10 @@ extern const char *strchr(const char *string, char find); extern int strcmp(const char *string1, const char *string2); extern size_t strlen(const char *string); extern int strnlen(const char *string, int length); -extern size_t strcat(char *dst, const char *add); -#define toupper(c) (c >= 'a') || (c <= 'z') ? c - 32 : c +extern char *strcat(char *dst, const char *add); +#define toupper(c) (c >= 'a') && (c <= 'z') ? c - 32 : c +#define tolower(c) (c >= 'A') && (c <= 'Z') ? c + 32 : c +#define ischar(c) (c >= 'A') && (c <= 'z') ? TRUE : FALSE //extern char toupper(char character); #define strcpy(dst, src) memcpy(dst, src, strlen(src) + 1) #define strncpy(dst, src, len) memcpy(dst, src, min(strlen(src)+1, len)) diff --git a/Lab20 Mass Storage/include/system.h b/Lab20 Mass Storage/include/system.h index a37fcd9..98c26ec 100644 --- a/Lab20 Mass Storage/include/system.h +++ b/Lab20 Mass Storage/include/system.h @@ -133,10 +133,10 @@ typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; typedef unsigned long long uint64_t; -typedef char int8_t; -typedef short int16_t; -typedef int int32_t; -typedef long long int64_t; +typedef signed char int8_t; +typedef signed short int16_t; +typedef signed int int32_t; +typedef signed long long int64_t; #if COLOR_DEPTH_BITS == 16 #define COLOR16(red, green, blue) (((((u16)red) & 0x1F) << 11) | \ diff --git a/Lab20 Mass Storage/system/shell.c b/Lab20 Mass Storage/system/shell.c index 4258e07..06286a3 100644 --- a/Lab20 Mass Storage/system/shell.c +++ b/Lab20 Mass Storage/system/shell.c @@ -64,7 +64,14 @@ extern int MouseUp(const char *command); #endif #if ENABLE_USB_STORAGE extern int MountFilesystem(const char *command); -extern int ReadFilesystem(const char *command); +extern int ReadBlock(const char *command); +extern int ReadDirectory(const char *command); +extern int ChangeDirectory(const char *command); +extern int PrintWorkingDirectory(const char *command); +extern int ReadFile(const char *command); +#endif +#if ENABLE_FAT +extern int MountFAT(const char *command); #endif #endif /* ENABLE_USB */ @@ -352,7 +359,19 @@ int ShellInit(void) ShellCommands[++i].command = "Mount"; ShellCommands[i].function = MountFilesystem; ShellCommands[++i].command = "read"; - ShellCommands[i].function = ReadFilesystem; + ShellCommands[i].function = ReadBlock; + ShellCommands[++i].command = "dir"; + ShellCommands[i].function = ReadDirectory; + ShellCommands[++i].command = "pwd"; + ShellCommands[i].function = PrintWorkingDirectory; + ShellCommands[++i].command = "cd"; + ShellCommands[i].function = ChangeDirectory; + ShellCommands[++i].command = "cat"; + ShellCommands[i].function = ReadFile; +#endif +#if ENABLE_FAT + ShellCommands[++i].command = "fat"; + ShellCommands[i].function = MountFAT; #endif #if ENABLE_USB_HID ShellCommands[++i].command = "Keyboard"; diff --git a/Lab20 Mass Storage/system/string.c b/Lab20 Mass Storage/system/string.c index 092bd62..8484a82 100644 --- a/Lab20 Mass Storage/system/string.c +++ b/Lab20 Mass Storage/system/string.c @@ -104,14 +104,14 @@ size_t strlen(const char *string) /* Inputs: dst - the existing string appended to */ /* add - the new string to be appended to existing */ /* */ -/* Returns: Success (0) */ +/* Returns: The destination pointer (dst) on success */ /*...................................................................*/ -size_t strcat(char *dst, const char *add) +char *strcat(char *dst, const char *add) { int length = strlen(dst); /*safer : strnlen(dst, 1024);? */ - memcpy(&dst[length], add, strlen(add)); - return length; + memcpy(&dst[length], add, strlen(add) + 1); + return dst; } /*...................................................................*/