Question about In-Field Update over network remotely

I have read the tutirail about In-Field Updta from http://www.ghielectronics.com/docs/147/in-field-update and I find that EMX can be updated over network remotely. but there is only a example of updating from SD card in the tuturial.

Is there a example about In-Field Update over network remotely?

If I understand correctly, does EMX hat the feature as follow (see picture)? My EMX is with latest 4.2 SDK and micro framework firmware.

You can get the file from absolutely anything. IFU does not care where the files came from…it accepts a byte array of your data.

@ andre.m - , @ Gus

You mean that I can get files from any anything, but I must download/save these files in SD crad firstly, then run update from SD card, right?

@ andre.m -

thank you very much!

Actually, it is not safer as IFU automatically takes care of the buffering internally. There is no need to save data at all.

Good job GHI :slight_smile:

1 Like

Yeah, IFU for the G120 has been particularly elegant. For my application, I simply stream the update in chunks through serial, and it works quite well. And if there is a problem during the streaming, I can call SystemUpdate.Abort().

Dunno if the minimum byte-array size bug exists for the EMX or not, though. Even if it does, it should be fixed in the next SDK release.

I have some trouble in saving the files from form-upload to SD card.

I have the webserver in EMX and I have built a web page “FileUpLoad.html” for uploading the “Config.hex”, “Firmware.hex”, “Firmware2.hex” and “ManagedApp.hex” files. see as follow:

C# Programm.cs


           using (HttpServer server = new HttpServer())
           {
               server.AddEvent("/fileupload", new HttpServer.EventCallback(File_Upload));

               while (true)
               {
                   // Sleep for 500 milliseconds
                   Thread.Sleep(500);  
               }

           }
                      
                private static void File_Upload(object sender, HttpServer.EventCallbackEventArgs e)
        {
            e.Response = Resources.GetString(Resources.StringResources.FileUpLoad);
            e.ResponseContentType = "text/html";
        }

FileUpLoad.html


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
	<head>
		<title>File upload in HTML forms</title>
	</head>
	<body>

    <form action="http://www.cs.tut.fi/cgi-bin/run/~jkorpela/echo.cgi" enctype="multipart/form-data" method="post">
    
    <p>
    Please specify Config.hex file<br>
    <input type="file" name="Config" size="100">
    </p>
    
    <p>
    Please specify Firmware.hex file<br>
    <input type="file" name="Firmware" size="100">
    </p>
    
    <p>
    Please specify Firmware2.hex file<br>
    <input type="file" name="Firmware2" size="100">
    </p>

    <p>
    Please specify ManagedApp.hex file<br>
    <input type="file" name="ManagedApp" size="100">
    </p>
 <div>
    <input type="submit" value="Send">
</div>
</form>
	
	</body>
</html>


I really don’t know how can I receive the 4 files and save them into SD card for In-Field-Update? Can you give me some suggestion?

How can I save the content of upload-file to SD card?

I have tried many times, but not successful…

I have tried some codes as follow, but I haven’t found the content of upload-file.

C#



        private static void File_Upload(object sender, HttpServer.EventCallbackEventArgs e)
        {
            e.Response = Resources.GetString(Resources.StringResources.FileUpLoad);
            e.ResponseContentType = "text/html";
        }


        private static void uploadPage(object sender, HttpServer.EventCallbackEventArgs e)
        {
             if ((e.Post != null) && (e.Post["Config"] != null))
             {
                    e.Response = "You have uploaded the following text file: <br />";
                    e.Response += ((HttpServer.MultiPartItem)e.Post["Config"]).Content;


                    StreamWriter textFile = new StreamWriter(Parameter.SDCardRootDirectory + @ "\Config.hex");
                    textFile.WriteLine(((HttpServer.MultiPartItem)e.Post["Config"]).Content.ToString());
                    textFile.Close();
                    Debug.Print("Config.hex ready!");
             }
             else
             {
                     e.Response = "No data posted";
             }

             e.ResponseContentType = "text/html";
        }


html file:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
	<head>
		<title>File upload in HTML forms</title>
	</head>
	<body>

    <form action="/upload" enctype="multipart/form-data" method="post">
    
    <p>
    Please specify Config.hex file<br>
    <input type="file" name="Config" size="100">
    </p>
    

 <div>
    <input type="submit" value="Upload">
</div>
</form>
	
	</body>
</html>

Can you give me some help…?

