Skip to content

Commit 3eac365

Browse files
committed
Add example to perform OTA on M4
1 parent 5855289 commit 3eac365

File tree

4 files changed

+169
-0
lines changed

4 files changed

+169
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
/*
2+
* This example demonstrates how to update the firmware of the Arduino Portenta H7 M4 core
3+
* using a firmware image stored on the QSPI.
4+
*
5+
* WARNING: Only 1MB M7 + 1MB M4 flash split is supported
6+
*
7+
* Steps:
8+
* 1) Create a sketch for the Portenta H7 M4 core using 1MB M7 + 1MB M4 flash split and verify
9+
* that it both compiles and works on a board.
10+
* 2) In the IDE select: Sketch -> Export compiled Binary.
11+
* 3) Create an OTA update file utilising the tools 'lzss.py' and 'bin2ota.py' stored in
12+
* https://github.com/arduino-libraries/ArduinoIoTCloud/tree/master/extras/tools .
13+
* A) ./lzss.py --encode SKETCH.bin SKETCH.lzss
14+
* B) ./bin2ota.py PORTENTA_H7_M7 SKETCH.lzss SKETCH.ota
15+
* 4) Upload the OTA file to a network reachable location, e.g. OTA_Usage_Portenta.ino.PORTENTA_H7_M4.ota
16+
* has been uploaded to: http://downloads.arduino.cc/ota/OTA_Usage_Portenta.ino.PORTENTA_H7_M4.ota
17+
* 5) Perform an OTA update via steps outlined below.
18+
*/
19+
20+
/******************************************************************************
21+
* INCLUDE
22+
******************************************************************************/
23+
24+
#include <Arduino_Portenta_OTA.h>
25+
26+
#include <WiFi.h>
27+
28+
#include "RPC.h"
29+
30+
#include "arduino_secrets.h"
31+
32+
/******************************************************************************
33+
* CONSTANT
34+
******************************************************************************/
35+
36+
/* Please enter your sensitive data in the Secret tab/arduino_secrets.h */
37+
static char const SSID[] = SECRET_SSID; /* your network SSID (name) */
38+
static char const PASS[] = SECRET_PASS; /* your network password (use for WPA, or use as key for WEP) */
39+
40+
#if defined(ARDUINO_PORTENTA_H7_M7)
41+
static char const OTA_FILE_LOCATION[] = "https://downloads.arduino.cc/ota/OTA_Usage_Portenta.ino.PORTENTA_H7_M4.ota";
42+
#else
43+
#error "Board not supported"
44+
#endif
45+
46+
/******************************************************************************
47+
* SETUP/LOOP
48+
******************************************************************************/
49+
50+
void setup()
51+
{
52+
// Initialize RPC library; this also boots the M4 core
53+
RPC.begin();
54+
55+
Serial.begin(115200);
56+
while (!Serial) {}
57+
58+
Serial.println("Do you want to install/update the M4 core firmware? Y/[n]");
59+
if(!waitResponse()) {
60+
Serial.println("Nothing to do. It's now safe to reboot or disconnect your board.");
61+
return;
62+
}
63+
64+
if (WiFi.status() == WL_NO_SHIELD)
65+
{
66+
Serial.println("Communication with WiFi module failed!");
67+
return;
68+
}
69+
70+
int status = WL_IDLE_STATUS;
71+
while (status != WL_CONNECTED)
72+
{
73+
Serial.print ("Attempting to connect to '");
74+
Serial.print (SSID);
75+
Serial.println("'");
76+
status = WiFi.begin(SSID, PASS);
77+
delay(10000);
78+
}
79+
Serial.print ("You're connected to '");
80+
Serial.print (WiFi.SSID());
81+
Serial.println("'");
82+
83+
Arduino_Portenta_OTA_QSPI ota(QSPI_FLASH_FATFS_MBR, 2);
84+
Arduino_Portenta_OTA::Error ota_err = Arduino_Portenta_OTA::Error::None;
85+
86+
if (!ota.isOtaCapable())
87+
{
88+
Serial.println("Higher version bootloader required to perform OTA.");
89+
Serial.println("Please update the bootloader.");
90+
Serial.println("File -> Examples -> Portenta_System -> PortentaH7_updateBootloader");
91+
return;
92+
}
93+
94+
Serial.println("Initializing OTA storage");
95+
if ((ota_err = ota.begin()) != Arduino_Portenta_OTA::Error::None)
96+
{
97+
Serial.print ("Arduino_Portenta_OTA::begin() failed with error code ");
98+
Serial.println((int)ota_err);
99+
return;
100+
}
101+
102+
103+
Serial.println("Starting download to QSPI ...");
104+
int const ota_download = ota.download(OTA_FILE_LOCATION, true /* is_https */);
105+
if (ota_download <= 0)
106+
{
107+
Serial.print ("Arduino_Portenta_OTA_QSPI::download failed with error code ");
108+
Serial.println(ota_download);
109+
return;
110+
}
111+
Serial.print (ota_download);
112+
Serial.println(" bytes stored.");
113+
114+
115+
Serial.println("Decompressing LZSS compressed file ...");
116+
int const ota_decompress = ota.decompress();
117+
if (ota_decompress < 0)
118+
{
119+
Serial.print("Arduino_Portenta_OTA_QSPI::decompress() failed with error code");
120+
Serial.println(ota_decompress);
121+
return;
122+
}
123+
Serial.print(ota_decompress);
124+
Serial.println(" bytes decompressed.");
125+
126+
127+
Serial.println("Storing parameters for firmware update in bootloader accessible non-volatile memory ...");
128+
if ((ota_err = ota.update()) != Arduino_Portenta_OTA::Error::None)
129+
{
130+
Serial.print ("ota.update() failed with error code ");
131+
Serial.println((int)ota_err);
132+
return;
133+
}
134+
135+
Serial.println("Performing a reset after which the bootloader will update the firmware.");
136+
Serial.println("Hint: Portenta H7 LED will blink Red-Blue-Green.");
137+
delay(1000); /* Make sure the serial message gets out before the reset. */
138+
ota.reset();
139+
}
140+
141+
void loop()
142+
{
143+
144+
}
145+
146+
bool waitResponse() {
147+
bool confirmation = false;
148+
while (confirmation == false) {
149+
if (Serial.available()) {
150+
char choice = Serial.read();
151+
switch (choice) {
152+
case 'y':
153+
case 'Y':
154+
confirmation = true;
155+
return true;
156+
break;
157+
case 'n':
158+
case 'N':
159+
confirmation = true;
160+
return false;
161+
break;
162+
default:
163+
continue;
164+
}
165+
}
166+
}
167+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#define SECRET_SSID ""
2+
#define SECRET_PASS ""
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)