Skip to content

Commit da11900

Browse files
committed
MCUboot library: add examples
1 parent 7f00608 commit da11900

File tree

2 files changed

+194
-0
lines changed

2 files changed

+194
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
This example shows how to enable/disable bootloader debug
3+
using MCUboot library. The used debug output is Serial1
4+
5+
Circuit:
6+
- Arduino Portenta H7 board
7+
8+
This example code is in the public domain.
9+
*/
10+
11+
#include <MCUboot.h>
12+
13+
// the setup function runs once when you press reset or power the board
14+
void setup() {
15+
// set RTC register DR7
16+
MCUboot::bootDebug(true);
17+
}
18+
19+
// the loop function runs over and over again forever
20+
void loop() {
21+
22+
23+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
/*
2+
This example shows how to perform an OTA with MCUboot
3+
using MCUboot library.
4+
5+
WARNING: The ota binary is signed and encrypted with default keys.
6+
The example will work only if default keys are flashed within the
7+
bootloader otherwise MCUboot will refuse to boot the OTA binary
8+
9+
Circuit:
10+
- Arduino Portenta H7 board
11+
12+
This example code is in the public domain.
13+
*/
14+
15+
#include "BlockDevice.h"
16+
#include "MBRBlockDevice.h"
17+
#include "FATFileSystem.h"
18+
#include <MCUboot.h>
19+
#include <WiFi.h>
20+
21+
static char const SSID[] = "SECRET_SSID"; /* your network SSID (name) */
22+
static char const PASS[] = "SECRET_PASS"; /* your network password (use for WPA, or use as key for WEP) */
23+
24+
static char const OTA_FILE_LOCATION[] = "https://downloads.arduino.cc/ota/OTA_Usage_Portenta.ino.PORTENTA_H7_M7.MCUboot.slot";
25+
26+
static const int MCUBOOT_SLOT_SIZE = 0x1E0000;
27+
28+
bool applyUpdate = false;
29+
bool confirmUpdate = false;
30+
31+
// the setup function runs once when you press reset or power the board
32+
void setup() {
33+
Serial.begin(9600);
34+
while(!Serial);
35+
36+
if (WiFi.status() == WL_NO_SHIELD)
37+
return;
38+
39+
int status = WL_IDLE_STATUS;
40+
while (status != WL_CONNECTED)
41+
{
42+
Serial.print("Attempting to connect to SSID: ");
43+
Serial.println(SSID);
44+
status = WiFi.begin(SSID, PASS);
45+
delay(3000);
46+
}
47+
Serial.println("Connected to wifi");
48+
49+
Serial.println("Are you ready to apply a new update? Y/[n]");
50+
applyUpdate = waitResponse();
51+
52+
if (applyUpdate) {
53+
54+
// Mount filesystem and download the OTA file
55+
mbed::BlockDevice * raw = mbed::BlockDevice::get_default_instance();
56+
mbed::MBRBlockDevice * mbr = new mbed::MBRBlockDevice(raw, 2);
57+
int err = mbr->init();
58+
if (err < 0) {
59+
Serial.print("Error initializing Block Device ");
60+
Serial.println(err);
61+
return;
62+
}
63+
64+
mbed::FATFileSystem * fs = new mbed::FATFileSystem("ota");
65+
err = fs->mount(mbr);
66+
if (err < 0) {
67+
Serial.print("Error mounting filesystem ");
68+
Serial.println(err);
69+
return;
70+
}
71+
72+
Serial.println("Downloading update file");
73+
err = WiFi.download((char*)OTA_FILE_LOCATION, "/ota/update.bin", true);
74+
if (err < 0) {
75+
Serial.print("Error downloading file ");
76+
Serial.println(err);
77+
return;
78+
}
79+
80+
// OTA file is not padded to reduce download time,
81+
// but MCUboot needs update file to be padded
82+
FILE* update_file = fopen("/ota/update.bin", "rb+");
83+
fseek(update_file, 0, SEEK_END);
84+
int fsize = ftell(update_file);
85+
86+
Serial.print("File update.bin size ");
87+
Serial.println( fsize );
88+
89+
if (fsize < MCUBOOT_SLOT_SIZE) {
90+
const char buffer[1] = {0xFF};
91+
92+
Serial.println("Padding update file");
93+
printProgress(fsize, MCUBOOT_SLOT_SIZE, 10, true);
94+
while (fsize < MCUBOOT_SLOT_SIZE) {
95+
int ret = fwrite(buffer, 1, 1, update_file);
96+
if (ret != 1) {
97+
Serial.println("Error writing update file");
98+
break;
99+
}
100+
fsize += 1;
101+
printProgress(fsize, MCUBOOT_SLOT_SIZE, 10, false);
102+
}
103+
}
104+
Serial.println("Flashed 100%");
105+
106+
fseek(update_file, 0, SEEK_END);
107+
Serial.print("File update.bin size ");
108+
Serial.println( fsize );
109+
110+
if(fsize != 0x1E0000) {
111+
Serial.print("Error padding file ");
112+
return;
113+
}
114+
115+
fclose(update_file);
116+
fs->unmount();
117+
118+
// Is it possible to pre-confirm padded OTA file to prevent rollback
119+
Serial.println("Do you want to make the update permanent? Y/[n]");
120+
confirmUpdate = waitResponse();
121+
122+
// Set update pending and image OK flags
123+
MCUboot::applyUpdate(confirmUpdate);
124+
Serial.println("Done, waiting reset");
125+
} else {
126+
Serial.println("No update pending. It's now safe to reboot or disconnect your board.");
127+
}
128+
}
129+
130+
bool waitResponse() {
131+
bool confirmation = false;
132+
while (confirmation == false) {
133+
if (Serial.available()) {
134+
char choice = Serial.read();
135+
switch (choice) {
136+
case 'y':
137+
case 'Y':
138+
confirmation = true;
139+
return true;
140+
break;
141+
case 'n':
142+
case 'N':
143+
confirmation = true;
144+
return false;
145+
break;
146+
default:
147+
continue;
148+
}
149+
}
150+
}
151+
}
152+
153+
void printProgress(uint32_t offset, uint32_t size, uint32_t threshold, bool reset) {
154+
static int percent_done = 0;
155+
if (reset == true) {
156+
percent_done = 0;
157+
Serial.println("Flashed " + String(percent_done) + "%");
158+
} else {
159+
uint32_t percent_done_new = offset * 100 / size;
160+
if (percent_done_new >= percent_done + threshold) {
161+
percent_done = percent_done_new;
162+
Serial.println("Flashed " + String(percent_done) + "%");
163+
}
164+
}
165+
}
166+
167+
// the loop function runs over and over again forever
168+
void loop() {
169+
// wait 100ms
170+
delay(100);
171+
}

0 commit comments

Comments
 (0)