asy508
October 25, 2023, 2:41am
21
I got Blink_sfu.bin (in Binary.h),in sketch SFU_LoadBinary.ino . So in external flash, I got Blink_sfu.bin.
Its not update the Zero flash.
Then, I upload SFUBoot.ino into Zero, it flash Blink_sfu.h into Zero but IDE doesnt recognize board anymore.
asy508
October 25, 2023, 3:47am
22
asy508:
Based on example from here . I rewrite to use with W5500 Ethernet.
/*
This example downloads sketch update over NB/Cat1 network. (but can also be used for wifi / GSM / other types of networks as well)
You can choose between HTTP and HTTPS connection.
It downloads the binary file and saves it to the MKRMEM flash to store and apply the downloaded binary file.
You can also works with other types of flash memory such as winbond W25QXX, just remember to adjust the flash page size if needed. (currently set to 256 bytes per page)
To create the bin file for update of a SAMD board (except of M0),
use in Arduino IDE command "Export compiled binary".
To create a bin file for AVR boards see the instructions in README.MD.
To try this example, you should have a web server where you put
the binary update. (such as amazon s3)
Modify the constants below to match your configuration.
Important note:
Don't forget to include the SFU library in the new sketch file as well!
Created based on ArduinoOTA library in March 2023
by Amir Pinkert
based on Nicola Elia and Juraj Andrassy work
*/
#include <Ethernet.h>
#include <SPI.h>
#include <ArduinoHttpClient.h>
#include <SFU.h>
#include <Arduino_MKRMEM.h>
#define Serial SerialUSB
EthernetClient transport;
byte mac[6] = {0xDE,0xAD,0xBE,0xEF,0xFE,0x05};
const char* BIN_FILENAME = "UPDATE.BIN";
void setup() {
Serial.begin(115200);
while (!Serial);
Ethernet.init (0);
Ethernet.begin(mac);
Serial.print("server is at ");
Serial.println(Ethernet.localIP());
flash.begin();
/*
// you can format the flash at this point, but everything stored on it will be deleted so use with care
Serial.println("Erasing chip ...");
flash.eraseChip();
Serial.println("Mounting ...");
int res = filesystem.mount();
if(res != SPIFFS_OK && res != SPIFFS_ERR_NOT_A_FS) {
Serial.println("mount() failed with error code "); Serial.println(res); return;
}
Serial.println("Unmounting ...");
filesystem.unmount();
Serial.println("Formatting ...");
res = filesystem.format();
if(res != SPIFFS_OK) {
Serial.println("format() failed with error code "); Serial.println(res); return;
}
*/
Serial.print("Mounting ... ");
if(SPIFFS_OK != filesystem.mount()) {
Serial.println("mount() failed with error code "); Serial.println(filesystem.err()); return;
}
Serial.println("OK");
Serial.print("Checking ... ");
if(SPIFFS_OK != filesystem.check()) {
Serial.println("check() failed with error code "); Serial.println(filesystem.err()); return;
}
Serial.println("OK");
// now connect to network
Serial.println("Starting Arduino web client.");
// connection state
boolean connected = false;
// start the modem with NB.begin()
// check for updates
checkForOTAUpdates();
}
void loop() {
// add your normal loop code below ...
}
void checkForOTAUpdates() {
const char* SERVER = "iot.armscloud.com"; // Set your correct hostname
const unsigned short SERVER_PORT = 80; // Commonly 80 (HTTP) | 443 (HTTPS)
//const char* PATH = "/update/ap_lan_v1_ssl.bin"; // Set the URI to the .bin firmware
//const char* PATH = "/update/SFUBoot.bin";
//const char* PATH = "/update/SFUBoot_boot.bin";
const char* PATH = "/update/Blink_sfu.bin";
//const char* PATH = "/update/Blink_sfu_boot.bin";
HttpClient client(transport, SERVER, SERVER_PORT); // HTTP
char buff[32];
snprintf(buff, sizeof(buff), PATH);
Serial.print("Check for update file ");
Serial.println(buff);
// Make the GET request
client.get(buff);
int statusCode = client.responseStatusCode();
Serial.print("Update status code: ");
Serial.println(statusCode);
if (statusCode != 200) {
client.stop();
return;
}
unsigned long length = client.contentLength();
if (length == HttpClient::kNoContentLengthHeader) {
client.stop();
Serial.println("Server didn't provide Content-length header. Can't continue with update.");
return;
}
Serial.print("Server returned update file of size ");
Serial.print(length);
Serial.println(" bytes");
Serial.println("Creating \"UPDATE.BIN\" ... ");
File file = filesystem.open(BIN_FILENAME, CREATE | WRITE_ONLY| APPEND);
Serial.println("File created");
client.setTimeout(30000); // works well with 30 seconds
byte b;
uint16_t flashBufferSize = 256; // adjust according to your flash page size
byte flashBuffer[flashBufferSize];
uint16_t i = 0;
int localChecksum = 0; // this is optional - you can get the intended checksum value from your server and compare with your local file to make sure your local file was downloaded correctly
while (length > 0) {
if (!client.readBytes(&b, 1)) // reading a byte with timeout
break;
// add to flashBuffer
flashBuffer[i] = b;
// add to checksum
int bValue = (int)b;
localChecksum = localChecksum + bValue;
i ++;
// check if flashBuffer is full
if (i > (flashBufferSize - 1)){
// write to file
file.write((void *)flashBuffer, flashBufferSize);
// reset i
i = 0;
}
length--;
}
// add whats left on the flashBuffer
if (i > 0){
byte remainderBuffer[i];
// fill buffer
for (uint16_t x=0; x <= i; x++) {
remainderBuffer[x] = flashBuffer[x];
}
// write to file
file.write((void *)remainderBuffer, i);
}
file.close();
client.stop();
if (length > 0) {
filesystem.remove(BIN_FILENAME);
filesystem.unmount();
Serial.print("Timeout downloading update file at ");
Serial.print(length);
Serial.println(" bytes. Can't continue with update.");
return;
}
Serial.print("Local checksum:");
Serial.println(localChecksum);
Serial.print("Download finished. Unmounting ... ");
filesystem.unmount();
Serial.println("OK");
Serial.println("Sketch update apply and reset.");
Serial.flush();
}
Result:
14:53:18.339 -> server is at 192.168.0.214
14:53:18.339 -> Mounting ... OK
14:53:18.710 -> Checking ... OK
14:53:25.784 -> Starting Arduino web client.
14:53:25.784 -> Check for update file /update/Blink_sfu.bin
14:53:26.854 -> Update status code: 200
14:53:26.902 -> Server returned update file of size 46260 bytes
14:53:26.902 -> Creating "UPDATE.BIN" ...
14:53:27.182 -> File created
14:53:29.926 -> Local checksum:3381931
14:53:29.926 -> Download finished. Unmounting ... OK
14:53:29.926 -> Sketch update apply and reset.
It doesnt update the Zero board.
Its same if i try use this sketch. Its download the firmware, but not apply into Zero flash, its update after I upload SFUBoot.ino into it and IDE can recognize.
Edit : I try again a few times, sometimes IDE doesnt recognize Zero.
Edit : Need to restart IDE to make it recognize Zero
Edit : So, I believe SFUBoot.ino is working with Zero
Juraj
October 25, 2023, 9:27am
23
so now the build.sh. do you have a way to run it?
asy508
October 25, 2023, 9:30am
24
I m not sure about it. What does this script do? Is it convert from bin file to C header file?
Juraj
October 25, 2023, 11:48am
25
it converts bin to hex array. it uses a tool available in Linux
asy508
October 25, 2023, 12:14pm
26
cat SKETCH.bin | xxd --include > Binary.h
So it similar to this command in Linux.
Juraj
October 25, 2023, 12:46pm
27
https://www.tutorialspoint.com/unix_commands/xxd.htm
xxd creates a hex dump of a given file or standard input.
asy508
October 26, 2023, 1:25am
28
If that so, I can use linux to convert bin to hex array.
My question is, how to make Zero flash update, after download new firmware? Right now, I only can download firmware into external flash, and need to flash SFUBoot.ino to apply new firmware.
Juraj
October 26, 2023, 7:04am
29
you can use ArduinoOTA library's SerialFlashStorage
asy508
October 26, 2023, 8:24am
30
#include <SerialFlashStorage.h>
SerialFlashStorageClass SerialFlashStorage;
void setup()
{
//after download new firmware into external flash
SerialFlashStorage.apply();
}
Is this correct? I m not sure.
Juraj
October 26, 2023, 9:44am
31
the SFU library preppends the compiled SFUBoot to the current sketch. including SFU adds SFUBoot to the sketch.
so after a reset SFUBoot runs and loads the update from the external flash into the internal flash
asy508
October 27, 2023, 1:29am
32
I include SFU into Blink sketch, it doesnt update. Is it possible because I use mkrzero.h in SFU? But I can use SFUBoot.ino on zero.
Juraj
October 27, 2023, 5:23am
33
so I thought you made your version of the SFU with Zero support.
the build.sh created a file which you should integrate into your version of the SFU library
asy508
October 27, 2023, 6:33am
34
asy508:
so, i download and save into example SFU directory.
Right now, I could not figure out how make SFU.h work with Zero. So that, I just use, mkrzero.h by
redefine SFU.cpp
#if defined(ARDUINO_SAMD_MKRZERO) || defined(ARDUINO_SAMD_ZERO)
#include "boot/mkrzero.h"
I am not sure how to make zero version for SFU, I though I can use mkrzero.h for zero. Do you have guide how to do it?
Juraj
October 27, 2023, 6:57am
35
did you add a new line in build.sh? or create zero.h with some other way?
add a new #if for Zero in SFU.cpp
asy508
October 27, 2023, 7:04am
36
from my understanding, SFUBoot.ino compile binary, then convert into hex array. Then add to SFU.h? Is this correct?
Edit: Ok Done. Update Blink work. I got it. Thank you for your help and time. I m really appreciate.
Next, I will try with Ethernet and I will update here, it should be fine.
1 Like
system
Closed
April 24, 2024, 7:04am
37
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.