• 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() 
    {
    
    }
  • 相关阅读:
    第十三周进度条
    寻找水军
    第十二周进度条
    学习总结
    第十五周工作总结
    第十四周工作总结
    《梦断代码》阅读笔记03
    个人工作总结20
    个人工作总结19
    个人工作总结18
  • 原文地址:https://www.cnblogs.com/BlueMountain-HaggenDazs/p/6059412.html
Copyright © 2020-2023  润新知