Skip to content

Commit 5750925

Browse files
committed
Add example to perform secure OTA update with MCUboot
1 parent d1a2533 commit 5750925

File tree

2 files changed

+177
-0
lines changed

2 files changed

+177
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#define SECRET_SSID ""
2+
#define SECRET_PASS ""
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,175 @@
1+
/*
2+
MCUboot update using WiFi
3+
This example shows how to update firmware using MCUboot and downloading the update through WiFi
4+
5+
1 - Setup your local http server with the update.bin file and configure the correct path in the sketch
6+
2 - Bootstrap this sketch on your board
7+
3 - Open the serial monitor and start the update process
8+
4 - The Sketch will pad the update file and mark the update as pending
9+
5 - Reset the board
10+
6 - MCUboot will take care of the swap and revert process
11+
*/
12+
13+
#include "BlockDevice.h"
14+
#include "MBRBlockDevice.h"
15+
#include "FATFileSystem.h"
16+
#include "arduino_secrets.h"
17+
#include <WiFi.h>
18+
19+
mbed::BlockDevice* qspi = mbed::BlockDevice::get_default_instance();
20+
mbed::MBRBlockDevice ota_data(qspi, 2);
21+
mbed::FATFileSystem ota("ota");
22+
23+
bool applyUpdate = false;
24+
bool confirmUpdate = false;
25+
26+
void setup() {
27+
Serial.begin(115200);
28+
while(!Serial);
29+
30+
if (WiFi.status() == WL_NO_SHIELD)
31+
return;
32+
33+
int status = WL_IDLE_STATUS;
34+
while (status != WL_CONNECTED)
35+
{
36+
Serial.print("Attempting to connect to SSID: ");
37+
Serial.println(SECRET_SSID);
38+
status = WiFi.begin(SECRET_SSID, SECRET_PASS);
39+
delay(3000);
40+
}
41+
Serial.println("Connected to wifi");
42+
43+
int err = ota.mount(&ota_data);
44+
if (err) {
45+
Serial.println("Please run WiFiFirmwareUpdater before");
46+
return;
47+
}
48+
49+
Serial.println("Are you ready to apply a new update? Y/[n]");
50+
applyUpdate = waitResponse();
51+
52+
if (applyUpdate) {
53+
Serial.println("Downloading update file");
54+
int err = WiFi.download("http://192.168.8.104:8080/update.bin", "/ota/update.bin", false);
55+
if (err < 0) {
56+
Serial.print("Error downloading file ");
57+
Serial.println(err);
58+
return;
59+
}
60+
61+
setUpdatePending();
62+
63+
Serial.println("Do you want to make the update permanent? Y/[n]");
64+
confirmUpdate = waitResponse();
65+
66+
if (confirmUpdate) {
67+
setImageOKFlag();
68+
}
69+
Serial.println("Done, waiting reset");
70+
} else {
71+
Serial.println("No update pending. It's now safe to reboot or disconnect your board.");
72+
}
73+
}
74+
75+
void printProgress(uint32_t offset, uint32_t size, uint32_t threshold, bool reset) {
76+
static int percent_done = 0;
77+
if (reset == true) {
78+
percent_done = 0;
79+
Serial.println("Flashed " + String(percent_done) + "%");
80+
} else {
81+
uint32_t percent_done_new = offset * 100 / size;
82+
if (percent_done_new >= percent_done + threshold) {
83+
percent_done = percent_done_new;
84+
Serial.println("Flashed " + String(percent_done) + "%");
85+
}
86+
}
87+
}
88+
89+
void setImageOKFlag() {
90+
FILE* update_file = fopen("/ota/update.bin", "rb+");
91+
const uint8_t buf[1] = { 0x01 };
92+
93+
fseek(update_file, ((15 * 128 * 1024) - 64), SEEK_SET);
94+
int ret = fwrite(buf, 1, 1, update_file);
95+
if (ret != 1) {
96+
Serial.println("Error writing Image OK flag");
97+
}
98+
fclose(update_file);
99+
}
100+
101+
void setUpdatePending() {
102+
FILE* update_file = fopen("/ota/update.bin", "rb+");
103+
104+
const uint32_t boot_img_magic[] = {
105+
0xf395c277,
106+
0x7fefd260,
107+
0x0f505235,
108+
0x8079b62c,
109+
};
110+
111+
if (update_file == nullptr) {
112+
Serial.println("Cannot open update file");
113+
return;
114+
}
115+
116+
fseek(update_file, 0, SEEK_END);
117+
int fsize = ftell(update_file);
118+
119+
Serial.print("File update.bin size ");
120+
Serial.println( fsize );
121+
122+
if (fsize < 0x1E0000) {
123+
const int update_file_size = 15 * 128 * 1024;
124+
const char buffer[128] = {0xFF};
125+
126+
Serial.println("\nPadding update file");
127+
128+
printProgress(fsize, update_file_size, 10, true);
129+
while (fsize < update_file_size) {
130+
int ret = fwrite(buffer, 1, 1, update_file);
131+
if (ret != 1) {
132+
Serial.println("Error writing update file");
133+
break;
134+
}
135+
fsize += 1;
136+
printProgress(fsize, update_file_size, 10, false);
137+
}
138+
}
139+
Serial.println("Flashed 100%");
140+
141+
fseek(update_file, ((15 * 128 * 1024) - 32), SEEK_SET);
142+
int ret = fwrite(boot_img_magic, 16, 1, update_file);
143+
if (ret != 1) {
144+
Serial.println("Error writing magic");
145+
}
146+
147+
fclose(update_file);
148+
}
149+
150+
bool waitResponse() {
151+
bool confirmation = false;
152+
while (confirmation == false) {
153+
if (Serial.available()) {
154+
char choice = Serial.read();
155+
switch (choice) {
156+
case 'y':
157+
case 'Y':
158+
confirmation = true;
159+
return true;
160+
break;
161+
case 'n':
162+
case 'N':
163+
confirmation = true;
164+
return false;
165+
break;
166+
default:
167+
continue;
168+
}
169+
}
170+
}
171+
}
172+
173+
void loop() {
174+
delay(1000);
175+
}

0 commit comments

Comments
 (0)