Skip to content

Commit

Permalink
Wrote fat-sd module to simplify SD card access.
Browse files Browse the repository at this point in the history
  • Loading branch information
Chadderz121 committed Mar 31, 2014
1 parent 2a68524 commit af1d192
Show file tree
Hide file tree
Showing 5 changed files with 472 additions and 1 deletion.
204 changes: 204 additions & 0 deletions bslug_include/io/fat-sd.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
/* io/fat-sd.h
* by Alex Chadwick
*
* Copyright (C) 2014, Alex Chadwick
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/

/* A simple helper-wrapper around libfat and libsd to allow mounting and using
* of FAT formatted sd cards. */

#ifndef _IO_FAT_SD_H_
#define _IO_FAT_SD_H_

#include <io/fat.h>
#include <io/libsd.h>

/* Call this before any other methods. The first module to call SD_Mount
* performs that actual FAT mounting procedure. Returns 0 on sucess. Sets errno.
*/
int SD_Mount(void);

/******************************************************************************/
/* File handling */

/* Open a file.
* fileStruct - buffer to store file information in.
* path - path of file.
* flags - open flags from <fcntl.h> O_RDONLY, O_RDWR, O_WRONLY, O_CREAT,
* O_APPEND, O_TRUNC
* Returns -1 on error or a fd for use in other file calls. Sets errno. */
static inline int SD_open(FILE_STRUCT *fileStruct, const char *path, int flags);
/* Close a file and synch to device. Returns 0 on success. */
static inline int SD_close(int fd);
/* Write to a file.
* Returns number of bytes successfully written (or -1 on error). Sets errno. */
static inline ssize_t SD_write(int fd, const char *ptr, size_t len);
/* Read from a file.
* Returns number of bytes successfully read (or -1 on error). Sets errno. */
static inline ssize_t SD_read(int fd, char *ptr, size_t len);
/* Seek within file. dir is one of SEEK_SET, SEEK_CUR or SEEK_END (stdio.h).
* Returns new absolute position (or -1 on error). Sets errno. */
static inline off_t SD_seek(int fd, off_t pos, int dir);

/* Shortens (or expands) a file to specified length.
* Returns 0 on success. Sets errno. */
static inline int SD_ftruncate(int fd, off_t len);
/* Synchronises a file to the device. This call does not return until all
* prior write calls to this file have been sent to the device.
* Returns 0 on success. Sets errno. */
static inline int SD_fsync(int fd);
/* Fills in the st buffer with metadata about the file.
* Returns 0 on success. Sets errno. */
static inline int SD_fstat(int fd, struct stat *st);

/******************************************************************************/
/* File system manipulation */

/* Gets the DOS file attributes of the specified file.
* Returns -1 on error. Does not set errno. */
static inline FILE_ATTR SD_getAttr(const char *file);
/* Sets the DOS file attributes of the specified file.
* Returns 0 on success. Does not set errno. */
static inline int SD_setAttr(const char *file, FILE_ATTR attr);

/* Fills in the st buffer with metadata about the specified file.
* Returns 0 on success. Sets errno. */
static inline int SD_stat(const char *path, struct stat *st);
/* Fills in the st buffer with metadata about the specified filesystem.
* Returns 0 on success. Sets errno. */
static inline int SD_statvfs(const char *path, struct statvfs *buf);

/* Deletes the specified file.
* Returns 0 on success. Sets errno. */
static inline int SD_unlink(const char *name);
/* Renames (or moves) a file from one name to another.
* Returns 0 on success. Sets errno. */
static inline int SD_rename(const char *oldName, const char *newName);

/* Sets the path for all future relative file paths.
* Returns 0 on success. Sets errno. */
static inline int SD_chdir(const char *name);

/* Creates the specified directory.
* Returns 0 on success. Sets errno. */
static inline int SD_mkdir(const char *path);

/******************************************************************************/
/* Directory listing */

/* Opens a directory for listing purposes.
* state - buffer in which to store directory information.
* path - path to the directory.
* Returns NULL on error. Sets errno. */
static inline DIR_STATE_STRUCT* SD_diropen(
DIR_STATE_STRUCT *state, const char *path);
/* Resets a directory iterator.
* Returns 0 on success. Sets errno. */
static inline int SD_dirreset(DIR_STATE_STRUCT *state);
/* Moves to the next file in a directory.
* state - iterator to advance
* filename - buffer in which to store name of next file. Will not exceed
* MAX_FILENAME_LENGTH.
* filestat - buffer in which to store metadata about the next file.
* Returns 0 on success. Sets errno.
* Returns -1 and sets errno to ENOENT if no more files avilable. */
static inline int SD_dirnext(
DIR_STATE_STRUCT *state, char *filename, struct stat *filestat);
/* Closes a directory iterator.
* Returns 0 on success. Sets errno. */
static inline int SD_dirclose(DIR_STATE_STRUCT *state);

