一、一些API
1、打开文件
SerialFlashFile file; file = SerialFlash.open("filename.bin"); if (file) { // true if the file exists}
2、读数据
char buffer[256]; file.read(buffer, 256);
3、获取文件尺寸和位置
file.size();
file.position()
file.seek(number);
4、写数据
file.write(buffer, 256);
5、擦除
file.erase();
6、创建新文件
SerialFlash.create(filename, size);
SerialFlash.createErasable(filename, size);
返回值为布尔型,返回True说明创建成功,返回false说明创建失败(没有足够的可用空间)
创建后,文件大小不可更改。
7、删除文件
SerialFlash.remove(filename);
删除文件后,其暂用的空间不会被回收,但删除后,可以再创建一个同名文件。
8、检查文件是否存在(不会打开文件)
SerialFlash.exists(filename);
9、列出文件所有信息
SerialFlash.opendir();
SerialFlash.readdir(buffer, buflen, filelen);
#ifndef SerialFlash_h_ #define SerialFlash_h_ #include <Arduino.h> #include <SPI.h> class SerialFlashFile; class SerialFlashChip { public: //两种Flash的初始化方法,一般选用第二种 static bool begin(SPIClass& device, uint8_t pin = 6); static bool begin(uint8_t pin = 6); //通过Id来查询容量 static uint32_t capacity(const uint8_t *id); //查询扇区大小 static uint32_t blockSize(); //睡眠以及唤醒 static void sleep(); static void wakeup(); //读取ID static void readID(uint8_t *buf); //读取序列号 static void readSerialNumber(uint8_t *buf); //读Flash static void read(uint32_t addr, void *buf, uint32_t len); static bool ready(); static void wait(); //写Flash static void write(uint32_t addr, const void *buf, uint32_t len); //擦出 static void eraseAll(); static void eraseBlock(uint32_t addr); //打开文件 static SerialFlashFile open(const char *filename); //创建文件 static bool create(const char *filename, uint32_t length, uint32_t align = 0); //创建文件 static bool createErasable(const char *filename, uint32_t length) { return create(filename, length, blockSize()); } //文件是否存在 static bool exists(const char *filename); //移除文件 static bool remove(const char *filename); static bool remove(SerialFlashFile &file); //打开文件目录 static void opendir() { dirindex = 0; } static bool readdir(char *filename, uint32_t strsize, uint32_t &filesize); private: static uint16_t dirindex; // current position for readdir() static uint8_t flags; // chip features static uint8_t busy; // 0 = ready // 1 = suspendable program operation // 2 = suspendable erase operation // 3 = busy for realz!! }; extern SerialFlashChip SerialFlash; class SerialFlashFile { public: SerialFlashFile() : address(0) { } operator bool() { if (address > 0) return true; return false; } //读 uint32_t read(void *buf, uint32_t rdlen) { if (offset + rdlen > length) { if (offset >= length) return 0; rdlen = length - offset; } SerialFlash.read(address + offset, buf, rdlen); offset += rdlen; return rdlen; } //写 uint32_t write(const void *buf, uint32_t wrlen) { if (offset + wrlen > length) { if (offset >= length) return 0; wrlen = length - offset; } SerialFlash.write(address + offset, buf, wrlen); offset += wrlen; return wrlen; } //设置偏移 void seek(uint32_t n) { offset = n; } //当前位置 uint32_t position() { return offset; } //文件大小 uint32_t size() { return length; } //是否可用 uint32_t available() { if (offset >= length) return 0; return length - offset; } //清楚 void erase(); void flush() { } //关闭指针 void close() { } uint32_t getFlashAddress() { return address; } protected: friend class SerialFlashChip; uint32_t address; // where this file's data begins in the Flash, or zero uint32_t length; // total length of the data in the Flash chip uint32_t offset; // current read/write offset in the file uint16_t dirindex; };
二、demo
1、写文件
/*********************头文件**********************/ #include <SerialFlash.h> #include <SPI.h> /*********************宏定义*******************/ #define File_SIZE 256 /*********************全局变量*******************/ //文件名和内容(要写的) const char *filename = "myfile.txt"; const char *contents = "0123456789ABCDEF"; //flash指针 const int g_FlashChipSelect = 21; // digital pin for flash chip CS pin /****************创建文件如果不存在********************/ bool create_if_not_exists (const char *filename) { if ( !SerialFlash.exists(filename) ) { Serial.println("Creating file " + String(filename)); return (SerialFlash.create(filename, File_SIZE)); } Serial.println("File " + String(filename) + " already exists"); return true; } /*****************初始化函数********************/ void setup() { //串口配置 Serial.begin(9600); while (!Serial) ; delay(100); Serial.println("Serial is OK!"); //配置Flash if ( !SerialFlash.begin(g_FlashChipSelect) ) { Serial.println("Unable to access SPI Flash chip"); } //创建文件指针 SerialFlashFile file; //创建文件,如果这个文件不存在 if (!create_if_not_exists(filename)) { Serial.println("Not enough space to create file " + String(filename)); //return; } file = SerialFlash.open(filename); file.write(contents, strlen(contents) + 1); Serial.println("String "" + String(contents) + "" written to file " + String(filename)); } void loop() { }
2、列出文件信息
/*********************头文件**********************/ #include <SerialFlash.h> #include <SPI.h> /*********************宏定义*******************/ /*********************全局变量*******************/ //flash指针 const int g_FlashChipSelect = 21; // digital pin for flash chip CS pin /********************空格*******************/ void spaces(int num) { for ( int i=0; i < num; i++ ) { Serial.print(" "); } } /*****************初始化函数********************/ void setup() { //串口配置 Serial.begin(9600); while (!Serial) ; delay(100); Serial.println("Serial is OK!"); //配置Flash if ( !SerialFlash.begin(g_FlashChipSelect) ) { Serial.println("Unable to access SPI Flash chip"); } //开路径 SerialFlash.opendir(); while(1) { char filename[64]; unsigned long filesize; if( SerialFlash.readdir( filename , sizeof(filename) , filesize) ) { Serial.print(" "); Serial.print(filename); spaces( 20 - strlen(filename) ); Serial.print(" "); Serial.print(filesize); Serial.print(" bytes"); Serial.println(); } else { break; } } } void loop() { }
3、删除全部Flash
/*********************头文件**********************/ #include <SerialFlash.h> #include <SPI.h> /*********************宏定义*******************/ /*********************全局变量*******************/ //flash指针 const int g_FlashChipSelect = 21; // digital pin for flash chip CS pin SerialFlashFile file; const unsigned long testIncrement = 4096; float eraseBytesPerSecond(const unsigned char *id) { if (id[0] == 0x20) return 152000.0; // Micron if (id[0] == 0x01) return 500000.0; // Spansion if (id[0] == 0xEF) return 419430.0; // Winbond if (id[0] == 0xC2) return 279620.0; // Macronix return 320000.0; // guess? } /*****************初始化函数********************/ void setup() { //串口配置 Serial.begin(9600); while (!Serial) ; delay(100); Serial.println("Serial is OK!"); // wait up to 10 seconds for Arduino Serial Monitor unsigned long startMillis = millis(); while (!Serial && (millis() - startMillis < 10000)) ; delay(100); //配置Flash if ( !SerialFlash.begin(g_FlashChipSelect) ) { Serial.println("Unable to access SPI Flash chip"); } //读ID unsigned char id[5]; SerialFlash.readID(id); unsigned long size = SerialFlash.capacity(id); //开路径 SerialFlash.opendir(); if( size > 0 ) { Serial.print( "Flash Memory has "); Serial.print( size ); Serial.println( " bytes."); Serial.println( "Erasing All Flash Memory:"); Serial.print(" estimated wait: "); int seconds = (float)size / eraseBytesPerSecond(id) + 0.5; Serial.print(seconds); Serial.println(" seconds."); Serial.println(" Yes, full chip erase is SLOW!"); SerialFlash.eraseAll(); unsigned long dotMillis = millis(); unsigned char dotcount = 0; while (SerialFlash.ready() == false) { if (millis() - dotMillis > 1000) { dotMillis = dotMillis + 1000; Serial.print("."); dotcount = dotcount + 1; if (dotcount >= 60) { Serial.println(); dotcount = 0; } } } if (dotcount > 0) Serial.println(); Serial.println("Erase completed"); unsigned long elapsed = millis() - startMillis; Serial.print(" actual wait: "); Serial.print(elapsed / 1000ul); Serial.println(" seconds."); } } void loop() { }