Skip to content

SNU/SFU - Second stage bootloader for WiFi and Serial flash based OTA #469

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 12 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions boards.txt
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ mkrwifi1010.build.vid=0x2341
mkrwifi1010.build.pid=0x8054
mkrwifi1010.bootloader.tool=openocd
mkrwifi1010.bootloader.file=mkrwifi1010/samd21_sam_ba_arduino_mkrwifi1010.bin
mkrwifi1010.arduinoota.extraflags=-d

# Arduino MKR FOX 1200
# --------------------
Expand Down
62 changes: 62 additions & 0 deletions libraries/SFU/examples/Usage/Usage.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
Usage
This example demonstrates how to use the SAMD SFU library to update a
sketch on an Arduino/Genuino Zero, MKRZero or MKR1000 board using an
SPI Flash memory chip. It prints out the date and time the sketch was compiled at
to both Serial and Serial1.

Circuit:
* Arduino MKR board with MKR MEM Shield (https://store.arduino.cc/arduino-mkr-mem-shield)

Steps to update sketch via SerialFlash:

1) Upload this sketch or another sketch that includes the SFU library
via #include <SFU.h>

2) Update the sketch as desired. For this example the sketch prints out
the compiled date and time so no updates are needed.

3) In the IDE select: Sketch -> Export compiled Binary

4) Write the .bin file to the flash chip in the way you prefer (eg. using https://github.com/PaulStoffregen/SerialFlash/blob/master/examples/CopyFromSerial/CopyFromSerial.ino). The filename MUST be "UPDATE.bin".

5) Reboot the board; the new binary will be automatically flashed to the board.

created 12 March 2018
by Martino Facchin
*/

/*
Include the SFU library

This will add some code to the sketch before setup() is called
to check if a serial flash is present and UPDATE.bin exists on it.

If UPDATE.bin is present, the file is used to update the sketch
running on the board. After this UPDATE.bin is deleted from flash.
*/
#include <SFU.h>

String message;

void setup() {
Serial.begin(9600);
Serial1.begin(9600);

// wait a bit
delay(1000);

message += "Sketch compile date and time: ";
message += __DATE__;
message += " ";
message += __TIME__;

// print out the sketch compile date and time on the serial port
Serial.println(message);
Serial1.println(message);
}

void loop() {
// add you own code here
}

