Skip to content

Commit 4fe266d

Browse files
authored
Merge pull request #513 from arduino/SFU
SFU - Second Stage Bootloader for MKR Boards with MKRMEM Shield
2 parents 4587fc5 + ee435d5 commit 4fe266d

17 files changed

+15619
-0
lines changed

libraries/SFU/examples/SFU_LoadBinary/Binary.h

Whitespace-only changes.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/**************************************************************************************
2+
* INCLUDE
3+
**************************************************************************************/
4+
5+
#include <Arduino_MKRMEM.h>
6+
7+
/**************************************************************************************
8+
* CONSTANTS
9+
**************************************************************************************/
10+
11+
static uint8_t const BINARY[] =
12+
{
13+
#include "Binary.h"
14+
};
15+
16+
/**************************************************************************************
17+
* SETUP/LOOP
18+
**************************************************************************************/
19+
20+
void setup() {
21+
Serial.begin(9600);
22+
23+
unsigned long const start = millis();
24+
for(unsigned long now = millis(); !Serial && ((now - start) < 5000); now = millis()) { };
25+
26+
flash.begin();
27+
28+
Serial.print("Mounting ... ");
29+
if(SPIFFS_OK != filesystem.mount()) {
30+
Serial.println("mount() failed with error code "); Serial.println(filesystem.err()); return;
31+
}
32+
Serial.println("OK");
33+
34+
35+
Serial.print("Checking ... ");
36+
if(SPIFFS_OK != filesystem.check()) {
37+
Serial.println("check() failed with error code "); Serial.println(filesystem.err()); return;
38+
}
39+
Serial.println("OK");
40+
41+
42+
Serial.print("Writing \"UPDATE.BIN\" ... ");
43+
File file = filesystem.open("UPDATE.BIN", CREATE | READ_WRITE| TRUNCATE);
44+
45+
int const bytes_to_write = sizeof(BINARY);
46+
int const bytes_written = file.write((void *)BINARY, bytes_to_write);
47+
48+
if(bytes_written != bytes_to_write) {
49+
Serial.println("write() failed with error code "); Serial.println(filesystem.err()); return;
50+
} else {
51+
Serial.print("OK (");
52+
Serial.print(bytes_written);
53+
Serial.println(" bytes written)");
54+
}
55+
56+
Serial.print("Unmounting ... ");
57+
filesystem.unmount();
58+
Serial.println("OK");
59+
}
60+
61+
void loop() {
62+
63+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/*
2+
Usage
3+
This example demonstrates how to use the SAMD SFU library to update a
4+
sketch on any Arduino MKR board connected to a MKRMEM Shield. This sketch
5+
prints out the date and time the sketch was compiled.
6+
7+
Steps to update sketch via MKRMEM shield:
8+
9+
1) Upload this sketch or another sketch that includes the SFU library
10+
via #include <SFU.h>
11+
12+
2) Update the sketch as desired. For this example the sketch prints out
13+
the compiled date and time so no updates are needed.
14+
15+
3) In the IDE select: Sketch -> Export compiled Binary
16+
17+
4) Open the location of the sketch and convert the .bin file to a C byte array.
18+
cat SKETCH.bin | xxd --include > Binary.h
19+
20+
5) Copy Binary.h file from the sketch's folder to the SFU_LoadBinary sketch
21+
and load it to the MKRMEM via SFU_LoadBinary sketch.
22+
*/
23+
24+
/*
25+
Include the SFU library
26+
27+
This will add some code to the sketch before setup() is called
28+
to check if UPDATE.bin is present on the flash chip of the MKRMEM
29+
shield. If this theck is positive the file is used to update the sketch
30+
running on the board. After this UPDATE.BIN is deleted from the flash.
31+
*/
32+
33+
#include <SFU.h>
34+
35+
void setup() {
36+
Serial.begin(9600);
37+
while(!Serial) { }
38+
39+
// wait a bit
40+
delay(1000);
41+
42+
String message;
43+
message += "Sketch compile date and time: ";
44+
message += __DATE__;
45+
message += " ";
46+
message += __TIME__;
47+
48+
// print out the sketch compile date and time on the serial port
49+
Serial.println(message);
50+
}
51+
52+
void loop() {
53+
// add you own code here
54+
}
+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
/*
2+
Copyright (c) 2020 Arduino LLC. All right reserved.
3+
4+
This library is free software; you can redistribute it and/or
5+
modify it under the terms of the GNU Lesser General Public
6+
License as published by the Free Software Foundation; either
7+
version 2.1 of the License, or (at your option) any later version.
8+
9+
This library is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12+
See the GNU Lesser General Public License for more details.
13+
14+
You should have received a copy of the GNU Lesser General Public
15+
License along with this library; if not, write to the Free Software
16+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17+
*/
18+
19+
/**************************************************************************************
20+
* INCLUDE
21+
**************************************************************************************/
22+
23+
#include <FlashStorage.h>
24+
#include <Arduino_MKRMEM.h>
25+
26+
/**************************************************************************************
27+
* DEFINE
28+
**************************************************************************************/
29+
30+
#define SFU_START 0x2000
31+
#define SFU_SIZE 0x8000
32+
33+
#define SKETCH_START (uint32_t*)(SFU_START + SFU_SIZE)
34+
35+
/**************************************************************************************
36+
* GLOBAL CONSTANTS
37+
**************************************************************************************/
38+
39+
static char const UPDATE_FILE_NAME[] = "UPDATE.BIN";
40+
41+
/**************************************************************************************
42+
* GLOBAL VARIABLES
43+
**************************************************************************************/
44+
45+
FlashClass mcu_flash;
46+
47+
/**************************************************************************************
48+
* FUNCTION DECLARATION
49+
**************************************************************************************/
50+
51+
extern "C" void __libc_init_array(void);
52+
53+
/**************************************************************************************
54+
* MAIN
55+
**************************************************************************************/
56+
57+
int main()
58+
{
59+
init();
60+
61+
__libc_init_array();
62+
63+
delay(1);
64+
65+
/* Initialize W25Q16DV flash chip found on Arduino MKRMEM Shield */
66+
flash.begin();
67+
68+
/* Mount and verify filesystem */
69+
if ((SPIFFS_OK == filesystem.mount()) && (SPIFFS_OK == filesystem.check()))
70+
{
71+
/* Open update file */
72+
filesystem.clearerr();
73+
File file = filesystem.open(UPDATE_FILE_NAME, READ_ONLY);
74+
if(SPIFFS_OK == filesystem.err())
75+
{
76+
bool update_success = false;
77+
/* Determine the size of the update file */
78+
int file_size = file.lseek(0, END);
79+
if (file_size > SFU_SIZE)
80+
{
81+
/* Skip the SFU section */
82+
file.lseek(SFU_SIZE, START);
83+
file_size -= SFU_SIZE;
84+
85+
/* Erase the MCU flash */
86+
uint32_t flash_address = (uint32_t)SKETCH_START;
87+
mcu_flash.erase((void*)flash_address, file_size);
88+
89+
/* Write the MCU flash */
90+
uint8_t buffer[512];
91+
for (int b = 0; b < file_size; b += sizeof(buffer))
92+
{
93+
file.read(buffer, sizeof(buffer));
94+
mcu_flash.write((void*)flash_address, buffer, sizeof(buffer));
95+
flash_address += sizeof(buffer);
96+
}
97+
update_success = true;
98+
}
99+
file.close();
100+
if (update_success) { filesystem.remove(UPDATE_FILE_NAME); }
101+
filesystem.unmount();
102+
}
103+
}
104+
105+
/* Jump to the sketch */
106+
__set_MSP(*SKETCH_START);
107+
108+
/* Reset vector table address */
109+
SCB->VTOR = ((uint32_t)(SKETCH_START) & SCB_VTOR_TBLOFF_Msk);
110+
111+
/* Address of Reset_Handler is written by the linker at the beginning of the .text section (see linker script) */
112+
uint32_t resetHandlerAddress = (uint32_t) * (SKETCH_START + 1);
113+
/* Jump to reset handler */
114+
asm("bx %0"::"r"(resetHandlerAddress));
115+
}

libraries/SFU/extras/SFUBoot/build.sh

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#!/bin/sh -x
2+
3+
ARDUINO=arduino
4+
SKETCH_NAME="SFUBoot.ino"
5+
SKETCH="$PWD/$SKETCH_NAME"
6+
BUILD_PATH="$PWD/build"
7+
OUTPUT_PATH="../../src/boot"
8+
9+
if [[ "$OSTYPE" == "darwin"* ]]; then
10+
ARDUINO="/Applications/Arduino.app/Contents/MacOS/Arduino"
11+
fi
12+
13+
buildSFUBootSketch() {
14+
BOARD=$1
15+
DESTINATION=$2
16+
17+
$ARDUINO --verify --board $BOARD --preserve-temp-files --pref build.path="$BUILD_PATH" $SKETCH
18+
cat "$BUILD_PATH/$SKETCH_NAME.bin" | xxd -include > $DESTINATION
19+
rm -rf "$BUILD_PATH"
20+
}
21+
22+
mkdir -p "$OUTPUT_PATH"
23+
24+
buildSFUBootSketch "arduino:samd:mkrzero" "$OUTPUT_PATH/mkrzero.h"
25+
buildSFUBootSketch "arduino:samd:mkr1000" "$OUTPUT_PATH/mkr1000.h"
26+
buildSFUBootSketch "arduino:samd:mkrwifi1010" "$OUTPUT_PATH/mkrwifi1010.h"
27+
buildSFUBootSketch "arduino:samd:mkrgsm1400" "$OUTPUT_PATH/mkrgsm1400.h"
28+
buildSFUBootSketch "arduino:samd:mkrnb1500" "$OUTPUT_PATH/mkrnb1500.h"
29+
buildSFUBootSketch "arduino:samd:mkrvidor4000" "$OUTPUT_PATH/mkrvidor4000.h"
30+
buildSFUBootSketch "arduino:samd:mkrwan1310" "$OUTPUT_PATH/mkrwan1310.h"
31+
buildSFUBootSketch "arduino:samd:mkrfox1200" "$OUTPUT_PATH/mkrfox1200.h"

libraries/SFU/keywords.txt

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#######################################
2+
# Syntax Coloring Map For SDU
3+
#######################################
4+
5+
#######################################
6+
# Datatypes (KEYWORD1)
7+
#######################################
8+
9+
SFU KEYWORD1
10+
11+
#######################################
12+
# Methods and Functions (KEYWORD2)
13+
#######################################
14+
15+
#######################################
16+
# Constants (LITERAL1)
17+
#######################################

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=samd

libraries/SFU/src/SFU.cpp

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
Copyright (c) 2020 Arduino LLC. All right reserved.
3+
4+
This library is free software; you can redistribute it and/or
5+
modify it under the terms of the GNU Lesser General Public
6+
License as published by the Free Software Foundation; either
7+
version 2.1 of the License, or (at your option) any later version.
8+
9+
This library is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12+
See the GNU Lesser General Public License for more details.
13+
14+
You should have received a copy of the GNU Lesser General Public
15+
License along with this library; if not, write to the Free Software
16+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17+
*/
18+
19+
#include <Arduino.h>
20+
21+
#include "SFU.h"
22+
23+
__attribute__ ((section(".sketch_boot")))
24+
unsigned char SFU_BOOT[0x8000] = {
25+
#if defined(ARDUINO_SAMD_MKRZERO)
26+
#include "boot/mkrzero.h"
27+
#elif defined(ARDUINO_SAMD_MKR1000)
28+
#include "boot/mkr1000.h"
29+
#elif defined(ARDUINO_SAMD_MKRWIFI1010)
30+
#include "boot/mkrwifi1010.h"
31+
#elif defined(ARDUINO_SAMD_MKRGSM1400)
32+
#include "boot/mkrgsm1400.h"
33+
#elif defined(ARDUINO_SAMD_MKRNB1500)
34+
#include "boot/mkrnb1500.h"
35+
#elif defined(ARDUINO_SAMD_MKRVIDOR4000)
36+
#include "boot/mkrvidor4000.h"
37+
#elif defined(ARDUINO_SAMD_MKRWAN1310)
38+
#include "boot/mkrwan1310.h"
39+
#elif defined(ARDUINO_SAMD_MKRFOX1200)
40+
#include "boot/mkrfox1200.h"
41+
#else
42+
#error "Unsupported board!"
43+
#endif
44+
};

libraries/SFU/src/SFU.h

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
Copyright (c) 2020 Arduino LLC. All right reserved.
3+
4+
This library is free software; you can redistribute it and/or
5+
modify it under the terms of the GNU Lesser General Public
6+
License as published by the Free Software Foundation; either
7+
version 2.1 of the License, or (at your option) any later version.
8+
9+
This library is distributed in the hope that it will be useful,
10+
but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12+
See the GNU Lesser General Public License for more details.
13+
14+
You should have received a copy of the GNU Lesser General Public
15+
License along with this library; if not, write to the Free Software
16+
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17+
*/
18+
19+
#ifndef _SFU_H_INCLUDED
20+
#define _SFU_H_INCLUDED
21+
22+
/* Nothing to do */
23+
24+
#endif /* _SFU_H_INCLUDED */

0 commit comments

Comments
 (0)