thank you for your help!!

what does mean “split the files based on the boundary”? I’m not very clear.

I have tried some codes bymyself as follow:



 private static void File_Upload(object sender, HttpServer.EventCallbackEventArgs e)
        {
            e.Response = Resources.GetString(Resources.StringResources.FileUpLoad);
            e.ResponseContentType = "text/html";
        }

        private static void uploadPage(object sender, HttpServer.EventCallbackEventArgs e)
        {
            if ((e.Post != null) && (e.Post["Config"] != null))
            {
                e.Response = "You have uploaded the following text file: <br />";
                //e.Response += ((HttpServer.MultiPartItem)e.Post["Config"]).Content;


                string Content = ((HttpServer.MultiPartItem)e.Post["Config"]).Content.ToString();

                /*
                string[] words = Content.Split(' ');

                foreach (string word in words)
                {
                    Debug.Print(word);
                }

                */
                StreamWriter textFile = new StreamWriter(@ "SD\Config.hex");
                textFile.WriteLine(Content);
                textFile.Close();
                Debug.Print("Config.hex ready!");
                 

            }
            else
            {
                e.Response = "No data posted";
            }

            //e.ResponseContentType = "text/html";

        }

Question 1: what does mean “split the files based on the boundary”? Can you show me some example?

Question 2: I can upload “Config.hex” with above codes, but I must change the extention of “Config.hex” to “Config.txt” (see picture), I can’t upload “Config.hex” directly. Is it possible to upload “Config.hex” directly ?

Question 3: the “Config.hex” is only 7KB. I can’t upload the file “Firmware.hex” with the same method(see above codes). I think “Firmware.hex” is too big( 1322KB), I have tried many times and I find that the uploading is successful if the file smaller as about 100KB. How can I upload the big file(Firmware.hex)?

@ andre.m -

I have tried my codes many times again, and I have 2 questions. The test C# codes and html codes are as follow:

C# codes:


           using (HttpServer server = new HttpServer())
           {
               server.AddEvent("/fileupload", new HttpServer.EventCallback(File_Upload));
               server.AddEvent("/upload", new HttpServer.EventCallback(uploadPage));

               while (true)
               {
                   // Sleep for 500 milliseconds
                   Thread.Sleep(500);  
               }
}


        private static void File_Upload(object sender, HttpServer.EventCallbackEventArgs e)
        {
            e.Response = Resources.GetString(Resources.StringResources.FileUpLoad);
            e.ResponseContentType = "text/html";
        }

        private static void uploadPage(object sender, HttpServer.EventCallbackEventArgs e)
        {
            if ((e.Post != null) && (e.Post["Config"] != null))
            {
                e.Response = "You have uploaded the following text file: <br />";
                e.Response += ((HttpServer.MultiPartItem)e.Post["Config"]).Content;
            }
            else
            {
                e.Response = "No data posted";
            }

            e.ResponseContentType = "text/html";

        }


FileUpLoad.html


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
	<head>
		<title>File upload in HTML forms</title>
	</head>
	<body>

    <form action="/upload" enctype="multipart/form-data" method="post">
    
    <p>
    Please specify Config.hex file<br>
    <input type="file" name="Config" size="100">
    </p>
    

 <div>
    <input type="submit" value="Upload">
</div>
</form>
	
	</body>
</html>

Question 1: How can I upload .hex file?

I have tested uploading Config.txt and Config.hex files, and the content of these files are same, olny the type of file is different.

If I upload Config.txt, I can see the content of these file in the webpage “/upload” after clicking “upload” buttom(see picture 1 and 2). I can use “…Content.ToString();” to get the string of content and save them into SD card for IFU.

If I upload Config.hex, I can’t see the content of these file in the webpage “/upload” after clicking “upload” buttom, I can only see “System.Byte[]” in the webpage “/upload” (see picture 3), I don’t know how can I get the string of content and save them into SD card for IFU.

