Hi,
In my Arduino IDE doesnt have
and
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"
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.
I try with both link my Blink_sfu.bin and Blink_sfu_boot.bin
this is Blink.ino
#include <Arduino_MKRMEM.h>
#include <SFU.h>
// the setup function runs once when you press reset or power the board
void setup() {
// initialize digital pin LED_BUILTIN as an output.
pinMode(LED_BUILTIN, OUTPUT);
}
// the loop function runs over and over again forever
void loop() {
digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
delay(1000); // wait for a second
digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
delay(1000); // wait for a second
}
Is this the correct step?
Edit: Hardware used => Arduino Zero,W5500, W25Q64FV