SD card file write woes

Hi,

I’m now trying out SD card writing abilities. Example code from ebook is producing following error during debug:

The thread 0x2 has exited with code 0 (0x0).
#### Exception System.IO.IOException - CLR_E_VOLUME_NOT_FOUND (1) ####
#### System.IO.Path::NormalizePath [IP: 0070] ####
#### System.IO.Path::GetFullPath [IP: 001a] ####
#### System.IO.FileStream::.ctor [IP: 0009] ####
#### System.IO.FileStream::.ctor [IP: 0010] ####
#### SDcard.Program::Main [IP: 0021] ####
A first chance exception of type ‘System.IO.IOException’ occurred in System.IO.dll
An unhandled exception of type ‘System.IO.IOException’ occurred in System.IO.dll

Points to this line as the problem:
FileStream FileHandle = new FileStream(rootDirectory + “hello.txt”, FileMode.Create);

Any help would be great! Thanks!

Funny another user just pointed out this error in the book and provided the fix.
We will update the book but for now see the last post here

http://www.ghielectronics.com/forum/index.php/topic,2408.0.html

Again, you the chimp! Thanks!

One thing to emphasize big time is the need to ensure you close the file after your done with it. If not, Windows will not be able to work with the SD card. Couldn’t even format it until I ran an SD card test program on the Fez Domino that simply opened the non-closed file and closed it again.

This is the same on any system out there, even huge systems like Linux and Windows…if you do not close of flush the data then you will corrupt the file and maybe the whole media

The link above does not work… Could someone post a new link or the fix for this problem. I am experiencing the same issue. (or similar anyway.)

Exception System.IO.IOException - CLR_E_FILE_IO (5)

#### Message: 
#### Microsoft.SPOT.IO.VolumeInfo::.ctor [IP: 0000] ####
#### Microsoft.SPOT.IO.RemovableMedia::MessageHandler [IP: 0022] ####

A first chance exception of type ‘System.IO.IOException’ occurred in Microsoft.SPOT.IO.dll
An unhandled exception of type ‘System.IO.IOException’ occurred in Microsoft.SPOT.IO.dll

Robert,
Try this.


using System;
using System.IO;
using System.Threading;

using Microsoft.SPOT;
using Microsoft.SPOT.IO;

using GHIElectronics.NETMF.IO;
using GHIElectronics.NETMF.FEZ;

using GHIElectronics.NETMF.Hardware;

using GHIElectronics.NETMF.USBHost;

/*
Lists of References
FEZPanda_GHIElectronics.NETMF.FEZ
GHIElectronics.NETMF.Hardware
GHIElectronics.NETMF.IO
GHIElectronics.NETMF.System
GHIElectronics.NETMF.USBHost
Microsoft.SPOT.Hardware
Microsoft.SPOT.IO
Microsoft.SPOT.Native
mscorlib
System.IO
*/

namespace FEZ_Panda_Application1
{
    public class Program
    {
        static byte[] ba = new byte[1024];

        static DateTime start_time;
        static TimeSpan ts;

        public static void writeSD()
        {        
            // ...
            // SD Card is inserted
            // Create a new storage device
            PersistentStorage sdPS = new PersistentStorage("SD");

            int i;

            for (i = 0; i < 1024; i++)
            {
                ba[i] = (byte)(i % 255);
            }
            
            // Mount the file system
            sdPS.MountFileSystem();

            string rootDirectory = VolumeInfo.GetVolumes()[0].RootDirectory;

            FileStream FileHandle = new FileStream(rootDirectory + @ "\hello.txt", FileMode.Create);

            for (i = 0; i < 1024; i++)
            {
                FileHandle.Write(ba, 0, 1024);
            }

            FileHandle.Close();

            sdPS.UnmountFileSystem();
        }

        public static void Main()
        {
            //Start measure
            start_time = DateTime.Now;
            writeSD();
            ts = DateTime.Now - start_time;
            Debug.Print("Write file to SD in: " + ts);
        }

    }
}

Make sure your SD card is formatted before you use it on the Panda. This may not be your issue, but I have seen a similar exception when the card is not formatted.

Have others tested the example in the book? What is wrong with it.

It works fine!

The sample in the book works fine… I wanted to view the solution above to see if I could find a resolution to my problem.

I am trying to write a program that will write the date, time, and temperature out to a file on the microSD. Here is what I have come up with so far, but I am getting the Exception System.IO.IOException - CLR_E_FILE_IO (5) error.

using System;
using System.IO;
using System.Text;
using System.Threading;

using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using Microsoft.SPOT.IO;