Question 2: How can I upload big file (for example: Firmware.hex is 1,29 MB (1.352.832 bytes)?

In Question 1 I have tested only a small file Config.hex, and the Config.hex is 6,80 KB (6.968 bytes), It seems that no problem to upload about 10KB file.

I had some steps to test the Firmware.txt.

step1: After “F5” my project I open webpage, choose Firmware.txt and clik uploading buttom. I can see something from Visual Studio Output (see picture 4).
I found that “Post data exceeds maximum allowed size” from Visual Studio debug.

step 2: I found the define “POST_MULTIPART_MAX_SIZE” in HttpServer.cs and changed the size to “100*131072”, It seems that the size is big enough for Firmware.txt
see as follow, I have changed the “POST_MULTIPART_MAX_SIZE”:

in HttpServer.cs


        private const int POST_URLENCODED_MAX_SIZE = 4096;      // Maximum buffer size to use when receiving UrlEncoded POST requests
        private const int POST_MULTIPART_PAYLOAD_SIZE = 1024;   // Block size to use when receiving MultiPart POST requests
        private const int POST_MULTIPART_MAX_SIZE = 100*131072;     // Maximum buffer size to use when receving MultiPart POST requests

step 3: I test again like step 1. I found the new problem “Exception System.OutOfMemoryException”. (see picture 5)

I have also tried some differnt small “POST_MULTIPART_MAX_SIZE”, for example: “50131072", "25131072”, and “15*131072”. there is always the “System.OutOfMemoryException” problem…

I have thought about it, but I really have no idea about changing server code to store the received bytes on the SD Card.

Can you tell me, where and how can I change the code?

I don’t understand it. I only know if I want to write something to SD card, I must string something firstly. or is there any other method?

How can I get the content from “((HttpServer.MultiPartItem)e.Post[“Config”]).Content” after uploading the Config.hex file?

hello, I have resolved my first question by myself.

About my second question "How can I upload big file? ", it seems very hard for me…

i even don’t know where I can start…

I have checked all the forum about " System.OutOfMemoryException", I didn’t find anything that helps me.

I have also used the “Add debug.GC(true) to force” method, but it works not good…

I can upload only small hex file(Config.hex) , the test codes are as follow:


private static void uploadPage(object sender, HttpServer.EventCallbackEventArgs e)
        {
            
            if ((e.Post != null) && (e.Post["Config"] != null))
            {
                e.Response = "You have uploaded the following text file: <br />";
                byte[] data_byte = (byte[])(((HttpServer.MultiPartItem)e.Post["Config"]).Content);
                
                string path = @ "SD\Config.hex";

                Debug.GC(true);
                // Create a file stream object
                using (FileStream fHandle = new FileStream(path, FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None,  256)) 
                {
                    try
                    {
                        // Write the contents
                        fHandle.Write(data_byte, 0, data_byte.Length);
                    }

                    finally
                    {

                        // We're done.
                        fHandle.Close();
                        Debug.Print("Config.hex ready!");
                    }
            }
            else
            {
                e.Response = "No data posted";
            }


            e.ResponseContentType = "text/html";

        }
                    

                }

Where are the codes about “server store the complete file in a variable”?
Can you give some help or examples? thank you very much°!

@ workhard10 - If the file you are receiving is very large, you MUST do it in pieces. If you attempt to receive the file in one shot and store it in one big variable, you can run out of memory.

Here are some options:
1.) Receive the file in pieces, storing each piece in the SD card in small chunks. Look at the System.IO.FileStream.Write() method. Once you have all the in-field update files, you can then perform the in-field update. However, you cannot read the files from the SD card in one big lump either, because you will again run out of memory. You must read the files in pieces, passing each piece to the SystemUpdate.Load() method, which can accept small chunks of data and cumulatively adds them automatically.

http://www.ghielectronics.com/community/forum/topic?id=11434

2.) Bypass the SD card and stream your files in pieces, passing each piece directly to the SystemUpdate.Load() method which will then stitch them together. You can always abort this step if there is a problem.

At the heart of your in-field update code will be a statement like this:

SystemUpdate.Load(CurrentIFUType, packet, packet.Length);

Where “packet” is a small chunk of data belonging to a file.

@ Iggmoe -

thank you for your suggestion!

My problem is the Webserver is not wrritten bymyself. The Webserver is from https://www.ghielectronics.com/community/codeshare/entry/186 , I have tested many times and I found the “Exception System.OutOfMemoryException” happened in the methods as follow:


 private void ThreadProc()
{..........................}
 
private static Hashtable ParseMultiPartFormData(NetworkStreamWrapper stream, int contentLength, string boundary)
{.................}

I guess that I must change something in the above methods, but the above 2 methods are too complicated for me. I have tried to use your suggestion and any other suggestion, but the last result was that I made the webserver chaos…

Do you know how to change the codes/webserver, so that the big files will be uploaded?