Go Down

Topic: Arduino Zero OTA update over GPRS (Read 1 time) previous topic - next topic

sigalabs

We have developed an Arduino Zero based custom device that has also internal SPI flash memory and GPRS modem for connectivity.
What we would like to achieve is a code that downloads a new firmware bin file over a FTP server, save it to the external SPI flash and then perform a firmware update on the internal flash.
That way we can remotely update the firmware on the board.

Can anyone please advise how we can achieve this?

From my understanding:

1) We should export a bin file with the newer firmware
2) Download it to the external flash of the custom device using the FTP
3) Use a custom bootloader to write the external flash addresses to the internal flash and update code?

Is a custom bootloader what we really need? Is there any other way with stock arduino zero bootloader?

Thank you very much!

Juraj

#1
Feb 02, 2019, 10:21 pm Last Edit: Feb 02, 2019, 10:25 pm by Juraj
see the SDU library.

or you can upload the bin to upper half of the internal flash and then move it to running location like the InternalStorage class of the WiFi101OTA library does

sigalabs

Hi Juraj,

thank you very much for your feedback. So from my understanding from the WIFI101 OTA library:

1) i should export a binary firmware file from the Arduino IDE
2) Upload it to my FTP server
3) Download it using GPRS and copy it to the internal flash with a code similar to this

Code: [Select]
while (client.connected() && read < contentLength) {
      while (client.available()) {
        read++;

        _storage->write((char)client.read());
      }
    }

    _storage->close();

_storage->apply();


4) Then the micro would restart and run on the new code



I would like to ask the following:

a) Do i need a custom bootloader or i could use the stock Arduino Zero for this to work

b) How should i export the binary file for the OTA? Do i need a special linker script or i just use the binary from the "Sketch / Export Compiled Binary" menu?

Thank you very much !



Juraj

I would like to ask the following:

a) Do i need a custom bootloader or i could use the stock Arduino Zero for this to work

b) How should i export the binary file for the OTA? Do i need a special linker script or i just use the binary from the "Sketch / Export Compiled Binary" menu?

a) bootloader is not involved
b) use "Export compiled binary" in Sketch menu. the output is in the sketch folder

sigalabs

Thank you very much Juraj, i managed to make it work using the internal flash method of the WIFI101OTA as you proposed.


The steps i have followed:

1) Init storage with file size
WiFiOTA._storage->open(8508); // firmware size as value

2) Write all bytes through looping
WiFiOTA._storage->write((char)incoming_data);

3) Close and apply! Your new firmware is ready!
WiFiOTA._storage->close();
WiFiOTA._storage->apply();


Juraj

Thank you very much Juraj, i managed to make it work using the internal flash method of the WIFI101OTA as you proposed.


The steps i have followed:

1) Init storage with file size
WiFiOTA._storage->open(8508); // firmware size as value

2) Write all bytes through looping
WiFiOTA._storage->write((char)incoming_data);

3) Close and apply! Your new firmware is ready!
WiFiOTA._storage->close();
WiFiOTA._storage->apply();


If you included the library, InternalStorage object exists.
open() doesn't use the parameter.

sindrevr

I am thinking about the same.... is there any manuals/howto`s for using WiFI101OTA for updating sketch directly from an HTTP/FTP server? Have been searching for hours and cannot find any. Sigalabs, would be appreciated if you could share in more details / post example sketch for acheiving this.

BR,
Sindre

Juraj

I am thinking about the same.... is there any manuals/howto`s for using WiFI101OTA for updating sketch directly from an HTTP/FTP server? Have been searching for hours and cannot find any. Sigalabs, would be appreciated if you could share in more details / post example sketch for acheiving this.

BR,
Sindre
the library is for upload from IDE. but the InternalStorage object of WiFI101OTA library can be 'feed' from any source.

vukovic

I am trying to update my Arduino Mega OTA.
I burned Optiboot to my board to be able to use ArduinoOTA library, and I am using SIM800L module. The sketch is exported as .hex file, and uploaded to the server.