using GHIElectronics.NETMF.FEZ;
using GHIElectronics.NETMF.IO;
using GHIElectronics.NETMF.System;

namespace FEZ_Domino_Application1
{
    public class Program
    {
        static InputPort IntButton;
        static OutputPort led;
        static Boolean run = false;

        static Thread OnThread = new Thread(IfOn);

        static PersistentStorage microSD;


        public static void Main()
        {
            led = new OutputPort((Cpu.Pin)FEZ_Pin.Digital.LED, false);
            IntButton = new InterruptPort((Cpu.Pin)FEZ_Pin.Interrupt.LDR, true, Port.ResistorMode.PullUp, Port.InterruptMode.InterruptEdgeLow);

            IntButton.OnInterrupt += new NativeEventHandler(IntButton_OnInterruped);

            OnThread.Start();

            Debug.Print("Infinite loop running...");
            Thread.Sleep(Timeout.Infinite);
        }

        static void IfOn()
        {
            bool On = true;
            bool Off = false;

            microSD = new PersistentStorage("SD");


            while (true)
            {
                if (run)
                {
                    led.Write(On);
                    Debug.Print("Led On.");

                    microSD.MountFileSystem();
                    Debug.Print("File System Mounted.");

                    string rootDirectory = VolumeInfo.GetVolumes()[0].RootDirectory;
                    Debug.Print("Root Directory Obtained.");

                    FileStream fileName;

                    fileName = new FileStream(rootDirectory + @ "\Temperatures.txt", FileMode.OpenOrCreate);
                    Debug.Print("File Opened or Created.");

                    // to add code to obtain 
                    byte[] data = Encoding.UTF8.GetBytes("Current Date, Current Time, Current Temperature");
                    fileName.Write(data, 0, data.Length);
                    Debug.Print("Data Written.");
                    fileName.Close();
                    Debug.Print("File Closed");
                    microSD.UnmountFileSystem();
                    Debug.Print("File System Unmounted.");


                    led.Write(Off);
                    Debug.Print("led off");
                    Thread.Sleep(1000);
                }
                else if ()
                {
                    
                }
                {

                }
                
            }
            
        }

        static void IntButton_OnInterruped(uint port, uint state, DateTime time)
        {
            run = !run;
            Debug.Print("Running: " + run.ToString());
        }
    }
}

Well except I forgot to remove the “else if” which is an unfinished thought…

Why not do it the simple way?

Start with working example in book … or put your code in “main” and step in code to understand what is going on.

This will also make it easier for us to help you as well.

Actually that is what I did… :slight_smile:

The problem started when I tried running the steps through any kind of loop.

I did find a solution, but am curious if anyone knows why there is an issue or if my “fix” is even valid. (The way I came up with the fix is that when I step through the code the error does not happen, unless I step through the code very quickly.)

This code is much closer to the example in the Beginners Guide. The difference is that I added a for next loop and some debugging comments.

The fix is adding the Thread.Sleep(2); command just before the UnmountFileSystem(); command. (In order for it to “fix” the problem it has to be before the UnmountFileSystem command.)

using System;
using System.IO;
using System.Text;
using System.Threading;

using Microsoft.SPOT;
using Microsoft.SPOT.IO;

using GHIElectronics.NETMF.IO;
using GHIElectronics.NETMF.FEZ;

//using GHIElectronics.NETMF.Hardware;



namespace MFConsoleApplication1
{
    public class Program
    {
        static void Main()
        {
            // ... check if SD is inserted
            // SD Card is inserted
            // Create a new storage device
            PersistentStorage sdPS = new PersistentStorage("SD");

            try
            {
                for (int i = 0; i < 50; i++)
                {
                    Debug.Print("Starting loop " + i.ToString() + ".");
                    // Mount the file system
                    sdPS.MountFileSystem();
                    Debug.Print("Mounting File System.");

                    // Assume one storage device is available,
                    // access it through NETMF
                    string rootDirectory = VolumeInfo.GetVolumes()[0].RootDirectory;
                    Debug.Print("Getting RootDirectory: " + rootDirectory.ToString());
                    FileStream FileHandle = new FileStream(rootDirectory + @ "\Temperatures.csv", FileMode.Append);
                    Debug.Print("Creating File...");
                    byte[] data = Encoding.UTF8.GetBytes("Probe, Date, Time, Temperature = " + i.ToString() + "\n\r");

                    // write the data and close the file
                    FileHandle.Write(data, 0, data.Length);
                    Debug.Print("Writing to file.");
                    FileHandle.Close();
                    Debug.Print("Closing File.");


                    Thread.Sleep(2);  // Adding this code seems to of fixed the problem, but I do not understand why.

                    // if we need to unmount
                    sdPS.UnmountFileSystem();
                    Debug.Print("Unmounting FileSystem.");

               
                }

            }
            catch (Exception ex)
            {
                Debug.Print(ex.ToString());
            }
        }
    }
}

