📄 filesystem.c
字号:
/*,-----------------------------------------------------------------------------------------.| io/filesystem|-----------------------------------------------------------------------------------------| this file implements a very very basic (custom) filesystem (->dataflash)| - 600 files max| - smallest file unit is 256 Byte| - store file as linked list across the whole dataflash| - file extension is always lowercase !!| - see below for filesystem information|| Author : {{removed according to contest rules}}| -> circuitcellar.com avr design contest 2006| -> Entry #AT2616||-----------------------------------------------------------------------------------------| License:| This program is free software; you can redistribute it and/or modify it under| the terms of the GNU General Public License as published by the Free Software| Foundation; either version 2 of the License, or (at your option) any later| version.| This program is distributed in the hope that it will be useful, but|| WITHOUT ANY WARRANTY;|| without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR| PURPOSE. See the GNU General Public License for more details.|| You should have received a copy of the GNU General Public License along with| this program; if not, write to the Free Software Foundation, Inc., 51| Franklin St, Fifth Floor, Boston, MA 02110, USA|| http://www.gnu.de/gpl-ger.html`-----------------------------------------------------------------------------------------*/#include "filesystem.h"#include "dataflash.h"//ACTIVATE DEBUG by editing this file:#include "debug.h"#define FILESYSTEM_REVISION 0x01/*store filesystem on dataflashsimple quick and dirty filesystem.store files in multiples of pagesize, every file chunkstores a pointer to the next data segment (linked list)-------------------------------------------------------------------------------every file consists of blocks with 256+8 Byte (=pagesize)- byte 0-255: DATA- byte 256: free/used tag -- 0xE0 -> used page, everything else: free page - byte 257: filesystem revision (starts with 0x01)- byte 258+259: file id (16bit uint) - byte 260+261: pointer to next file block- byte 262: block tag: 0x00 = first block, 0xEE = last block -> blocktag != 0xEE -> read more- byte 262: how many bytes of this block are used-------------------------------------------------------------------------------*/#define FILESYSTEM_FILE_FREETAG 0x100#define FILESYSTEM_FILE_REV 0x101#define FILESYSTEM_FILE_ID_HI 0x102#define FILESYSTEM_FILE_ID_LO 0x103#define FILESYSTEM_FILE_NEXT_HI 0x104#define FILESYSTEM_FILE_NEXT_LO 0x105#define FILESYSTEM_FILE_BLOCKTAG 0x106#define FILESYSTEM_FILE_BLOCK_USAGE 0x107/*-------------------------------------------------------------------------------filesystem info table is stored in block 0-49- every entry has 24 bytes: - byte 0- 1 : 16 bit file id (uint) (valid fileid: 1...549) - byte 2- 5 : 32 bit timestamp (last modified) - byte 6-16 : 11 byte filename (8+3 chars) - byte 17-18 : address of first block - byte 19-20 : address of last block - byte 21-23 : RESERVED-------------------------------------------------------------------------------!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!WARNING: we only support one open file (for writing) at one time !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/////// TODO: /// - replace writing of 0s with dataflash erase cmd !!!!#define FILESYSTEM_TABLE_SIZE 50#define FILESYSTEM_BLOCK_COUNT 2048#define FILESYSTEM_STATUS_IDLE 0x00#define FILESYSTEM_STATUS_FILE_OPEN 0x01#define FILESYSTEM_FTABLE_ID_HI 0#define FILESYSTEM_FTABLE_ID_LO 1#define FILESYSTEM_FTABLE_TIMESTAMP_3 2#define FILESYSTEM_FTABLE_TIMESTAMP_2 3#define FILESYSTEM_FTABLE_TIMESTAMP_1 4#define FILESYSTEM_FTABLE_TIMESTAMP_0 5//position of filename start#define FILESYSTEM_FTABLE_FILENAME_START 6#define FILESYSTEM_FTABLE_BLOCK_START_HI 17#define FILESYSTEM_FTABLE_BLOCK_START_LO 18#define FILESYSTEM_FTABLE_BLOCK_COUNT_HI 19#define FILESYSTEM_FTABLE_BLOCK_COUNT_LO 20volatile unsigned char filesystem_status;volatile unsigned int filesystem_fileid;volatile unsigned int filesystem_first_block;volatile unsigned int filesystem_current_block;volatile unsigned int filesystem_block_count;volatile unsigned char filesystem_filename[8];volatile unsigned char filesystem_filename_ext[3];unsigned char filesystem_buffer[256];volatile unsigned char filesystem_file_pos;//initvoid filesystem_init(){ filesystem_status = FILESYSTEM_STATUS_IDLE; filesystem_fileid = 0; filesystem_first_block = 0; filesystem_current_block = 0; filesystem_file_pos = 0; //check if we need to format flash: dataflash_copy_page_to_buffer(0, 0); if ((dataflash_read_buffer(0, 0)==0xFF) && (dataflash_read_buffer(1, 0)==0xFF)) filesystem_format();}void filesystem_delete_file(unsigned int fileid){ unsigned int tmp; unsigned int tmp_old; unsigned int pos; //invalid fileid ? if (fileid == 0) return; //copy lookuptable page to dataflash buffer 0 dataflash_copy_page_to_buffer(((fileid-1)/11), 0); //pos inside page is ? pos = 24*((fileid-1) % 11); #if FILESYSTEM_DEBUG softuart_puts_progmem("FS : deleting #"); softuart_put_uint16(fileid); softuart_puts_progmem("... "); #endif //get first block: tmp = dataflash_read_buffer(pos + FILESYSTEM_FTABLE_BLOCK_START_HI, 0)<<8; tmp |= dataflash_read_buffer(pos + FILESYSTEM_FTABLE_BLOCK_START_LO, 0); //mark lookup table entry as empty: dataflash_write_to_page_buffer(pos+FILESYSTEM_FTABLE_ID_HI,0,0); dataflash_write_to_page_buffer(pos+FILESYSTEM_FTABLE_ID_LO,0,0); //store lookuptable dataflash_copy_buffer_to_page(((fileid-1)/11), 0); //clear buffer: for (unsigned int j=0; j<256+8; j++) dataflash_write_to_page_buffer(j,1,0); while (tmp != 0x0000){ #if FILESYSTEM_DEBUG softuart_putc('x'); #endif //copy block to buffer0: dataflash_copy_page_to_buffer(tmp, 0); //remember page to clear tmp_old = tmp; //calc next block: tmp = dataflash_read_buffer(FILESYSTEM_FILE_NEXT_HI, 0)<<8; tmp |= dataflash_read_buffer(FILESYSTEM_FILE_NEXT_LO, 0); //tmp should be zero if this is the last block. but we have a flag for last block, too: if (dataflash_read_buffer(FILESYSTEM_FILE_BLOCKTAG,0) == 0xEE) tmp = 0x0000; //last block! else dataflash_copy_buffer_to_page(tmp_old,1); } #if FILESYSTEM_DEBUG softuart_puts_progmem(" done"); softuart_putnewline(); #endif}/*void filesystem_dump_file(unsigned int fileid){ unsigned int tmp; unsigned int count; unsigned int pos; //invalid fileid ? if (fileid == 0) return; //copy lookuptable page to dataflash buffer 0 dataflash_copy_page_to_buffer(((fileid-1)/11), 0); //pos inside page is ? pos = 24*((fileid-1) % 11); #if FILESYSTEM_DEBUG softuart_puts_progmem("FS : dumping #"); softuart_put_uint16(fileid); softuart_puts_progmem(", loc on block "); softuart_put_uint16((fileid-1)/11); softuart_puts_progmem(", pos "); softuart_put_uint8(pos); softuart_putnewline(); #endif //get first block: tmp = dataflash_read_buffer(pos + FILESYSTEM_FTABLE_BLOCK_START_HI, 0)<<8; tmp |= dataflash_read_buffer(pos + FILESYSTEM_FTABLE_BLOCK_START_LO, 0); while (tmp != 0x0000){ //copy block to buffer0: dataflash_copy_page_to_buffer(tmp, 0); //get bytes used inside this block: count = dataflash_read_buffer(FILESYSTEM_FILE_BLOCK_USAGE,0)+1; //dump block: unsigned int i=0; while (count > 0){ softuart_putc(dataflash_read_buffer(i,0)); count--; i++; } //calc next block: tmp = dataflash_read_buffer(FILESYSTEM_FILE_NEXT_HI, 0)<<8; tmp |= dataflash_read_buffer(FILESYSTEM_FILE_NEXT_LO, 0); //tmp should be zero if this is the last block. but we have a flag for last block, too: if (dataflash_read_buffer(FILESYSTEM_FILE_BLOCKTAG,0) == 0xEE) tmp = 0x0000; //last block! } #if FILESYSTEM_DEBUG softuart_puts_progmem("FS : dump done."); softuart_putnewline(); #endif}*///search for given filename [8.3]//return: 0 if not found, otherwise the file idunsigned int filesystem_search_file(unsigned char *filename, unsigned char *filename_ext){ unsigned int tmp; unsigned char x; unsigned char i,j; unsigned char found; //make file extension lowercase !! for(unsigned char i=0; i<3 && filename_ext[i] != 0; i++){ if ((filename_ext[i] >= 'A') && (filename_ext[i] <= 'Z')) filename_ext[i] = filename_ext[i] - 'A' + 'a'; } #if FILESYSTEM_DEBUG softuart_puts_progmem("FS : search file <"); x=0; while((x<8) && filename[x]) softuart_putc(filename[x++]); softuart_putc('>'); softuart_putc('<'); x=0; while((x<3) && filename_ext[x]) softuart_putc(filename_ext[x++]); softuart_puts_progmem("> "); #endif //search all filesystem table entries: for(i=0; i<FILESYSTEM_TABLE_SIZE; i++){ //copy page i to dataflash buffer 0 dataflash_copy_page_to_buffer(i, 0); //now read 11 filesystem entries: for(j=0; j<11; j++){ //extract id tmp = dataflash_read_buffer(j*24 + FILESYSTEM_FTABLE_ID_HI, 0)<<8; tmp |= dataflash_read_buffer(j*24 + FILESYSTEM_FTABLE_ID_LO, 0); //only check valid files: if (tmp != 0){ //check if first char equals, if true -> compare the rest if (filename[0] == dataflash_read_buffer(j*24+FILESYSTEM_FTABLE_FILENAME_START,0)){ //yes, first char matches! -> compare found = 1; //check filename for(x=1; x<8; x++){ //if char does not match -> found = 0 if (filename[x] != dataflash_read_buffer(j*24+FILESYSTEM_FTABLE_FILENAME_START + x,0)) found = 0; //end of string -> break if (filename[x] == 0) break; } //check extension (IS ALWAYS 3 CHARS !!) for(x=0; x<3; x++){ if (filename_ext[x] != dataflash_read_buffer(j*24+FILESYSTEM_FTABLE_FILENAME_START + 8 + x,0)) found = 0; } if (found == 1){ //we got it -> return file id #if FILESYSTEM_DEBUG softuart_puts_progmem(" found !\r\n"); #endif return tmp; } } } } } //not found -> return 0 #if FILESYSTEM_DEBUG softuart_puts_progmem(" not found !\r\n"); #endif return 0;}//erase filesystem !!! //FIXME: use dataflash erase instead !void filesystem_format(){ unsigned int i; #if FILESYSTEM_DEBUG softuart_puts_progmem("FS: formating... please wait (takes a long time) ["); #endif //copy page 0 to dataflash buffer 0 dataflash_copy_page_to_buffer(0, 0); //??? remove this, not neccessary! //clear buffer for(i=0; i<256+8; i++) dataflash_write_to_page_buffer(i,0,0); //copy buffer to all fs table sectors: for(i=0; i<FILESYSTEM_BLOCK_COUNT; i++){ //store cleared buffer on flash: dataflash_copy_buffer_to_page(i,0); #if FILESYSTEM_DEBUG softuart_putc('.'); #endif } #if FILESYSTEM_DEBUG softuart_puts_progmem("] done"); softuart_putnewline(); #endif }//list files in filesystem:/*void filesystem_list_files(){ unsigned int tmp,tmp2; unsigned char i,j,k; #if FILESYSTEM_DEBUG softuart_putnewline(); softuart_puts_progmem(" <fid> <start> <size> <filename>"); softuart_putnewline(); softuart_puts_progmem("---------------------------------------"); softuart_putnewline(); #endif //search all filesystem table entries: for(i=0; i<FILESYSTEM_TABLE_SIZE; i++){ //copy page i to dataflash buffer 0 dataflash_copy_page_to_buffer(i, 0); //now read 11 filesystem entries: for(j=0; j<11; j++){ //check if there is already a file with our id: tmp = dataflash_read_buffer(j*24 + FILESYSTEM_FTABLE_ID_HI, 0)<<8; tmp |= dataflash_read_buffer(j*24 + FILESYSTEM_FTABLE_ID_LO, 0); if (tmp != 0){ //print all: //for(tmp2=0; tmp2<24; tmp2++) // rprintf("%x ",dataflash_read_buffer(j*24+tmp2,0)); //rprintf("\r\n"); //this is a active file -> print #if FILESYSTEM_DEBUG softuart_putc(' '); softuart_put_uint16(tmp); //print start/end sector: tmp = dataflash_read_buffer(j*24 + FILESYSTEM_FTABLE_BLOCK_START_HI, 0); tmp = tmp<<8; tmp += dataflash_read_buffer(j*24 + FILESYSTEM_FTABLE_BLOCK_START_LO, 0); tmp2 = dataflash_read_buffer(j*24 + FILESYSTEM_FTABLE_BLOCK_COUNT_HI, 0); tmp2 = tmp2<<8; tmp2 += dataflash_read_buffer(j*24 + FILESYSTEM_FTABLE_BLOCK_COUNT_LO, 0); softuart_putc(' '); softuart_putc(' '); softuart_put_uint16(tmp); softuart_puts_progmem(" / "); softuart_put_uint16(tmp2); softuart_puts_progmem(" ./"); unsigned char c; for (k=0; k<8; k++){ c = dataflash_read_buffer(j*24 + FILESYSTEM_FTABLE_FILENAME_START + k, 0); if (c) softuart_putc(c); else break; } softuart_putc('.'); for (k=0; k<3; k++){ c = dataflash_read_buffer(j*24 + FILESYSTEM_FTABLE_FILENAME_START + 8 +k, 0); if (c) softuart_putc(c); else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -