📄 sd_card.c
字号:
//*****************************************************************************
//
// sd_card.c - Example program for reading files from an SD card.
//
// Copyright (c) 2007 Luminary Micro, Inc. All rights reserved.
//
// Software License Agreement
//
// Luminary Micro, Inc. (LMI) is supplying this software for use solely and
// exclusively on LMI's microcontroller products.
//
// The software is owned by LMI and/or its suppliers, and is protected under
// applicable copyright laws. All rights are reserved. You may not combine
// this software with "viral" open-source software in order to form a larger
// program. Any use in violation of the foregoing restrictions may subject
// the user to criminal sanctions under applicable laws, as well as to civil
// liability for the breach of the terms and conditions of this license.
//
// THIS SOFTWARE IS PROVIDED "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED
// OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF
// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE APPLY TO THIS SOFTWARE.
// LMI SHALL NOT, IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL, OR
// CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
//
// This is part of revision 1952 of the Stellaris Peripheral Driver Library.
//
//*****************************************************************************
#include <string.h>
#include "../../../hw_types.h"
#include "../../../hw_memmap.h"
#include "../../../src/sysctl.h"
#include "../../../src/gpio.h"
#include "../../../src/systick.h"
#include "../../../src/interrupt.h"
#include "../../../utils/uartstdio.h"
#include "../../../utils/cmdline.h"
#include "../../../third_party/fatfs/src/ff.h"
#include "../../../third_party/fatfs/src/diskio.h"
//*****************************************************************************
//
//! \addtogroup ek_lm3s6965_revc_list
//! <h1>SD card using FAT file system (sd_card)</h1>
//!
//! This example application demonstrates reading a file system from
//! an SD card. It makes use of FatFs, a FAT file system driver. It
//! provides a simple command console via a serial port for issuing commands
//! to view and navigate the file system on the SD card.
//!
//! The first UART, which is connected to the FTDI virtual serial port
//! on the Stellaris LM3S6965 Evaluation Board, is configured for 115,200
//! bits per second, and 8-n-1 mode. When the program is started a message
//! will be printed to the terminal. Type ``help'' for command help.
//!
//! For additional details about FatFs, see the following site:
//! http://elm-chan.org/fsw/ff/00index_e.html
//
//*****************************************************************************
//*****************************************************************************
//
// Defines the size of the buffers that hold the path, or temporary
// data from the SD card. There are two buffers allocated of this size.
// The buffer size must be large enough to hold the longest expected
// full path name, including the file name, and a trailing null character.
//
//*****************************************************************************
#define PATH_BUF_SIZE 80
//*****************************************************************************
//
// Defines the size of the buffer that holds the command line.
//
//*****************************************************************************
#define CMD_BUF_SIZE 64
//*****************************************************************************
//
// This buffer holds the full path to the current working directory.
// Initially it is root ("/").
//
//*****************************************************************************
static char g_cCwdBuf[PATH_BUF_SIZE] = "/";
//*****************************************************************************
//
// A temporary data buffer used when manipulating file paths, or reading data
// from the SD card.
//
//*****************************************************************************
static char g_cTmpBuf[PATH_BUF_SIZE];
//*****************************************************************************
//
// The buffer that holds the command line.
//
//*****************************************************************************
static char g_cCmdBuf[CMD_BUF_SIZE];
//*****************************************************************************
//
// The following are data structures used by FatFs.
//
//*****************************************************************************
static FATFS g_sFatFs;
static DIR g_sDirObject;
static FILINFO g_sFileInfo;
static FIL g_sFileObject;
//*****************************************************************************
//
// A structure that holds a mapping between an FRESULT numerical code,
// and a string represenation. FRESULT codes are returned from the FatFs
// FAT file system driver.
//
//*****************************************************************************
typedef struct
{
FRESULT fresult;
char *pcResultStr;
}
tFresultString;
//*****************************************************************************
//
// A macro to make it easy to add result codes to the table.
//
//*****************************************************************************
#define FRESULT_ENTRY(f) { (f), (#f) }
//*****************************************************************************
//
// A table that holds a mapping between the numerical FRESULT code and
// it's name as a string. This is used for looking up error codes for
// printing to the console.
//
//*****************************************************************************
tFresultString g_sFresultStrings[] =
{
FRESULT_ENTRY(FR_OK),
FRESULT_ENTRY(FR_NOT_READY),
FRESULT_ENTRY(FR_NO_FILE),
FRESULT_ENTRY(FR_NO_PATH),
FRESULT_ENTRY(FR_INVALID_NAME),
FRESULT_ENTRY(FR_INVALID_DRIVE),
FRESULT_ENTRY(FR_DENIED),
FRESULT_ENTRY(FR_EXIST),
FRESULT_ENTRY(FR_RW_ERROR),
FRESULT_ENTRY(FR_WRITE_PROTECTED),
FRESULT_ENTRY(FR_NOT_ENABLED),
FRESULT_ENTRY(FR_NO_FILESYSTEM),
FRESULT_ENTRY(FR_INVALID_OBJECT),
FRESULT_ENTRY(FR_MKFS_ABORTED)
};
//*****************************************************************************
//
// A macro that holds the number of result codes.
//
//*****************************************************************************
#define NUM_FRESULT_CODES (sizeof(g_sFresultStrings) / sizeof(tFresultString))
//*****************************************************************************
//
// This function returns a string representation of an error code
// that was returned from a function call to FatFs. It can be used
// for printing human readable error messages.
//
//*****************************************************************************
const char *
StringFromFresult(FRESULT fresult)
{
unsigned int uIdx;
//
// Enter a loop to search the error code table for a matching
// error code.
//
for(uIdx = 0; uIdx < NUM_FRESULT_CODES; uIdx++)
{
//
// If a match is found, then return the string name of the
// error code.
//
if(g_sFresultStrings[uIdx].fresult == fresult)
{
return(g_sFresultStrings[uIdx].pcResultStr);
}
}
//
// At this point no matching code was found, so return a
// string indicating unknown error.
//
return("UNKNOWN ERROR CODE");
}
//*****************************************************************************
//
// This is the handler for this SysTick interrupt. FatFs requires a
// timer tick every 10 ms for internal timing purposes.
//
//*****************************************************************************
void
SysTickHandler(void)
{
//
// Call the FatFs tick timer.
//
disk_timerproc();
}
//*****************************************************************************
//
// This function implements the "ls" command. It opens the current
// directory and enumerates through the contents, and prints a line for
// each item it finds. It shows details such as file attributes, time and
// date, and the file size, along with the name. It shows a summary of
// file sizes at the end along with free space.
//
//*****************************************************************************
int
Cmd_ls(int argc, char *argv[])
{
unsigned long ulTotalSize;
unsigned long ulFileCount;
unsigned long ulDirCount;
FRESULT fresult;
FATFS *pFatFs;
//
// Open the current directory for access.
//
fresult = f_opendir(&g_sDirObject, g_cCwdBuf);
//
// Check for error and return if there is a problem.
//
if(fresult != FR_OK)
{
return(fresult);
}
ulTotalSize = 0;
ulFileCount = 0;
ulDirCount = 0;
//
// Give an extra blank line before the listing.
//
UARTprintf("\n");
//
// Enter loop to enumerate through all directory entries.
//
for(;;)
{
//
// Read an entry from the directory.
//
fresult = f_readdir(&g_sDirObject, &g_sFileInfo);
//
// Check for error and return if there is a problem.
//
if(fresult != FR_OK)
{
return(fresult);
}
//
// If the file name is blank, then this is the end of the
// listing.
//
if(!g_sFileInfo.fname[0])
{
break;
}
//
// If the attribue is directory, then increment the directory count.
//
if(g_sFileInfo.fattrib & AM_DIR)
{
ulDirCount++;
}
//
// Otherwise, it is a file. Increment the file count, and
// add in the file size to the total.
//
else
{
ulFileCount++;
ulTotalSize += g_sFileInfo.fsize;
}
//
// Print the entry information on a single line with formatting
// to show the attributes, date, time, size, and name.
//
UARTprintf("%c%c%c%c%c %u/%02u/%02u %02u:%02u %9u %s\n",
(g_sFileInfo.fattrib & AM_DIR) ? 'D' : '-',
(g_sFileInfo.fattrib & AM_RDO) ? 'R' : '-',
(g_sFileInfo.fattrib & AM_HID) ? 'H' : '-',
(g_sFileInfo.fattrib & AM_SYS) ? 'S' : '-',
(g_sFileInfo.fattrib & AM_ARC) ? 'A' : '-',
(g_sFileInfo.fdate >> 9) + 1980,
(g_sFileInfo.fdate >> 5) & 15,
g_sFileInfo.fdate & 31,
(g_sFileInfo.ftime >> 11),
(g_sFileInfo.ftime >> 5) & 63,
g_sFileInfo.fsize,
g_sFileInfo.fname);
} // endfor
//
// Print summary lines showing the file, dir, and size totals.
//
UARTprintf("\n%4u File(s),%10u bytes total\n%4u Dir(s)",
ulFileCount, ulTotalSize, ulDirCount);
//
// Get the free space.
//
fresult = f_getfree("/", &ulTotalSize, &pFatFs);
//
// Check for error and return if there is a problem.
//
if(fresult != FR_OK)
{
return(fresult);
}
//
// Display the amount of free space that was calculated.
//
UARTprintf(", %10uK bytes free\n", ulTotalSize * pFatFs->sects_clust / 2);
//
// Made it to here, return with no errors.
//
return(0);
}
//*****************************************************************************
//
// This function implements the "cd" command. It takes an argument
// that specifes the directory to make the current working directory.
// Path separators must use a forward slash "/". The argument to cd
// can be one of the following:
// * root ("/")
// * a fully specified path ("/my/path/to/mydir")
// * a single directory name that is in the current directory ("mydir")
// * parent directory ("..")
//
// It does not understand relative paths, so dont try something like this:
// ("../my/new/path")
//
// Once the new directory is specified, it attempts to open the directory
// to make sure it exists. If the new path is opened successfully, then
// the current working directory (cwd) is changed to the new path.
//
//*****************************************************************************
int
Cmd_cd(int argc, char *argv[])
{
unsigned int uIdx;
FRESULT fresult;
//
// Copy the current working path into a temporary buffer so
// it can be manipulated.
//
strcpy(g_cTmpBuf, g_cCwdBuf);
//
// If the first character is /, then this is a fully specified
// path, and it should just be used as-is.
//
if(argv[1][0] == '/')
{
//
// Make sure the new path is not bigger than the cwd buffer.
//
if(strlen(argv[1]) + 1 > sizeof(g_cCwdBuf))
{
UARTprintf("Resulting path name is too long\n");
return(0);
}
//
// If the new path name (in argv[1]) is not too long, then
// copy it into the temporary buffer so it can be checked.
//
else
{
strncpy(g_cTmpBuf, argv[1], sizeof(g_cTmpBuf));
}
}
//
// If the argument is .. then attempt to remove the lowest level
// on the CWD.
//
else if(!strcmp(argv[1], ".."))
{
//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -