Skip to content

Commit 1cb8f77

Browse files
committed
Initial: add SFU for rp2040
1 parent 87ac07c commit 1cb8f77

File tree

10 files changed

+4934
-1
lines changed

10 files changed

+4934
-1
lines changed

libraries/SFU/extra/main.cpp

+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
#include "mbed.h"
2+
#include "FlashIAPBlockDevice.h"
3+
#include "FATFileSystem.h"
4+
5+
#define SD_MOUNT_PATH "ota"
6+
#define FULL_UPDATE_FILE_PATH "/" SD_MOUNT_PATH "/" MBED_CONF_APP_UPDATE_FILE
7+
8+
#define POST_APPLICATION_ADDR 0x10000
9+
10+
#if !defined(POST_APPLICATION_ADDR)
11+
#error "target.restrict_size must be set for your target in mbed_app.json"
12+
#endif
13+
14+
//Pin order: MOSI, MISO, SCK, CS
15+
//FlashIAPBlockDevice sd(XIP_BASE + 0xF00000, 0x100000);
16+
FlashIAPBlockDevice sd(XIP_BASE + 0x100000, 0x100000);
17+
FATFileSystem fs(SD_MOUNT_PATH);
18+
FlashIAP flash;
19+
20+
void apply_update(FILE *file, uint32_t address);
21+
22+
int main()
23+
{
24+
FILE *file;
25+
sd.init();
26+
int err = fs.mount(&sd);
27+
if (err != 0) {
28+
printf("No partition found\r\n");
29+
goto boot;
30+
}
31+
32+
file = fopen(FULL_UPDATE_FILE_PATH, "rb");
33+
if (file != NULL) {
34+
printf("Firmware update found\r\n");
35+
36+
apply_update(file, XIP_BASE + POST_APPLICATION_ADDR);
37+
38+
fclose(file);
39+
remove(FULL_UPDATE_FILE_PATH);
40+
} else {
41+
printf("No update found to apply\r\n");
42+
}
43+
44+
fs.unmount();
45+
46+
boot:
47+
sd.deinit();
48+
49+
printf("Starting application\r\n");
50+
51+
mbed_start_application(XIP_BASE + POST_APPLICATION_ADDR + 0x100);
52+
}
53+
54+
void apply_update(FILE *file, uint32_t address)
55+
{
56+
fseek(file, 0, SEEK_END);
57+
// Skip the first POST_APPLICATION_ADDR bytes
58+
long len = ftell(file) - POST_APPLICATION_ADDR;
59+
printf("Firmware size is %ld bytes\r\n", len);
60+
fseek(file, POST_APPLICATION_ADDR, SEEK_SET);
61+
62+
flash.init();
63+
64+
const uint32_t page_size = flash.get_page_size();
65+
char *page_buffer = new char[page_size];
66+
uint32_t addr = address;
67+
uint32_t next_sector = addr + flash.get_sector_size(addr);
68+
bool sector_erased = false;
69+
size_t pages_flashed = 0;
70+
uint32_t percent_done = 0;
71+
while (true) {
72+
73+
// Read data for this page
74+
memset(page_buffer, 0, sizeof(char) * page_size);
75+
int size_read = fread(page_buffer, 1, page_size, file);
76+
if (size_read <= 0) {
77+
break;
78+
}
79+
80+
// Erase this page if it hasn't been erased
81+
if (!sector_erased) {
82+
flash.erase(addr, flash.get_sector_size(addr));
83+
sector_erased = true;
84+
}
85+
86+
// Program page
87+
flash.program(page_buffer, addr, page_size);
88+
89+
addr += page_size;
90+
if (addr >= next_sector) {
91+
next_sector = addr + flash.get_sector_size(addr);
92+
sector_erased = false;
93+
}
94+
95+
if (++pages_flashed % 3 == 0) {
96+
uint32_t percent_done_new = ftell(file) * 100 / len;
97+
if (percent_done != percent_done_new) {
98+
percent_done = percent_done_new;
99+
printf("Flashed %3ld%%\r", percent_done);
100+
}
101+
}
102+
}
103+
printf("Flashed 100%%\r\n");
104+
105+
delete[] page_buffer;
106+
107+
flash.deinit();
108+
}

libraries/SFU/extra/mbed-os.lib

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
https://github.com/arduino/mbed-os/#1820aade78cbc3e3231def2c3ffd0b363bf1778c

libraries/SFU/extra/mbed_app.json

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"config": {
3+
"update_file": {
4+
"help": "Path to the application update binary on the SD card",
5+
"value": "\"UPDATE.BIN\""
6+
}
7+
},
8+
"target_overrides": {
9+
"NANO_RP2040_CONNECT": {
10+
"platform.stdio-baud-rate": 115200,
11+
"target.c_lib": "small",
12+
"target.restrict_size": "0x10000"
13+
}
14+
}
15+
}

libraries/SFU/library.properties

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
name=SFU
2+
version=1.0.0
3+
author=Arduino
4+
maintainer=Arduino <[email protected]>
5+
sentence=Update the sketch on your board from a Arduino MKRMEM Shield.
6+
paragraph=Requires a Arduino MKRMEM Shield.
7+
category=Other
8+
url=https://www.arduino.cc/en/Reference/SFU
9+
architectures=mbed

libraries/SFU/src/SFU.cpp

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include "SFU.h"
2+
#include "FlashIAPBlockDevice.h"
3+
#include "FATFileSystem.h"
4+
#include "PluggableUSBMSD.h"
5+
6+
const unsigned char SFU[0x10000] __attribute__ ((section(".second_stage_ota"), used)) = {
7+
#include "rp2040.h"
8+
};
9+
10+
FlashIAPBlockDevice bd(XIP_BASE + 0x100000, 0x100000);
11+
12+
void USBMSD::begin()
13+
{
14+
int err = getFileSystem().mount(&bd);
15+
if (err) {
16+
err = getFileSystem().reformat(&bd);
17+
}
18+
}
19+
20+
mbed::FATFileSystem& USBMSD::getFileSystem()
21+
{
22+
static mbed::FATFileSystem fs("ota");
23+
return fs;
24+
}
25+
26+
USBMSD MassStorage(&bd);
27+
28+
int SFU::begin() {
29+
MassStorage.begin();
30+
}
31+
32+
int SFU::download(const char* url) {
33+
// No download at the moment, allow the user to upload a file via mass storage
34+
}
35+
36+
int SFU::apply() {
37+
// No autoreboot
38+
}

libraries/SFU/src/SFU.h

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include "WiFiNINA.h"
2+
3+
class SFU {
4+
public:
5+
static int begin();
6+
static int download(const char* url);
7+
static int apply();
8+
};

0 commit comments

Comments
 (0)