92 changes: 92 additions & 0 deletions libraries/SFU/extras/FlashBoot/FlashBoot.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
/*
Copyright (c) 2017 Arduino LLC. All right reserved.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include <SerialFlash.h>
#include <FlashStorage.h>

#define SDU_START 0x2000
#define SDU_SIZE 0x4000

#define SKETCH_START (uint32_t*)(SDU_START + SDU_SIZE)

#ifndef SERIALFLASH_CS_PIN
#define SERIALFLASH_CS_PIN 5
#endif

#define UPDATE_FILE "UPDATE.BIN"

FlashClass flash;

// Initialize C library
extern "C" void __libc_init_array(void);

int main() {
init();

__libc_init_array();

delay(1);

if (SerialFlash.begin(SERIALFLASH_CS_PIN) && SerialFlash.exists(UPDATE_FILE)) {
SerialFlashFile updateFile = SerialFlash.open(UPDATE_FILE);
uint32_t updateSize = updateFile.size();
bool updateFlashed = false;

if (updateSize > SDU_SIZE) {
// skip the SDU section
updateFile.seek(SDU_SIZE);
updateSize -= SDU_SIZE;

uint32_t flashAddress = (uint32_t)SKETCH_START;

// erase the pages
flash.erase((void*)flashAddress, updateSize);

uint8_t buffer[512];

// write the pages
for (uint32_t i = 0; i < updateSize; i += sizeof(buffer)) {
updateFile.read(buffer, sizeof(buffer));

flash.write((void*)flashAddress, buffer, sizeof(buffer));

flashAddress += sizeof(buffer);
}

updateFlashed = true;
}

updateFile.close();

if (updateFlashed) {
SerialFlash.remove(UPDATE_FILE);
}
}

// jump to the sketch
__set_MSP(*SKETCH_START);

//Reset vector table address
SCB->VTOR = ((uint32_t)(SKETCH_START) & SCB_VTOR_TBLOFF_Msk);

// address of Reset_Handler is written by the linker at the beginning of the .text section (see linker script)
uint32_t resetHandlerAddress = (uint32_t) * (SKETCH_START + 1);
// jump to reset handler
asm("bx %0"::"r"(resetHandlerAddress));
}

32 changes: 32 additions & 0 deletions libraries/SFU/extras/FlashBoot/build.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/bin/sh -x

ARDUINO=arduino
SKETCH_NAME="FlashBoot.ino"
SKETCH="$PWD/$SKETCH_NAME"
BUILD_PATH="$PWD/build"
OUTPUT_PATH="../../src/boot"

if [[ "$OSTYPE" == "darwin"* ]]; then
ARDUINO="/Applications/Arduino.app/Contents/MacOS/Arduino"
fi

buildSDUBootSketch() {
BOARD=$1
DESTINATION=$2

$ARDUINO --verify --board $BOARD --preserve-temp-files --pref build.path="$BUILD_PATH" $SKETCH
cat "$BUILD_PATH/$SKETCH_NAME.bin" | xxd -i > $DESTINATION
rm -rf "$BUILD_PATH"
}

mkdir -p "$OUTPUT_PATH"

buildSDUBootSketch "arduino:samd:arduino_zero_edbg" "$OUTPUT_PATH/zero.h"
buildSDUBootSketch "arduino:samd:mkr1000" "$OUTPUT_PATH/mkr1000.h"
buildSDUBootSketch "arduino:samd:mkrzero" "$OUTPUT_PATH/mkrzero.h"
buildSDUBootSketch "arduino:samd:mkrfox1200" "$OUTPUT_PATH/mkrfox1200.h"
buildSDUBootSketch "arduino:samd:mkrgsm1400" "$OUTPUT_PATH/mkrgsm1400.h"
buildSDUBootSketch "arduino:samd:mkrwan1300" "$OUTPUT_PATH/mkrwan1300.h"
buildSDUBootSketch "arduino:samd:mkrnb1500" "$OUTPUT_PATH/mkrnb1500.h"
buildSDUBootSketch "arduino:samd:mkrwifi1010" "$OUTPUT_PATH/mkrwifi1010.h"
buildSDUBootSketch "arduino:samd:mkrvidor" "$OUTPUT_PATH/mkrvidor4000.h"
17 changes: 17 additions & 0 deletions libraries/SFU/keywords.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#######################################
# Syntax Coloring Map For SFU
#######################################

#######################################
# Datatypes (KEYWORD1)
#######################################

SFU KEYWORD1

#######################################
# Methods and Functions (KEYWORD2)
#######################################

#######################################
# Constants (LITERAL1)
#######################################
9 changes: 9 additions & 0 deletions libraries/SFU/library.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
name=SFU
version=1.0.0
author=Arduino
maintainer=Arduino <[email protected]>
sentence=Update the sketch on your board by loading from a compiled binary from a external serial flash.
paragraph=Requires an external serial flash supported by the SerialFlash library ( https://github.com/PaulStoffregen/SerialFlash ).
category=Other
url=http://www.arduino.cc/en/Reference/SFU
architectures=samd
46 changes: 46 additions & 0 deletions libraries/SFU/src/SFU.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
Copyright (c) 2017 Arduino LLC. All right reserved.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include <Arduino.h>

#include "SFU.h"

__attribute__ ((section(".sketch_boot")))
unsigned char sduBoot[0x4000] = {
#if defined(ARDUINO_SAMD_ZERO)
#include "boot/zero.h"
#elif defined(ARDUINO_SAMD_MKR1000)
#include "boot/mkr1000.h"
#elif defined(ARDUINO_SAMD_MKRZERO)
#include "boot/mkrzero.h"
#elif defined(ARDUINO_SAMD_MKRFox1200)
#include "boot/mkrfox1200.h"
#elif defined(ARDUINO_SAMD_MKRGSM1400)
#include "boot/mkrgsm1400.h"
#elif defined(ARDUINO_SAMD_MKRWAN1300)
#include "boot/mkrwan1300.h"
#elif defined(ARDUINO_SAMD_MKRNB1500)
#include "boot/mkrnb1500.h"
#elif defined(ARDUINO_SAMD_MKRWIFI1010)
#include "boot/mkrwifi1010.h"
#elif defined(ARDUINO_SAMD_MKRVIDOR4000)
#include "boot/mkrvidor4000.h"
#else
#error "Unsupported board!"
#endif
};
24 changes: 24 additions & 0 deletions libraries/SFU/src/SFU.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
Copyright (c) 2017 Arduino LLC. All right reserved.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#ifndef _SFU_H_INCLUDED
#define _SFU_H_INCLUDED

// nothing for now

#endif
Loading