SOLVED!
I have compiled my own SDUBoot.ino with fixed SDU_START 0x2000
and for SODAQ Sara (boot/sodaq_sara.h
). My sketch with #include "SDU.h"
compiles successfully. The board package is also installed in Arduino (http://downloads.sodaq.net/package_sodaq_samd_index.json). Here my code with changes (base is SodaqCore-samd-1.8.6-sodaq from Github):
File libraries/SDU/extras/SDUBoot/SDUBoot.ino
:
#include <SD.h>
#include <FlashStorage.h>
#define SDU_START 0x2000
#define SDU_SIZE 0x4000
#define SKETCH_START (uint32_t*)(SDU_START + SDU_SIZE)
#ifndef SDCARD_SS_PIN
#define SDCARD_SS_PIN 10
#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 (SD.begin(SDCARD_SS_PIN) && SD.exists(UPDATE_FILE)) {
File updateFile = SD.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) {
SD.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));
}
File libraries/SDU/extras/SDUBoot/build.sh
:
#!/bin/sh -x
ARDUINO=arduino
SKETCH_NAME="SDUBoot.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 "SODAQ:samd:sodaq_sara" "$OUTPUT_PATH/sodaq_sara.h"
File libraries/SDU/src/SDU.cpp
:
#include <Arduino.h>
#include "SDU.h"
__attribute__ ((section(".sketch_boot")))
unsigned char sduBoot[0x4000] = {
#include "boot/sodaq_sara.h"
};
Sketch file sdu_test.ino
:
#include <Arduino.h>
#include "SDU.h"
#if defined(ARDUINO_SODAQ_SARA)
#define DEBUG_STREAM SerialUSB
#else
#error "Please select the SODAQ SARA as your board"
#endif
#define DEBUG_STREAM_BAUD 115200
String message;
void setup() {
// Start communication.
DEBUG_STREAM.begin(DEBUG_STREAM_BAUD);
while (!DEBUG_STREAM) {
// Wait for Serial Monitor to be opened.
}
message += "Sketch compile date and time: ";
message += __DATE__;
message += " ";
message += __TIME__;
// print out the sketch compile date and time on the serial port
DEBUG_STREAM.println(message);
}
void loop() {
// add you own code here
}
File arduino/50/.arduino15/packages/SODAQ/hardware/samd/1.8.6/variants/sodaq_sara/linker_scripts/gcc/flash_with_bootloader.ld
add these lines:
KEEP(*(.sketch_boot))
. = ALIGN(0x2000);
here:
...
SECTIONS
{
PROVIDE(__sodaq_firmware_state = ORIGIN(FLASH) - 0x100);
.text :
{
__text_start__ = .;
KEEP(*(.sketch_boot))
. = ALIGN(0x2000);
KEEP(*(.isr_vector))
...
On SD card (formatted as FAT32) I have stored the renamed file UPDATE.bin
without bootloader of the compiled sketch file. Pin D10 is connected and used as chip select CS.
Build boot hex files:
$ cd libraries/SDU/extras/SDUBoot
$ ./build.sh
Version 1.8.6-sodaq has these missing lines on arduino_zero variant but not on sodaq_sara variant.