📄 file_sys.c~
字号:
** will return a 0 upon success, and an EOF on a failure.
** - Fixed bug in sub directory functions that was not checking for
** directory entries after the first cluster of entries.
**
** Version: 2.11
** Date: August 25, 2005
** Revised by: Erick M. Higa
** Description:
** - Fixed bug in fcreate() that caused lost clusters if the file
** previously existed.
**
** Version: 3.0
** Date: March 29, 2006
** Revised by: Erick M. Higa
** Description:
** - Fixed bug in fquickformat() that would stay in a while loop forever.
** - Fixed bug in fquickformat() that incorrectly calculated too many
** sectors for the root directory size.
** - Added an inititialize_media() call at the end of fquickformat() so
** the card settings are reset after completion.
** - Fixed bug in fcreate() (in v2.11) that would destroy a cluster chain
** even if it doesn't exist.
** - Fixed bug in ungetc() (since v2.00) that was not updating addr_temp
** before checking and modifying the disk.
** - Fixed bug in "cf_cmd.c" that would cause it to always use the first
** partition entry of the card.
** - _BIG_ENDIAN_ fixes made for incorrect directory entry pointers
** called.
** - Fixed bug in dump_buff_data_hex(), dump_file_entry_hex(), and
** dump_file_data_hex() that was printing the wrong debug locations.
** - Changed fseek()'s "offset" handle to a signed long, enabling you to
** go backwards from the current position of the file.
** - Fixed bug in flush() that was writing the same data to the same
** location twice.
** - Added check to mkdir that wouldn't allow the user to make a "blank"
** directory.
** - Added block writing capabilities to SD.
** - Added card reset and init between retries in _FF_read/_FF_write if
** it fails.
** - The IAR Embedded Workbench IDE Compiler is no longer supported.
** - Changed code and examples to be more MISRA compatible.
** - Bitfields no longer used in time/date routines, fixing issues with
** the ICC time/date stamp, and to make it more compatible with more
** compilers.
** - Default setting changed to use the Priio Mega128-MMC board
** (previously set for the Mega128-Net board).
**
** Version: 3.0.1
** Date: April 7, 2006
** Revised by: Erick M. Higa
** Description:
** - Fixed initialize_media() so that the active partition entry
** (reguardless if it is the first entry) will be used.
** - Fixed conditional compiles in fdemo.c and file_sys.c for _RTC_ON_
** not used.
**
*****************************************************************************/
#define _FILE_SYS_C_SRC
/*****************************************************************************
**
** MODULES USED
**
*****************************************************************************/
#if defined(_ROWLEY_CWAVR_)
#include <__cross_studio_io.h>
#include <ina90.h>
#include <pgmspace.h>
#include <stdio_c.h>
#endif
/*****************************************************************************
**
** PROTOTYPES OF LOCAL FUNCTIONS
**
*****************************************************************************/
#ifdef _NO_MALLOC_
FILE *_FF_MALLOC(void);
#endif
#if defined(_IAR_EWAVR_)
int16 _FF_strncmp(int8 *data_buff1, int8 *data_buff2, int16 n);
size_t _FF_strlen(int8 *s);
int8 *_FF_strrchr(int8 *s, int16 c);
#endif
int8 ascii_to_char(int8 ascii_char);
int8 valid_file_char(int8 file_char);
FileDirEntryStruct *scan_directory(int8 *fname, uint8 mode_flag);
uint32 clust_to_addr(uint16 clust_no);
uint16 addr_to_clust(uint32 clus_addr);
uint16 next_cluster(uint16 current_cluster, uint8 fmode);
int8 file_name_conversion(int8 *input_name, int8 *save_name);
uint16 prev_cluster(uint16 clus_no);
#ifndef _READ_ONLY_
int8 write_clus_table(uint16 current_cluster, uint16 next_value, uint8 fmode);
int8 append_toc(FILE *rp);
int8 erase_clus_chain(uint16 start_clus);
#endif
#ifdef _DIRECTORIES_SUPPORTED_
int16 _FF_checkdir(int8 *f_path, int8 *path_temp);
int8 _FF_chdir(int8 *f_path);
#endif
#if !defined(_SECOND_FAT_ON_) && !defined(_READ_ONLY_)
int16 clear_second_FAT(void);
#endif
/*****************************************************************************
**
** EXPORTED VARIABLES
**
*****************************************************************************/
flash int8 _FF_VERSION_[] = "v3.0";
#ifdef _RTC_ON_
int8 RTCHour, RTCMin, RTCSec;
int8 RTCDay, RTCMonth;
int16 RTCYear;
#endif
#ifdef _NO_MALLOC_
FILE _FF_FileSpaceAllocation[_FF_MAX_FILES_OPEN];
#endif
/*****************************************************************************
**
** GLOBAL VARIABLES
**
*****************************************************************************/
#if defined(_CVAVR_)
bit NextClusterValidFlag;
#else
uint8 NextClusterValidFlag;
#endif
uint32 _FF_ScanAddr;
#ifdef _DEBUG_ON_
flash int8 FileListStr[] = "\r\nFile Listing for: ROOT\x5c";
flash int8 SCStr[] = "]\t(%X)";
flash int8 EntryStr[] = "\t[%ld] bytes\t(%X)\t";
#endif
flash int8 VolSerialStr[] = "\r\n\tVolume Serial:\t[0x%08lX]";
flash int8 VolLabelStr[] = "\r\n\tVolume Label:\t[%s]\r\n";
#ifdef _DEBUG_SCANDIR_
flash int8 _FF_ScanDirStartStr[] = "\r\nSCAN_DIRECTORY(\"%s\", 0x%lX, Mode-%d) - ";
flash int8 _FF_ScanDirDebugStr[] = "\t[ScanDirHere-%02d](%lX)";
flash int8 _FF_ScanDirInfoStr[] = "\t[%s=?%s]";
#endif
#ifdef _DEBUG_C2A_
flash int8 _FF_Clus2AddrErrStr[] = "\r\n[Clus2AddrErr-0x%X]";
#endif
#ifdef _DEBUG_A2C_
flash int8 _FF_Addr2ClusErrStr[] = "\r\n[Addr2ClusErr-%d,0x%X]";
#endif
#ifdef _DEBUG_NEXTCLUS_
flash int8 _FF_NextClusDebugStr[] = "\tNextClusHere-%02d";
flash int8 _FF_NextClusInfoStr[] = "\r\nNextClus(%X,%d)";
#endif
#ifdef _DEBUG_PREVCLUS_
flash int8 _FF_PrevClusDebugStr[] = "\tPrevClusHere-%02d";
flash int8 _FF_PrevClusInfoStr[] = "\r\nPrevClus(%X)";
#endif
#ifdef _DEBUG_WRITE_CLUSTER_TABLE_
flash int8 _FF_WriteClusterDebugStr[] = "\tWriteClusERR-%02d";
flash int8 _FF_WriteClusterInfoStr[] = "\r\nWriteClus(%X,%X,%d)";
#endif
#ifdef _DEBUG_APPRNDTOC_
flash int8 _FF_AppendTOCDebugStr[] = "\tAppendTOCERR-%02d";
flash int8 _FF_AppendTOCAddrStr[] = "\r\nAddress Entry @ 0x%lX - APPENDTOC";
#endif
#ifdef _DEBUG_MKDIR_
flash int8 _FF_MkDirDebugStr[] = "\tMakeDirHere-%02d";
#endif
flash int8 _FF_TimeDateStr[] = "%02d/%02d/%04d %02d:%02d:%02d";
#ifdef _DEBUG_CHDIR_
flash int8 _FF_ChDirDebugStr[] = "\tChDirHere-%02d";
flash int8 _FF_ChDirValStr[] = " %02X";
#endif
#ifdef _DEBUG_FF_CHDIR_
flash int8 _FF_FFChDirDebugStr[] = "\tFFChDir-%02d";
#endif
#ifdef _DEBUG_FOPEN_
flash int8 _FF_FOpenDebugStr[] = "\r\nFopenERR-%02d";
flash int8 _FF_FOpenDetailsStr[] = "\r\nOpened [mode = %d]:\r\n ";
#endif
#ifdef _DEBUG_FCREATE_
flash int8 _FF_FCreateDebugStr[] = "\tFcreateERR-%02d";
flash int8 _FF_FCreateInfoStr[] = "\r\nFCREATE(\"%s\", %d";
flash int8 _FF_FCreateAddrStr[] = "\r\nAddress Entry @ 0x%lX - FCREATE";
#endif
#ifdef _DEBUG_FFLUSH_
flash int8 _FF_FFlushDebugStr[] = "\tFFlushHere-%02d";
flash int8 _FF_FFlushStr[] = "\r\nFFLUSH Called";
#endif
#ifdef _DEBUG_FPUTC_
flash int8 _FF_FPutcDebugStr[] = "\tFPutcERR-%02d";
flash int8 _FF_FPutcInfoStr[] = "\r\nFPUTC(%X)";
#endif
#if defined(_DEBUG_ON_) && !defined(_NO_FILE_DATA_BUFFER_)
flash int8 _FF_BuffAddrStr[] = "\r\n_FF_buff @ 0x%08lX";
#endif
#ifdef _DEBUG_STREAM_START_
flash int8 _FF_StreamErrStr[] = " - StreamError%02d";
flash int8 _FF_StreamErrPlusStr[] = " - StreamError%02d[i=%X]";
flash int8 _FF_BlockofClustStr[] = "\r\nFind Block of 0x%X Clusters";
flash int8 _FF_FoundBlockofClustStr[] = "\r\nFound Block of [%X] Clusters starting at clus [%X] ";
#endif
/*****************************************************************************
**
** EXPORTED FUNCTIONS
**
*****************************************************************************/
#ifdef _DEBUG_ON_
/****************************************************************************
**
** Function to display all files and folders in the root directory, with the
** size of the file in bytes within the [brakets]
**
** Parameters: None
**
** Returns: None
**
****************************************************************************/
void read_directory(void)
{
uint8 valid_flag;
uint16 c, n, d, m, ent_max;
FileDirEntryStruct *dep;
#ifdef _DIRECTORIES_SUPPORTED_
uint32 dir_addr;
uint16 dir_clus;
if(_FF_DirAddr != _FF_RootAddr)
{
dir_clus = addr_to_clust(_FF_DirAddr);
if(dir_clus < 2)
return;
}
#endif
_FF_printf(FileListStr);
#ifdef _DIRECTORIES_SUPPORTED_
for(d = 0; ((d < _FF_PATH_LENGTH) && _FF_FullPath[d]); d++)
_FF_putchar(_FF_FullPath[d]);
if(_FF_DirAddr == _FF_RootAddr)
ent_max = BPB_RootEntCnt.uval16;
else
#ifdef _BYTES_PER_SEC_512_
ent_max = ((uint16) BPB_SecPerClus) << 4;
#else
ent_max = BPB_BytsPerSec.uval16 / sizeof(FileDirEntryStruct) * BPB_SecPerClus;
#endif
dir_addr = _FF_DirAddr;
#else
ent_max = BPB_RootEntCnt.uval16;
#endif
d = 0;
m = 0;
while(d < ent_max)
{
#ifdef _DIRECTORIES_SUPPORTED_
if(_FF_read(dir_addr + m, _FF_Buff))
#else
if(_FF_read(_FF_RootAddr + m, _FF_Buff))
#endif
break;
dep = (FileDirEntryStruct *) _FF_Buff;
#ifdef _BYTES_PER_SEC_512_
for(n = 0; n < 16; n++)
#else
for(n = 0; n < (BPB_BytsPerSec.uval16 / sizeof(FileDirEntryStruct)); n++)
#endif
{
valid_flag = 1;
if(dep->name_entry[0] == 0)
{
/* a '\0' in this location means no more entries avaliable */
return; /* clear entries */
}
for(c = 0; ((c < 11) && valid_flag); c++)
{
/* make sure all the characters in the file/folder name are valid */
if(valid_file_char(dep->name_entry[c]) == 0)
valid_flag = 0;
}
if(valid_flag)
{
_FF_putchar('\r');
_FF_putchar('\n');
_FF_putchar('\t');
if((dep->attr) & ATTR_DIRECTORY)
_FF_putchar('[');
for(c = 0; c < 8; c++)
{
if(dep->name_entry[c] == 0x20)
c = 8;
else
_FF_putchar(dep->name_entry[c]);
}
if((dep->attr) & ATTR_DIRECTORY)
{
_FF_printf(SCStr, dep->start_clus_lo);
}
else
{
_FF_putchar('.');
for(c = 8; c < 11; c++)
{
if((dep->name_entry[c]) == 0x20)
c = 11;
else
_FF_putchar(dep->name_entry[c]);
}
_FF_printf(EntryStr, dep->file_size, dep->start_clus_lo);
}
} /*if(valid_flag)*/
dep++;
d++;
} /*for(n = 0; n < 16; n++)*/
m++;
#ifdef _DIRECTORIES_SUPPORTED_
if(_FF_RootAddr != _FF_DirAddr)
{
if(m == BPB_SecPerClus)
{
m = next_cluster(dir_clus, SINGLE);
if((m < 0xFFF8) && (NextClusterValidFlag))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -