Arduino101学习笔记(十四)—— Flash库

一、一些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();
     擦除文件,就是将指定文件全部内容写为255 (0xFF)

 

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() 
{

}
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值