My idea is to download the .hex file from server and use ArduinoOTA to perform something like @Sigilabs suggested. This is the code which is supposed to do the trick :

Code: [Select]
char *binaryUpdate;
    inet.httpGET("server", 80, "path to hex", binaryUpdate, 1000);

    ArduinoOTA._storage->open(1000);

    int i = 0;
    while (binaryUpdate[i] != '\0')
    {
        ArduinoOTA._storage->write(binaryUpdate[i]);
        i++;
    }

    ArduinoOTA._storage->close();
    ArduinoOTA._storage->apply();


The problem is that the inetGSM library which I use to download the sketch, stores it to the binaryUpdate variable, and there is not enough memory to do that. What I want instead, is to write the downloaded file directly to ArduinoOTA's InternalStorage, character by character, as they are downloaded from the server.

Can anyone point me to the right direction on how to do that ? GRPS is the only way to perform download, I cannot use WiFi.

Juraj

I am trying to update my Arduino Mega OTA.
I burned Optiboot to my board to be able to use ArduinoOTA library, and I am using SIM800L module. The sketch is exported as .hex file, and uploaded to the server.

My idea is to download the .hex file from server and use ArduinoOTA to perform something like @Sigilabs suggested. This is the code which is supposed to do the trick :

Code: [Select]
char *binaryUpdate;
    inet.httpGET("server", 80, "path to hex", binaryUpdate, 1000);

    ArduinoOTA._storage->open(1000);

    int i = 0;
    while (binaryUpdate[i] != '\0')
    {
        ArduinoOTA._storage->write(binaryUpdate[i]);
        i++;
    }

    ArduinoOTA._storage->close();
    ArduinoOTA._storage->apply();


The problem is that the inetGSM library which I use to download the sketch, stores it to the binaryUpdate variable, and there is not enough memory to do that. What I want instead, is to write the downloaded file directly to ArduinoOTA's InternalStorage, character by character, as they are downloaded from the server.

Can anyone point me to the right direction on how to do that ? GRPS is the only way to perform download, I cannot use WiFi.
use bin file, because the hex file has not only sketch data. it has lines with addresses a check sum and other control values

vukovic

#10
Jul 24, 2019, 05:53 pm Last Edit: Jul 24, 2019, 05:54 pm by vukovic
I googled how to do it, because I get only .hex generated, and I've found your reply here :

https://arduino.stackexchange.com/questions/57132/why-is-there-no-hex-file-generated-when-i-build-binary-output-from-the-arduino

Which states :

Code: [Select]
For AVR boards "Export compiled binary" generates hex.

If I understand correctly, Arduino Mega 2560 is AVR board ? Can I somehow still generate .bin ?

Juraj

#11
Jul 24, 2019, 06:23 pm Last Edit: Jul 24, 2019, 06:24 pm by Juraj
I googled how to do it, because I get only .hex generated, and I've found your reply here :

https://arduino.stackexchange.com/questions/57132/why-is-there-no-hex-file-generated-when-i-build-binary-output-from-the-arduino

Which states :

Code: [Select]
For AVR boards "Export compiled binary" generates hex.

If I understand correctly, Arduino Mega 2560 is AVR board ? Can I somehow still generate .bin ?
https://github.com/jandrassy/ArduinoOTA#atmega-support
https://github.com/jandrassy/ArduinoOTA/blob/ab7792d6d776b5ecc4e09e688cbb5c6ab37ccbab/extras/avr/platform.local.txt#L5

vukovic

I've generated the .bin and downloaded it, but Arduino restarts after the download, to be exact, in the line before the while. I have 4kB of available memory, and the .bin is below 2kB.

Juraj

I've generated the .bin and downloaded it, but Arduino restarts after the download, to be exact, in the line before the while. I have 4kB of available memory, and the .bin is below 2kB.
allocate the memory

char binaryUpdate[2000];

Go Up