Search Results for

    Show / Hide Table of Contents

    File System


    The file system library is a subset of the full .NET file system support. Most examples should work with only minor changes. The internal drivers fully support FAT16 or FAT32 file systems, with no limitations beyond the FAT file system itself!

    Note

    The USB drive must have an MBR record, not a GPT table. FAT16 and FAT32 file systems are supported.

    Fat File System

    USB Mass Storage

    This allows file access on USB devices with MSC class, such as USB memory sticks. See the USB page.

    SD Card

    SD and MMC cards are fully supported as detailed on the SD tutorial page. Additionally, SPI SD drivers are also supported through the ManagedFileSystem software utility drivers.

    The example below requires the GHIElectronics.TinyCLR.IO and GHIElectronics.TinyCLR.Devices.Storage libraries and a device with an SD card.

    var sd = StorageController.FromName(SC20100.StorageController.SdCard);
    var drive = FileSystem.Mount(sd.Hdc);
    
    //Show a list of files in the root directory
    var directory = new DirectoryInfo(drive.Name);
    var files = directory.GetFiles();
    
    foreach (var f in files) {
        System.Diagnostics.Debug.WriteLine(f.Name);
    }
    
    //Create a text file and save it to the SD card.
    var file = new FileStream($@"{drive.Name}Test.txt", FileMode.OpenOrCreate);
    var bytes = Encoding.UTF8.GetBytes(DateTime.UtcNow.ToString() +
        Environment.NewLine);
    
    file.Write(bytes, 0, bytes.Length);
    
    file.Flush();
    
    FileSystem.Flush(sd.Hdc);
    
    

    Low-level Access

    You can access the raw underlying data of the storage provider by using the Provider property of the controller. Be careful when using this interface, however, as it bypasses any file system present and writes directly to the device. This is useful for implementing your own or otherwise unsupported file systems.

    var controller = StorageController.FromName
            (SC20100.StorageController.SdCard);
    
    controller.Provider.Open(); // open
    controller.Provider.Read(address, buffer, 0, buffer.Length, TimeSpan.FromSeconds(5));
    controller.Provider.Close(); // close
    
    

    Tiny File System (TFS)

    Tiny File System(TFS) can be used to access any memory storage as a file system. All that is needed is a basic driver to Read, Write, and Erase these storages.

    Below is an example that uses the external flash through TFS.

    Note

    This example requires the GHIElectronics.TinyCLR.IO.TinyFileSystem

    const int CLUSTER_SIZE = 1024;
    
    var tfs = new TinyFileSystem(new QspiMemory(), CLUSTER_SIZE);
                
    if (!tfs.CheckIfFormatted()) {
        //Do Format if necessary 
        tfs.Format();
    }
    else {
        // Mount tiny file system
        tfs.Mount();
    }
    
    //Open to write
    using (var fsWrite = tfs.Create("settings.dat")) {
        using (var wr = new StreamWriter(fsWrite)) {
            wr.WriteLine("This is TFS test");
            wr.Flush();
            fsWrite.Flush();
        }
    }
    
    //Open to read
    using (var fsRead = tfs.Open("settings.dat", FileMode.Open)) {
        using (var rdr = new StreamReader(fsRead)) {
            System.String line;
            
            while ((line = rdr.ReadLine()) != null) {
                    Debug.WriteLine(line);
            }
        }
    }
    

    Below is a basic driver implementation utilizing QSPI external flash. It automatically sets the size appropriately depending on whether the deployment is extended or not, as explained on the External Flash page. It however gives you the option to fix the size to 2MB, as the remaining 8MB can optionally be used by InField Update.

    public sealed class QspiMemory : IStorageControllerProvider
    {
        public StorageDescriptor Descriptor => this.descriptor;
        const int SectorSize = 4 * 1024;
    
        private StorageDescriptor descriptor = new StorageDescriptor()
        {
            CanReadDirect = false,
            CanWriteDirect = false,
            CanExecuteDirect = false,
            EraseBeforeWrite = true,
            Removable = true,
            RegionsContiguous = true,
            RegionsEqualSized = true,
            RegionAddresses = new long[] { 0 },
            RegionSizes = new int[] { SectorSize },
            RegionCount = (2 * 1024 * 1024) / (SectorSize)
        };
    
        private IStorageControllerProvider qspiDrive;
    
        public QspiMemory() : this(2 * 1024 * 1024)
        {
    
        }
    
        public QspiMemory(uint size)
        {
            var maxSize = Flash.IsEnabledExtendDeployment ? (10 * 1024 * 1024) : (16 * 1024 * 1024);
    
            if (size > maxSize)
                throw new ArgumentOutOfRangeException("size too large.");
    
            if (size <= SectorSize)
                throw new ArgumentOutOfRangeException("size too small.");
    
            if (size != descriptor.RegionCount * SectorSize)
            {
                descriptor.RegionCount = (int)(size / SectorSize);
            }
    
            qspiDrive = StorageController.FromName(SC20260.StorageController.QuadSpi).Provider;
    
            this.Open();
        }
    
        public void Open()
        {
            qspiDrive.Open();
        }
    
        public void Close()
        {
            qspiDrive.Close();
        }
    
        public void Dispose()
        {
            qspiDrive.Dispose();
        }
    
        public int Erase(long address, int count, TimeSpan timeout)
        {
            return qspiDrive.Erase(address, count, timeout);
        }
    
        public bool IsErased(long address, int count)
        {
            return qspiDrive.IsErased(address, count);
        }
    
        public int Read(long address, int count, byte[] buffer, int offset, TimeSpan timeout)
        {
            return qspiDrive.Read(address, count, buffer, offset, timeout);
        }
    
        public int Write(long address, int count, byte[] buffer, int offset, TimeSpan timeout)
        {
            return qspiDrive.Write(address, count, buffer, offset, timeout);
        }
    
        public void EraseAll(TimeSpan timeout)
        {
            for (var sector = 0; sector < this.Descriptor.RegionCount; sector++)
            {
                qspiDrive.Erase(sector * this.Descriptor.RegionSizes[0], this.Descriptor.RegionSizes[0], timeout);
            }
        }
    }
    
    • Improve this Doc
    ☀
    ☾
    In This Article

    Back to top

    Back to top Copyright © 2022 GHI Electronics, LLC
    Generated by DocFX