1

I am trying to perform a firmware update from an SD card, on a Sodaq Sara AFF board. If i use the SDU.h library in my sketch, it fails the board check. See this link please.

I have edited the SDU.cpp myself to force the selection of ARDUINO_SAM_ZERO. It is now :

__attribute__ ((section(".sketch_boot")))
unsigned char sduBoot[0x6000] = {
  #include "boot/mzero.h"
};

I have increased the size to 6000 otherwise it was complaining too many initializers.

I also have changed the SD_SS_PIN to match my pin on the SDUboot.ino, under extras. Afterwards, i recompiled it with build.sh in the same folder.

But I am unable to perform the firmware update. After power cycling the board (original code: the blink example, target update: blink with a faster rate) - the original firmware remains.

I exported the firmware using arduino IDE -> export compiled bynary, and tested both versions with and without bootloader.

Any help would be appreciated.

6
  • 3
    what bootloader has the board? the difference between MKR/Zero and M0 is for SDU the bootloader size which is 2kB for MKR and Zero and 4 kB for M0. why do you want to use SDU? is your sketch larger then half of the flash?
    – Juraj
    Commented Jan 26, 2021 at 6:41
  • @Juraj the board has a ATSAMD21J18, 32-Bit ARM Cortex M0+. So, I assume 4 kB bootloader size. Is it relevant if the sketch is larger then half of the flash?
    – phlegx
    Commented Mar 30, 2021 at 12:25
  • Zero and M0 are both SAMD21 but have different bootloaders. the sketch binary doesn't have to be smaller then half of the flash if it is loaded from SD card
    – Juraj
    Commented Mar 30, 2021 at 13:03
  • github.com/arduino/ArduinoCore-samd/pull/344/commits
    – Juraj
    Commented Apr 2, 2021 at 6:24
  • And what does it mean finally? What is the correct setup to get it work?
    – phlegx
    Commented Apr 7, 2021 at 0:04

1 Answer 1

1

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.

1
  • Hi, I was away due to things changing in Cororna times, but now I'm back. This does not work. It compiles, but I am unable to load the new firmware without bootloader.
    – Sean
    Commented Jul 24, 2021 at 16:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.