📄 ffile.c
字号:
/******************************************************************
* ffile.c: Flash File System
*
* Copyright (c) 2001 Atmel Corporation.
* All Rights Reserved.
*
* You are autorized to use, copy and distribute this software only at
* a single site (the term "site" meaning a single company location).
* This copyright notice must be included in any copy, modification
* or portion of this software merged into another program.
*
* This software is licenced solely for use with Atmel AVR micro
* controller family. The software may not be modified to execute on
* any other microcontroller architectures
*
* This software is provided "as is"; Without warranties either express
* or implied, including any warranty regarding merchantability,
* fitness for a particular purpose or noninfringement.
*
* In no event shall Atmel or its suppliers be liable for any special,
* indirect,incidential or concequential damages resulting from the
* use or inability to use this software.
*
* Revision history:
*
* January 17, 2001: Version 1.0 Created by JB
* July 13, 2001 Version 1.2 JB
* - Changed to IAR compiler V2.25
* - Renamed flash file functions to avoid conflict with
* standard file I/O names
* - Bug fixes in HTTP
* - Speed optimization in TCP
*
*
*******************************************************************/
#include "ffile.h"
#include "dataflash.h"
#include "string.h"
#include "stdio.h"
void Send (unsigned char *string);
FFILE file[FILE_MAX_OPEN_FILES];
DIR directory;
unsigned int lastWrittenPage;
/*format the file system and write a Media Status Table to EEPROM*/
void fformat(void)
{
unsigned char buffer[80]; //Could be removed after debug
unsigned int x;
buffer[FILE_MST_STATUS] = FILE_OK;
buffer[FILE_MST_FREE_SPACE_l] = 0;
buffer[FILE_MST_FREE_SPACE_h] = 4;
buffer[FILE_MST_DEALLOCATED_SPACE_l] = 0;
buffer[FILE_MST_DEALLOCATED_SPACE_h] = 0;
buffer[FILE_MST_DEALLOCATED_NEXT_l] = 0;
buffer[FILE_MST_DEALLOCATED_NEXT_h] = 0;
buffer[FILE_MST_FILE_ID_NEXT_l] = 0;
buffer[FILE_MST_FILE_ID_NEXT_h] = 0;
buffer[FILE_MST_LAST_PAGE_l] = 0;
buffer[FILE_MST_LAST_PAGE_h] = 0;
for (x=0;x<32;x++)
{
buffer[FILE_MST_DEALLOCATED_PTRS+x] = 0xff;
}
for (x=0;x<77;x++)
{
EEput(FILE_MST_BASE+x, buffer[x]);
}
saveMST();
}
/*Open a file for reading or writing. Only one file can be open
for writing at a time.*/
FFILE *ffopen(char *fileName, char type)
{
FFILE *stream;
char *str,x, filename[8], fileext[3], filen[12];
unsigned int j;
strncpy(filen, fileName, 12);
str = strtok(filen, ".");
strncpy(filename, str, 8);
str = strtok(NULL, " \r\n");
strncpy(fileext, str, 3);
if (type == 'r')
{
j=ffindFile(filename, fileext); //Check if file exists.
if (j != FILE_FNULL)
{
for (x=0;x<FILE_MAX_OPEN_FILES;x++) //Find a free FILE structure
{
if (file[x].status == FILE_READY) //Prepare FILE struct for file.
{
stream = &file[x];
strncpy(stream->file_name, filename, 8);
strncpy(stream->file_ext, fileext, 3);
stream->start_page = j;
read_page(j, stream->buffer, 40);
stream->file_id = stream->buffer[FILE_ID_h]*256 + stream->buffer[FILE_ID_l];
stream->file_size = (stream->buffer[FILE_SIZE_ll]&0xff);
stream->file_size += ((stream->buffer[FILE_SIZE_lh]<<8)&0xff00);
stream->file_size += (unsigned long)((stream->buffer[FILE_SIZE_hl])*0x10000);
stream->file_size += (unsigned long)((stream->buffer[FILE_SIZE_hh])*0x1000000);
stream->end_page = stream->start_page + stream->buffer[FILE_NUM_PAGES_h]*256 + stream->buffer[FILE_NUM_PAGES_l];
stream->status = FILE_READ;
stream->start_page++;
stream->count = 0;
read_page(stream->start_page++, stream->buffer, FLASH_PAGE_SIZE);
return stream; //return FILE ptr.
}
}
}
return NULL;
}
else if (type == 'w')
{
for (x=0;x<FILE_MAX_OPEN_FILES;x++)
{
if (file[x].status == FILE_WRITE) //Check if there are other files open for writing.
{
return NULL;
}
}
if (ffindFile(filename,fileext)!= FILE_FNULL)//Check if file exists.
{
return NULL;
}
for (x=0;x<FILE_MAX_OPEN_FILES;x++)
{
if (file[x].status == FILE_READY) //find free FILE struct.
{
stream = &file[x];
stream->start_page = EEgetInt(FILE_MST_BASE+FILE_MST_LAST_PAGE_l); //Find starting page of file.
if (stream->start_page > 1022)
{
return NULL;
}
stream->status = FILE_WRITE;
stream->file_id = 0; //file ID is optional
strncpy(stream->file_name, filename, 8);
strncpy(stream->file_ext, fileext, 3);
stream->file_size = 0;
stream->count = 0;
stream->end_page = stream->start_page+1;
lastWrittenPage = stream->end_page;
return stream;
}
}
return NULL;
}
else
{
return NULL;
}
}
int ffindFile(char *file_name, char *file_ext)
{
unsigned int nextPage=0, last;
char buffer[20], i;
read_page(nextPage, buffer, 20);
last = EEgetInt(FILE_MST_BASE+FILE_MST_LAST_PAGE_l);
/*search for file (stop at last written page)*/
while (!(buffer[FILE_NUM_PAGES_l] == 0xff && buffer[FILE_NUM_PAGES_h]== 0xff) && nextPage < last)
{
i=0;
while ( (i<16) && (nextPage != (EEgetInt(FILE_MST_BASE+FILE_MST_DEALLOCATED_PTRS+2*i)) ) )
{
i++;
}
if (!(i<16) )
{
if (!strncmp(file_name, &buffer[FILE_NAME], 8) && !strncmp(file_ext, &buffer[FILE_EXT], 3) )
{
return nextPage;
}
}
nextPage += (unsigned int)(buffer[FILE_NUM_PAGES_l] | (buffer[FILE_NUM_PAGES_h]<<8));
read_page(nextPage, buffer, 20);
}
return FILE_FNULL;
}
/* Write one char to FILE->buffer. If the buffer is full, write to page.*/
void ffput(FFILE *stream, const char data)
{
if (stream->status == FILE_WRITE)
{
stream->buffer[(stream->count++)] = data;
stream->file_size++;
if (stream->count == FLASH_PAGE_SIZE)
{
if (stream->end_page > 1022)
{
if ( EEgetInt(FILE_MST_BASE+FILE_MST_DEALLOCATED_SPACE_l) > 10 )
{
reclaim(); //If the end of the dataflash is reached and there are
} //deleted files, reclaim deallocated space.
}
if (stream->end_page < 1023)
{
write_page(stream->end_page++,stream->buffer);
lastWrittenPage = stream->end_page;
}
stream->count=0;
}
}
}
/* Read one char from FILE->buffer. If buffer is empty, read new page into buffer.*/
char ffget(FFILE *stream)
{
char data;
if (stream->status == FILE_READ)
{
data = stream->buffer[(stream->count++)%FLASH_PAGE_SIZE];
if (stream->count > stream->file_size)
{
data = 0;
}
else
{
if ( ((stream->count) % FLASH_PAGE_SIZE)==0 )
{
read_page(stream->start_page++,stream->buffer,FLASH_PAGE_SIZE);
}
}
}
return data;
}
/* write uses fput to write strings into file.*/
int ffwrite(FFILE *stream, char *buffer, int size)
{
int x;
for (x=0;x<size;x++)
{
ffput(stream, buffer[x]);
}
return x;
}
/* read uses fget to read strings from file.*/
int ffread(FFILE *stream, char *buffer, int size)
{
int x=0;
while ( (x<size) && (!ffeof(stream)) )
{
buffer[x++]=ffget(stream);
}
return x;
}
/* read one line. */
int ffreadln(FFILE *stream, char *buffer, int size)
{
int x=0;
while ( (x<size) && (!ffeof(stream)) )
{
buffer[x++] = ffget(stream);
if ( ((buffer[x-1] == '\r') || (buffer[x-1] == '\n')) && ((buffer[x-2] == '\r') || (buffer[x-2] == '\n')) )
{
return x; //If EOL is found, stop reading and return.
}
}
return x; //EOL is not found, but the buffer is full.
}
/* feof returns 1 if EOF is reached.*/
char ffeof(FFILE *stream)
{
if (stream->status == FILE_READ)
{
if (stream->count >= stream->file_size)
{
return (1);
}
}
return (0);
}
char ffclose (FFILE *stream)
{
unsigned int tmp;
/* If file is read, references to the file need to be deleted.*/
if (stream->status == FILE_READ)
{
stream->status = FILE_READY;
stream->file_id = 0;
stream->file_name[0] = '\0';
stream->file_ext[0] = '\0';
stream->count = 0;
stream->file_size = 0;
stream->start_page = 0;
stream->end_page = 0;
}/*If the file is written, the last page has to be written and
file header has to be created and written.*/
else if (stream->status == FILE_WRITE)
{
if (stream->end_page < 1023)
{
if (stream->count != 0) //If there is still data in FILE->buffer
{
write_page (stream->end_page++, stream->buffer);
}
stream->buffer[FILE_ID_l] = EEget(FILE_MST_BASE+FILE_MST_FILE_ID_NEXT_l);
stream->buffer[FILE_ID_h] = EEget(FILE_MST_BASE+FILE_MST_FILE_ID_NEXT_h);
strncpy(&stream->buffer[FILE_NAME], stream->file_name, 8);
strncpy(&stream->buffer[FILE_EXT], stream->file_ext, 3);
stream->buffer[FILE_SIZE_ll] = (unsigned char)(stream->file_size & 0xff);
stream->buffer[FILE_SIZE_lh] = (unsigned char)((stream->file_size>>8)&0xff);
stream->buffer[FILE_SIZE_hl] = (unsigned char)((stream->file_size>>16)&0xff);
stream->buffer[FILE_SIZE_hh] = (unsigned char)((stream->file_size>>24)&0xff);
tmp = (stream->end_page-stream->start_page);
stream->buffer[FILE_NUM_PAGES_l] = (tmp&0xff);
stream->buffer[FILE_NUM_PAGES_h] = ((tmp>>8)&0xff);
write_page(stream->start_page, stream->buffer);
tmp = EEgetInt(FILE_MST_BASE+FILE_MST_FREE_SPACE_l);
tmp -= (stream->end_page-stream->start_page);
EEput(FILE_MST_BASE+FILE_MST_STATUS, FILE_OK); //Write new information to Media Status Table
EEput(FILE_MST_BASE+FILE_MST_FREE_SPACE_l, (tmp&0xff));
EEput(FILE_MST_BASE+FILE_MST_FREE_SPACE_h, ((tmp>>8)&0xff));
tmp = EEgetInt(FILE_MST_BASE+FILE_MST_FILE_ID_NEXT_l);
tmp++;
EEput(FILE_MST_BASE+FILE_MST_FILE_ID_NEXT_l, (tmp&0xff));
EEput(FILE_MST_BASE+FILE_MST_FILE_ID_NEXT_h, ((tmp>>8)&0xff));
EEput(FILE_MST_BASE+FILE_MST_LAST_PAGE_l, (stream->end_page&0xff));
EEput(FILE_MST_BASE+FILE_MST_LAST_PAGE_h, ((stream->end_page>>8)&0xff));
saveMST();
stream->status = FILE_READY; // Prepare FILE for new file.
stream->file_id = 0;
stream->file_name[0] = '\0';
stream->file_ext[0] = '\0';
stream->count = 0;
stream->file_size = 0;
stream->start_page = 0;
stream->end_page = 0;
lastWrittenPage = 0;
}
else
{
stream->status = FILE_READY;
stream->file_id = 0;
stream->file_name[0] = '\0';
stream->file_ext[0] = '\0';
stream->count = 0;
stream->file_size = 0;
stream->start_page = 0;
stream->end_page = 0;
return 0;
}
}
else
{
return 0;
}
return 1;
}
char ffinit(void)
{
char buffer[80], x; // buffer[80] could be removed..
read_page(1023, buffer, 79); //
EEput(FILE_MST_BASE+FILE_MST_STATUS, buffer[FILE_MST_STATUS]); //
EEput(FILE_MST_BASE+FILE_MST_FREE_SPACE_l, buffer[FILE_MST_FREE_SPACE_l]); //
EEput(FILE_MST_BASE+FILE_MST_FREE_SPACE_h, buffer[FILE_MST_FREE_SPACE_h]); //
EEput(FILE_MST_BASE+FILE_MST_DEALLOCATED_SPACE_l, buffer[FILE_MST_DEALLOCATED_SPACE_l]); //
EEput(FILE_MST_BASE+FILE_MST_DEALLOCATED_SPACE_h, buffer[FILE_MST_DEALLOCATED_SPACE_h]); //
EEput(FILE_MST_BASE+FILE_MST_DEALLOCATED_NEXT_l, buffer[FILE_MST_DEALLOCATED_NEXT_l]); //Commented lines could be removed after debug
EEput(FILE_MST_BASE+FILE_MST_DEALLOCATED_NEXT_h, buffer[FILE_MST_DEALLOCATED_NEXT_h]); //
EEput(FILE_MST_BASE+FILE_MST_FILE_ID_NEXT_l, buffer[FILE_MST_FILE_ID_NEXT_l]); //
EEput(FILE_MST_BASE+FILE_MST_FILE_ID_NEXT_h, buffer[FILE_MST_FILE_ID_NEXT_h]); //
EEput(FILE_MST_BASE+FILE_MST_LAST_PAGE_l, buffer[FILE_MST_LAST_PAGE_l]); //
EEput(FILE_MST_BASE+FILE_MST_LAST_PAGE_h, buffer[FILE_MST_LAST_PAGE_h]); //
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -