Skip to content

Update SD example #7

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Feb 15, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 95 additions & 11 deletions examples/OTA_SD_Portenta/OTA_SD_Portenta.ino
Original file line number Diff line number Diff line change
@@ -1,44 +1,128 @@
/*
This example demonstrates how to use to update
the firmware of the Arduino Portenta H7 using
a firmware image stored on a SD card.
* This example demonstrates how to use to update the firmware of the Arduino Portenta H7 using
* a firmware image stored on the SD.
*
* Steps:
* 1) Create a sketch for the Portenta H7 and verifiy
* that it both compiles and works on a board.
* 2) In the IDE select: Sketch -> Export compiled Binary.
* 3) Create an OTA update file utilising the tools 'lzss.py' and 'bin2ota.py' stored in
* https://github.com/arduino-libraries/ArduinoIoTCloud/tree/master/extras/tools .
* A) ./lzss.py --encode SKETCH.bin PORTENTA_H7_M7.lzss
* B) ./bin2ota.py PORTENTA_H7_M7.lzss PORTENTA_H7_M7.ota
* 4) Upload the OTA file to a network reachable location, e.g. OTA_Usage_Portenta.ino.PORTENTA_H7_M7.ota
* has been uploaded to: http://downloads.arduino.cc/ota/OTA_Usage_Portenta.ino.PORTENTA_H7_M7.ota
* 5) Perform an OTA update via steps outlined below.
*/

#include "Arduino_Portenta_OTA.h"
/******************************************************************************
* INCLUDE
******************************************************************************/

#include <Arduino_Portenta_OTA.h>

#include <WiFi.h>

#include "arduino_secrets.h"

/******************************************************************************
* CONSTANT
******************************************************************************/

/* Please enter your sensitive data in the Secret tab/arduino_secrets.h */
static char const SSID[] = SECRET_SSID; /* your network SSID (name) */
static char const PASS[] = SECRET_PASS; /* your network password (use for WPA, or use as key for WEP) */

static char const OTA_FILE_LOCATION[] = "http://downloads.arduino.cc/ota/OTA_Usage_Portenta.ino.PORTENTA_H7_M7.ota";

/******************************************************************************
* SETUP/LOOP
******************************************************************************/

void setup()
{
Serial.begin(115200);
while (!Serial) {}

Serial.println("*****OTA from SD*****");
Arduino_Portenta_OTA_SD ota(SD_OFFSET, 10240);
if (WiFi.status() == WL_NO_SHIELD)
{
Serial.println("Communication with WiFi module failed!");
return;
}

int status = WL_IDLE_STATUS;
while (status != WL_CONNECTED)
{
Serial.print ("Attempting to connect to '");
Serial.print (SSID);
Serial.println("'");
status = WiFi.begin(SSID, PASS);
delay(10000);
}
Serial.print ("You're connected to '");
Serial.print (WiFi.SSID());
Serial.println("'");

//Arduino_Portenta_OTA_SD ota(SD_FATFS, 0);
Arduino_Portenta_OTA_SD ota(SD_FATFS_MBR, 1);
Arduino_Portenta_OTA::Error ota_err = Arduino_Portenta_OTA::Error::None;

if (!ota.isOtaCapable())
{
Serial.println("Higher version bootloader required to perform OTA.");
Serial.println("Please update the bootloader.");
Serial.println("File -> Examples -> Portenta_System -> PortentaH7_updateBootloader");
return;
}

Serial.println("Initializing OTA storage");
if ((ota_err = ota.begin()) != Arduino_Portenta_OTA::Error::None)
{
Serial.print ("ota.begin() failed with error code ");
Serial.print ("Arduino_Portenta_OTA::begin() failed with error code ");
Serial.println((int)ota_err);
return;
}

/* This function sets the precise length of update binary, in this case of OTA_Usage_Portenta.ino.PORTENTA_H7_M7.bin */
ota.setUpdateLen(131728);

Serial.println("Starting download to SD ...");
int const ota_download = ota.download(OTA_FILE_LOCATION, false /* is_https */);
if (ota_download <= 0)
{
Serial.print ("Arduino_Portenta_OTA_SD::download failed with error code ");
Serial.println(ota_download);
return;
}
Serial.print (ota_download);
Serial.println(" bytes stored.");


Serial.println("Decompressing LZSS compressed file ...");
int const ota_decompress = ota.decompress();
if (ota_decompress < 0)
{
Serial.print("Arduino_Portenta_OTA_SD::decompress() failed with error code");
Serial.println(ota_decompress);
return;
}
Serial.print(ota_decompress);
Serial.println(" bytes decompressed.");


Serial.println("Storing parameters for firmware update in bootloader accessible non-volatile memory");
if ((ota_err = ota.update()) != Arduino_Portenta_OTA::Error::None)
{
Serial.print ("ota.update() failed with error code ");
Serial.print ("Arduino_Portenta_OTA::update() failed with error code ");
Serial.println((int)ota_err);
return;
}

Serial.println("Performing a reset after which the bootloader will update the firmware.");
Serial.println("Hint: Portenta H7 LED will blink Red-Blue-Green.");
delay(1000);
ota.reset();
}

void loop()
{

}
}
2 changes: 2 additions & 0 deletions examples/OTA_SD_Portenta/arduino_secrets.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#define SECRET_SSID ""
#define SECRET_PASS ""
22 changes: 12 additions & 10 deletions examples/OTA_Usage_Portenta/OTA_Usage_Portenta.ino
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
/*
Usage
This example demonstrates how to use the Arduino_Portenta_OTA library to update a
sketch on any Portenta via the storage types allowed by the board.
Steps to update sketch:
1) Upload this sketch or any other sketch (this one lights the LED up with different colours).
This sketch can be used to generate an example binary that can be uploaded to Portenta via OTA.
It needs to be used together with
- 'OTA_Qspi_Flash.ino' if you want to use the Qspi Flash as storage system
OR
- 'SD_Qspi_Flash.ino' if you want to use the SD card as storage system

Steps to test OTA on Portenta:
1) Upload this sketch or any other sketch (this one lights up the RGB LED with different colours).
2) In the IDE select: Sketch -> Export compiled Binary
3) Open the location of the sketch and choose the next step according to the desired storage type:
- SD: copy the binary to the SD with the name "UPDATE.BIN"
- INTERNAL FLASH:
- QSPI Flash:
5) Upload the sketch OTA_*_Portenta.ino
3) Upload the exported binary to a server
4) Choose a storage mechanism (SD or QSPI), open the related OTA_*_Portenta.ino sketch,
eventually update the OTA_FILE_LOCATION
5) Upload the sketch OTA_*_Portenta.ino to perform OTA via SD or QSPI Flash
*/

void setLed(int blue, int gree, int red) {
Expand Down
5 changes: 1 addition & 4 deletions src/Arduino_Portenta_OTA_SD.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,6 @@ Arduino_Portenta_OTA_SD::Arduino_Portenta_OTA_SD(StorageTypePortenta const stora

bool Arduino_Portenta_OTA_SD::init()
{
if (_block_device.init())
return false;

if(_storage_type == SD_FATFS)
{
_fs_sd = new mbed::FATFileSystem("fs");
Expand All @@ -70,7 +67,7 @@ bool Arduino_Portenta_OTA_SD::init()

if (_storage_type == SD_FATFS_MBR)
{
_bd = new mbed::MBRBlockDevice(reinterpret_cast<mbed::BlockDevice *>(&_block_device), 1);
_bd = new mbed::MBRBlockDevice(reinterpret_cast<mbed::BlockDevice *>(&_block_device), _data_offset);
_fs_sd = new mbed::FATFileSystem("fs");
int const err = _fs_sd->mount(_bd);
if (err)
Expand Down