I also was having trouble with IO errors in trying to read the SD card, and noticed the prior recommendations to add a capacitor in parallel with C10 as the problem could be power related.

As Robert2 has noted, a quick fix if you can stand the delay, is to insert a sleep thread before the error point in the code. At least this also worked for me as it allowed the power level time to recover. Not what I call a robust solution, but at least it pinpoints the problem.

I think each person had a different problem on this thread…

The delay before the unmount is needed because you are unmounting so fast and that should not be the normal case.

The exception is harmless. Here is what is happening:
-Mount SD card.
-NETMF tries to send an insert event.
-You are unmounting immediately before NETMF was even able to send an event.
-You get the exception in the output

Thanks for the additional information on the “fast unmount”, Mike, but is the other problem caused by power instability to the SD card?

I ask because the error on my Fez Domino and the fix that I described in my previous post don’t appear to be caused by a “race” problem in the unmount. I’d like to be sure I understand your analysis as I’m just getting started on revising a lot of code. Please let me know if the following is too much information for one of these posts. The original output (with error message) I receive when trying to list the files & folders on the SD card is as follows:

02/22/2011 12:00:00
Getting files and folders:
Files available on \SD:
\SD\ADS_4000_README.txt
Folders available on \SD:
    #### Exception System.IO.IOException - CLR_E_FILE_IO (4) ####
    #### Message: 
    #### Microsoft.SPOT.IO.VolumeInfo::.ctor [IP: 0000] ####
    #### Microsoft.SPOT.IO.RemovableMedia::MessageHandler [IP: 0022] ####
A first chance exception of type 'System.IO.IOException' occurred in Microsoft.SPOT.IO.dll
An unhandled exception of type 'System.IO.IOException' occurred in Microsoft.SPOT.IO.dll


When I add a 100 ms delay to the code the error message goes away and the program executes as intended.  Here is the listing with the one line fix "Thread.Sleep(100);" added:


 // SD caed section
 // SD Card is inserted
 // Create a new storage device
 PersistentStorage sdPS = new PersistentStorage("SD");
 // Mount the file system
 sdPS.MountFileSystem();
 // Assume one storage device is available, access it through 
 // Micro Framework and display available files and folders:
 Debug.Print("Getting files and folders:");
   if (VolumeInfo.GetVolumes()[0].IsFormatted)
      {
       string rootDirectory = VolumeInfo.GetVolumes()[0].RootDirectory;
       string[] files = Directory.GetFiles(rootDirectory);
       string[] folders = Directory.GetDirectories(rootDirectory);
       Debug.Print("Files available on " + rootDirectory + ":");
 // the following delay eliminated the 'System.IO.IOException' error 
       Thread.Sleep(100);
       for (int i = 0; i < files.Length; i++)
       Debug.Print(files[i]);
       Debug.Print("Folders available on " + rootDirectory + ":");
       for (int i = 0; i < folders.Length; i++)
       Debug.Print(folders[i]);
      }
        else
         {
           Debug.Print("Storage is not formatted. Format on PC first.");
         }
 // Unmount
 sdPS.UnmountFileSystem();

The output generated by the code with the delay fix is as follows:

02/24/2011 12:00:00
Getting files and folders:
Files available on \SD:
\SD\ADS_4000_README.txt
Folders available on \SD:
ADC value = 421 vmax= 424
ADC value = 421 vmax= 424
ADC value = 421 vmax= 424
02/24/2011 12:00:04
adc now= 107 13254770 ticks
02/24/2011 12:00:05
adc now= 107 23370771 ticks
02/24/2011 12:00:06
adc now= 107 33486375 ticks
The program ‘[3] Micro Framework application: Managed’ has exited with code 0 (0x0).

No folders are listed since there’s only the root folder on this card. The program thens goes on to execute as intended. The 100 ms delay is well before the unmount command, so doesn’t that imply that there’s something else causing the problem besides a unmount that is too fast?
Thanks for any insight you can provide.

Yes, this is exception is just because of fast unmount. It is in the message (event) handler which is in a separate thread and should not affect you.

Exception System.IO.IOException - CLR_E_FILE_IO (4)

Message:

Microsoft.SPOT.IO.VolumeInfo::.ctor [IP: 0000]

Microsoft.SPOT.IO.RemovableMedia::MessageHandler [IP: 0022]

WHere do i get this book everyone mentions?

See here:

And Welcome to the forum!