/******************************************************************************/

extern PARTITION sd_partition;

static inline int SD_open(
FILE_STRUCT *fileStruct, const char *path, int flags) {
return FAT_open(fileStruct, &sd_partition, path, flags);
}
static inline int SD_close(int fd) {
return FAT_close(fd);
}
static inline ssize_t SD_write(int fd, const char *ptr, size_t len) {
return FAT_write(fd, ptr, len);
}
static inline ssize_t SD_read(int fd, char *ptr, size_t len) {
return FAT_read(fd, ptr, len);
}
static inline off_t SD_seek(int fd, off_t pos, int dir) {
return FAT_seek(fd, pos, dir);
}

static inline int SD_ftruncate(int fd, off_t len) {
return FAT_ftruncate(fd, len);
}
static inline int SD_fsync(int fd) {
return FAT_fsync(fd);
}
static inline int SD_fstat(int fd, struct stat *st) {
return FAT_fstat(fd, st);
}

static inline FILE_ATTR SD_getAttr(const char *file) {
return FAT_getAttr(&sd_partition, file);
}
static inline int SD_setAttr(const char *file, FILE_ATTR attr) {
return FAT_setAttr(&sd_partition, file, attr);
}

static inline int SD_stat(const char *path, struct stat *st) {
return FAT_stat(&sd_partition, path, st);
}
static inline int SD_statvfs(const char *path, struct statvfs *buf) {
return FAT_statvfs(&sd_partition, path, buf);
}

static inline int SD_unlink(const char *name) {
return FAT_unlink(&sd_partition, name);
}
static inline int SD_rename(const char *oldName, const char *newName) {
return FAT_rename(&sd_partition, oldName, newName);
}

static inline int SD_chdir(const char *name) {
return FAT_chdir(&sd_partition, name);
}

static inline int SD_mkdir(const char *path) {
return FAT_mkdir(&sd_partition, path);
}

static inline DIR_STATE_STRUCT* SD_diropen(
DIR_STATE_STRUCT *state, const char *path) {
return FAT_diropen(state, &sd_partition, path);
}
static inline int SD_dirreset(DIR_STATE_STRUCT *state) {
return FAT_dirreset(state);
}
static inline int SD_dirnext(
DIR_STATE_STRUCT *state, char *filename, struct stat *filestat) {
return FAT_dirnext(state, filename, filestat);
}
static inline int SD_dirclose(DIR_STATE_STRUCT *state) {
return FAT_dirclose(state);
}

#endif /* _IO_FAT_SD_H_ */
2 changes: 1 addition & 1 deletion bslug_include/io/fat.h
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ enum FILE_ATTR {
FILE_ATTR FAT_getAttr(PARTITION *partition, const char *file);
/* Sets the DOS file attributes of the specified file.
* Returns 0 on success. Does not set errno. */
int FAT_setAttr(PARTITION *partition, const char *file, FILE_ATTR attr);
int FAT_setAttr(PARTITION *partition, const char *file, FILE_ATTR attr);

/* Fills in the st buffer with metadata about the specified file.
* Returns 0 on success. Sets errno. */
Expand Down
175 changes: 175 additions & 0 deletions modules/libfat-sd/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
###############################################################################
# Makefile
# by Alex Chadwick
#
# A makefile script for generation of a brainslug module
###############################################################################
# Hopefully you shouldn't need to change anything in this file.
# Alter makefile.mk to change common settings.

###############################################################################
# devkitpro settings
ifeq ($(strip $(DEVKITPRO)),)
$(error "Please set DEVKITPRO in your environment. export DEVKITPRO=<path to>devkitPro")
endif
ifeq ($(strip $(DEVKITPPC)),)
$(error "Please set DEVKITPPC in your environment. export DEVKITPPC=<path to>devkitPPC")
endif

BSLUGDIR := $(DEVKITPRO)/bslug

PATH := $(DEVKITPPC)/bin:$(PATH)
LIB_INC_DIRS := $(DEVKITPPC)/lib/gcc/powerpc-eabi/4.6.3/include \
$(DEVKITPPC)/lib/gcc/powerpc-eabi/4.6.3/include-fixed \
$(BSLUGDIR)/include

include makefile.mk

###############################################################################
# Parameters

# A comma to make writing commands easier
C := ,
# Used to suppress command echo.
Q ?= @
LOG ?= @echo $@
# The intermediate directory for compiled object files.
BUILD ?= build
# The name of the assembler listing file to generate.
LIST ?= $(TARGET:.mod=.list)
# The name of the map file to generate.
MAP ?= $(TARGET:.mod=.map)

INC_DIRS += $(LIB_INC_DIRS)

###############################################################################
# Compiler settings

# The toolchain to use.
PREFIX = powerpc-eabi-
# Tools to use
AS = $(PREFIX)as
LD = $(PREFIX)ld
CC = $(PREFIX)g++
OBJDUMP = $(PREFIX)objdump

# --relocatable: make sure ld doesn't remove relocations bslug will need
# -s: strip local symbols to speed linking
# --gc-sections: remove unneeded symbols
# -T: use the linker script specified (to force certain bslug sections together)
# -Map: generate a map file
LDFLAGS += --relocatable -s --gc-sections -u bslug_load -u bslug_meta \
-T $(BSLUGDIR)/bslug.ld \
$(patsubst %,-Map %,$(strip $(MAP)))
LD1FLAGS += --relocatable -s \
-T $(BSLUGDIR)/bslug_elf.ld

# -O2: optimise lots
# -Wall: generate lots of warnings
# -x c: compile as C code
# -std=gnu99: use the C99 standard with GNU extensions
# -nostdinc: don't include standard headers (we don't have all the symbols)
# -ffreestanding: we don't have libc; don't expect we do
# -DGEKKO: define the symbol GEKKO (used in some libogc headers)
# -DHW_RVL: define the symbol HW_RVL (used in some libogc headers)
# -D__wii__: define the symbol __wii__ (used in some libogc headers)
# -mrvl: enable wii/gamecube compilation
# -mcpu=750: enable processor specific compilation
# -meabi: enable eabi specific compilation
# -mhard-float: enable hardware floating point instructions
# -fshort-wchar: use 16 bit whcar_t type in keeping with Wii executables
# -fno-common: stop common variables which the loader can't understand
# -msdata-none: do not use r2 or r13 as small data areas
# -memb: enable embedded application specific compilation
# -ffunction-sections: split up functions so linker can garbage collect
# -fdata-sections: split up data so linker can garbage collect
CFLAGS += -O2 -Wall -x c -std=gnu99 \
-nostdinc -ffreestanding \
-DGEKKO -DHW_RVL -D__wii__ \
-mrvl -mcpu=750 -meabi -mhard-float -fshort-wchar -fno-common \
-msdata=none -memb -ffunction-sections -fdata-sections

ifdef DEBUG
else
CFLAGS += -DNDEBUG
endif

###############################################################################
# Variable init

# Phony targets
PHONY :=

###############################################################################
# Rule to make everything.
PHONY += all

all : $(TARGET)

###############################################################################
# Derived rules

LDFLAGS += $(patsubst %,-l %,$(LIBS)) $(patsubst %,-l %,$(LIBS)) \
$(patsubst %,-L %,$(LIB_DIRS)) $(patsubst %,-L %/lib,$(LIB_DIRS))
CFLAGS += $(patsubst %,-I %,$(INC_DIRS)) \
$(patsubst %,-I %/include,$(LIB_DIRS)) -iquote src

OBJECTS := $(patsubst %.c,$(BUILD)/%.c.o,$(filter %.c,$(SRC)))

###############################################################################
# Special build rules

# Rule to make the module file.
$(TARGET) : $(BUILD)/output.elf $(BIN)
$(LOG)
-$Qmkdir -p $(dir $@)
$Q$(LD) $(BUILD)/output.elf $(LDFLAGS) -o $@

# Rule to make the module file.
$(BUILD)/output.elf : $(OBJECTS) $(BUILD)
$(LOG)
-$Qmkdir -p $(dir $@)
$Q$(LD) $(OBJECTS) $(LD1FLAGS) -o $@

# Rule to make intermediate directory
$(BUILD) :
-$Qmkdir $@

# Rule to make output directory
$(BIN) :
-$Qmkdir $@

###############################################################################
# Standard build rules

$(BUILD)/%.c.o: %.c
$(LOG)
-$Qmkdir -p $(dir $@)
$Q$(CC) -c $(CFLAGS) $< -o $@

###############################################################################
# Assembly listing rules

# Rule to make assembly listing.
PHONY += list
list : $(LIST)

# Rule to make the listing file.
%.list : $(TARGET)
$(LOG)
-$Qmkdir -p $(dir $@)
$Q$(OBJDUMP) -d $< > $@

###############################################################################
# Clean rule

# Rule to clean files.
PHONY += clean
clean :
-$Qrm -rf $(BUILD)
-$Qrm -rf $(BIN)

###############################################################################
# Phony targets

.PHONY : $(PHONY)
Loading

0 comments on commit af1d192

Please sign in to comment.