[SOLVED] OTA Flash appears to work but new code NOT loaded. Huh?


Howdy Y’all.

Been on hiatus for a few months. Did I miss much? :stuck_out_tongue:

So, here’s a weird one …

I have two BluzDK’s. Today I flashed a user app (using OTA) to one of them (named Bluz1) and it worked just fine. I go to do the same thing for Bluz2, which also appears to work fine …

… and here on my bench, the main LED did the usual stuff, just exactly as expected.

However, the new app has NOT been loaded. Instead, Bluz2 reboots and connects, still running the code that was on it prior to OTA flashing.

There was a lengthy WTF session leading up to the present state of affairs. Namely, if I compile Blinky locally and flash that (using (bluzDK/release-1.1.47) it all works fine. But then the OTA weirdness as above takes place.

Oh and I also tried this both using my (questionably outdated firmware) Gateway Shield and using my iPhone and Bluz app. Same both ways, It’s only the OTA flash that is doing this weirdness and only on one of my 'DKs.

Any clues?

Thanks in advance!


Hmmm. I wonder if there’s some internal lock bits that prevent application code from programming Flash? Can’t imagine how, but maybe such a thing has been inadvertently enabled by all my prior messing about with JTAG etc?

EDIT: Yup. There are such protection bits …

9.1.5 NVM protection blocks

The protection mechanism for NVM can be used to prevent erroneous application code from erasing or writing to protected blocks. Non-volatile memory can be protected from erases/writes depending on settings in the PROTENSET registers. One bit in a PROTENSET register represents one protected block. There are two PROTENSET registers of 32 bits which means there are 64 protectable blocks in total.

Note: If an erase or write to a protected block is detected, the CPU will hard fault. If an ERASEALL operation is attempted from the CPU while any block is protected it will be blocked and the CPU will hard fault.

On reset, all the protection bits are cleared. To ensure safe operation, the first task after reset must be to set the protection bits. The only way of clearing protection bits is by resetting the device from any reset source.

The protection mechanism is turned off when in debug mode (a debugger is connected) and the DISABLEINDEBUG register is set to disable.

So that pretty much eliminates that possible cause.

Incidentally, a full Flash erase was tried …

Erasing device (nRF51822_xxAA)...
Comparing flash   [100%] Done.
Erasing flash     [100%] Done.
Verifying flash   [100%] Done.
J-Link: Flash download: Total time needed: 5.505s (Prepare: 0.083s, Compare: 0.000s, Erase: 5.408s, Program: 0.000s, Verify: 0.000s, Restore: 0.013s)

… but to no avail. Same problem remains, after re-flash locally (as in OP) and then OTA attempt.


Welcome back! Things have been a little crazy, we are about to release a bi

When you did the OTA, did the RGB LED turn solid blue after the last magenta blink? If that was blue, then it should have copied the app to flash.

One other thing to check, did you change the module addresses in your local build? If you had changed the addresses in flash at any point then a new upload could fail since it would be downloading to the wring place. This could still show the blue RGB LED i mentioned above, but the code just wouldn’t ever get loaded.


Nice to be back … though I wish had more time to be so. Thanks. :wink:

There is indeed no blue flash, after the slow magenta pulses. Hmmm.

The firmware is unaltered bluzDK-firmware v1.1.47. Here’s the top few lines from git log in the directory I built from …

commit def41fc6541576bfac80a363048a5145f865d9e2
Merge: 5397b34 5bc2034
Author: Eric Ely eely22@users.noreply.github.com
Date: Thu Apr 7 18:01:02 2016 -0400

Merge pull request #13 from bluzDK/develop
timer for OTA updates, reset if it hangs

I built and programmed this exact same version into my Bluz1 device. It works fine. Then I did Bluz2 – without so much as recompiling – and it just doesn’t. I’m quite flummoxed over it. Here;s a log of the build process …

Figured I’d make a detailed log for you, so you can see with your own eyes. Here we go then …

gruvin:bluzDK-firmware$ show (echo $APP etc)
gruvin:bluzDK-firmware$ make clean
Building firmware for Bluz Production, platform ID: 103, product ID: 103
rm -f -r build/target


gruvin:bluzDK-firmware$ cd bootloader/
gruvin:bootloader$ make
/Applications/Xcode.app/Contents/Developer/usr/bin/make -C ../platform
arm-none-eabi-objcopy -O ihex ../build/target/bootloader/platform-103-lto/bootloader.elf ../build/target/bootloader/platform-103-lto/bootloader.hex
arm-none-eabi-size --format=berkeley ../build/target/bootloader/platform-103-lto/bootloader.elf
   text	   data	    bss	    dec	    hex	filename
  13512	    108	   2628	  16248	   3f78	../build/target/bootloader/platform-103-lto/bootloader.elf


gruvin:bootloader$ cd ../modules/
gruvin:modules$ make

/Applications/Xcode.app/Contents/Developer/usr/bin/make -C /Users/gruvin/projects/Bluz/bluzDK-firmware/modules/bluz/system-part1/
arm-none-eabi-size --format=berkeley ../../../build/target/user-part/platform-103-m/tinker.elf
   text	   data	    bss	    dec	    hex	filename
   5784	    476	    416	   6676	   1a14	../../../build/target/user-part/platform-103-m/tinker.elf
arm-none-eabi-objdump -h -S ../../../build/target/user-part/platform-103-m/tinker.elf > ../../../build/target/user-part/platform-103-m/tinker.lst

Now we Flash Bluz2, using a script I wrote, thusly …

gruvin:modules$ cat `which flash-bluz`
if [ "$APP" == "" ]; then
  echo "WARNING: APP not set. Defaulting to tinker.hex"

# power on first
echo -en "power on\nq" | JLinkExe -Device NRF51822_XXAA -If SWD -Speed 6000 > /dev/null

# now flash
adalink $* nrf51822 -p jlink \
  -h ${SOFTDEVICE}                                        \
  -h ${TGT}/bootloader/platform-103-lto/bootloader.hex    \
  -h ${TGT}/system-part1/platform-103-m/system-part1.hex  \
  -h ${TGT}/user-part/platform-103-m/${APP}.hex
gruvin:modules$ flash-bluz

That was uneventful …

To remove a possible variable from the equation, I’ll use the iPhone Gateway app to try and get Bluz2 connected …

So here we are, all looking good. Time for an OTA of this …

const int LED = D7;

void setup() {
    pinMode(LED, OUTPUT);

void loop() {
    digitalWrite(LED, HIGH);
    digitalWrite(LED, LOW);

The gifaricated video isn’t entirely clear. There is definitely no blue flash before going back to green and the Particle IDE app definitely didn’t get copied to Flash.

Directly after this, I performed all of the above steps, starting from flash-bluz (no re-builds) and including the final Particle IDE Flash. On Bluz 1, it all works – including the single blue LED blink before resetting.

Both Bluz2 and Bluz1 re-connect to the cloud (slow cyan) after all of the above.

EDIT: Forgot to include these two screen snippets, from the Particle IDE …

So there it is. :-/

Could it be something to do with the claiming / secure keys or something? I don’t know all the ins and outs of that. But it sure seems unlikely.

Thanks again and oh, there’s really no rush at all. Nothing of any significance is being held up here. I’ve got plenty of other stuff to be getting on with. :wink:



I have a theory. I think this may have to do with the UICR register not being updated on the device, so the bootloader isn’t running. This can happen when flashing with an STLink v2, if you wipe the device the UICR register will get reset.

If you try to do a Factory Reset, is the bootloader even working on that device?

If you can’t get to bootloader update mode or perform a factory reset, then the UICR register is definitely the issue. What you need to do is modify this file: https://github.com/bluzDK/bluzDK-firmware/blob/develop/build/arm/linker/bootloader_nrf51.ld

You need to add code in the lines between:


  /* No init RAM section in bootloader. Used for bond information exchange. */

So it should look like this:

  /* Ensures the Bootloader start address in flash is written to UICR when flashing the image. */
  .uicrBootStartAddress :

  /* No init RAM section in bootloader. Used for bond information exchange. */

Add that code, rebuild the bootloader, then flash all 4 firmware binaries and try again. I think that will fix your issue.


Me again.

Well, I like the theory, … but unfortunately …

$ make clean
$ cd bootloader/
$ make
/Applications/Xcode.app/Contents/Developer/usr/bin/make -C ../platform
Building file: MCU/NRF51/NRF51_StdPeriph_Driver/src/app_error.c
Invoking: ARM GCC C Compiler
mkdir -p ../build/target/platform/platform-103-lto/./MCU/NRF51/NRF51_StdPeriph_Driver/src/
...-lc -lnosys  -L../build/target/platform/platform-103-lto/ -L../build/target/services/platform-103-lto/ -L../build/arm/linker -Wl,--whole-archive -lplatform -lservices -Wl,--no-whole-archive -T../build/arm/linker/bootloader_nrf51.ld -T../build/arm/linker/bootloader_nrf51_common.ld -Wl,-Map,../build/target/bootloader/platform-103-lto/bootloader.map

Invoking: ARM GNU Create Flash Image
arm-none-eabi-objcopy -O binary ../build/target/bootloader/platform-103-lto/bootloader.elf ../build/target/bootloader/platform-103-lto/bootloader.bin.pre_crc
if [ -s ../build/target/bootloader/platform-103-lto/bootloader.bin.pre_crc ]; then \
	head -c $((`stat -f%z ../build/target/bootloader/platform-103-lto/bootloader.bin.pre_crc` - 38)) ../build/target/bootloader/platform-103-lto/bootloader.bin.pre_crc > ../build/target/bootloader/platform-103-lto/bootloader.bin.no_crc && \
	tail -c 38 ../build/target/bootloader/platform-103-lto/bootloader.bin.pre_crc > ../build/target/bootloader/platform-103-lto/bootloader.bin.crc_block && \
	test "0102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f20280078563412" = `xxd -p -c 500 ../build/target/bootloader/platform-103-lto/bootloader.bin.crc_block` && \
	shasum -a 256 ../build/target/bootloader/platform-103-lto/bootloader.bin.no_crc | cut -c 1-65 | xxd -r -p | dd bs=1 of=../build/target/bootloader/platform-103-lto/bootloader.bin.pre_crc seek=$((`stat -f%z ../build/target/bootloader/platform-103-lto/bootloader.bin.pre_crc` - 38)) conv=notrunc  && \
	head -c $((`stat -f%z ../build/target/bootloader/platform-103-lto/bootloader.bin.pre_crc` - 4)) ../build/target/bootloader/platform-103-lto/bootloader.bin.pre_crc > ../build/target/bootloader/platform-103-lto/bootloader.bin.no_crc && \
	 crc32 ../build/target/bootloader/platform-103-lto/bootloader.bin.no_crc | cut -c 1-10 | xxd -r -p | dd bs=1 of=../build/target/bootloader/platform-103-lto/bootloader.bin.pre_crc seek=$((`stat -f%z ../build/target/bootloader/platform-103-lto/bootloader.bin.pre_crc` - 4)) conv=notrunc ;\
make: *** [../build/target/bootloader/platform-103-lto/bootloader.bin] Error 1

I can’t even see an error report in there.

… scratch RAM contents removed …

Tired. Sleepzzzz


insert coffee … read another page …

Oh! hehe

OK. So, on Bluz1 (working one) …

J-Link>mem32 0x10001014 1
10001014 = 0003C000

And on Bluz2 …

J-Link>mem32 0x10001014 1
10001014 = FFFFFFFF

So, I think we can safely say that your theory is confirmed.

What gives with the linker script, I wonder?

Here’s a copy of mine, just to show I didn’t screw it up (did I?) …

PATH: bluzDK-firmware/build/arm/linker/bootloader_nrf51.ld

/* Linker script to configure memory regions. */

GROUP(-lgcc -lc -lnosys)

  /** Flash start address for the bootloader. This setting will also be stored in UICR to allow the
   *  MBR to init the bootloader when starting the system. This value must correspond to 
   *  BOOTLOADER_REGION_START found in dfu_types.h. The system is prevented from starting up if 
   *  those values do not match. The check is performed in main.c, see
  APP_FLASH (rx) : ORIGIN = 0x3C000, LENGTH = 0x3C00

  /** RAM Region for bootloader. This setting is suitable when used with s110, s120, s130, s310. */
  RAM (rwx) :  ORIGIN = 0x20002C00, LENGTH = 0x5380

  /** Location of non initialized RAM. Non initialized RAM is used for exchanging bond information
   *  from application to bootloader when using buttonluss DFU OTA. 
  NOINIT (rwx) :  ORIGIN = 0x20007F80, LENGTH = 0x80

  /** Location of bootloader setting in at the last flash page. */
  BOOTLOADER_SETTINGS (rw) : ORIGIN = 0x0003FC00, LENGTH = 0x0400

  /** Location in UICR where bootloader start address is stored. */
  UICR_BOOTLOADER (r) : ORIGIN = 0x10001014, LENGTH = 0x04

  /* Ensures the bootloader settings are placed at the last flash page. */
  .bootloaderSettings(NOLOAD) :

  /* Ensures the Bootloader start address in flash is written to UICR when flashing the image. */
  .uicrBootStartAddress :

  /* No init RAM section in bootloader. Used for bond information exchange. */
  .noinit(NOLOAD) :

  } > NOINIT
  /* other placements follow here... */

INCLUDE "bootloader_nrf51_common.ld"


Well I got Bluz2 working. I manually copied the entire UCIR area from Bluz1 to Bluz2, using savefile/loadfile in JLinkExe.

Yay \o/

Interestingly, after doing that and re-flashing everything, including tinker, the blue light flash occurred and the previous OTA program from way back got overwritten over tinker. I thought that was kinda cute. :slight_smile: Makes sense too, of course.

Would still like to figure out what went wrong with the linker script, though.

This build environment is beyond doubt the most complex I’ve ever encountered. Quite the work of art, it seems.

There’s another version of the same linker script, it seems, at bootloader/src/bluz/dfu_gcc_nrf51.ld. This one already has the addition you asked me to add and doesn’t seem to cause any trouble. Maybe it’s not even used. Like I said, complex build system.

OK, now I really need to go sleep. :wink:

As always, no rush.


That looks fine. Does the bootloader build if you remove just the UICR lines you added?



I’m in better shape now, having finally slept and I have a bit of spare time today. So, I do a little more digging. It’s high past time I learned about linker scripts anyway. Never really needed to mess with them before. So go the laments of the self-taught. :wink:


OK, so GNU linker scripts seem pretty straightforward. From that, I figured the folliwng should work …

  /* Ensures the Bootloader start address in flash is written to UICR when flashing the image. */
  .uicrBootStartAddress :


… and it does, in as much as the build completes without error. Note that the line containing, KEEP(*(.uicrBootStartAddress)) has been removed. I haven’t yet been able to determine what that line is supposed to do. It certainly seems redundant to me, in any case.

Then again … I better test my theory. Using J-Link to erase just 0x0x10001014, then flash a fresh build, then check 0x10001014's contents, I see …

Crap! Another damn problem. Now I cannot write to 0x10001014 at all, “Verification error”. I even did a complete chip erase, only to find that 0x10001014 had not been touched. This is weird. No doubt it’s Flash write protection kicking in, somehow. But this was never a problem before.

EDIT: I now know what the KEEP line is supposed to do and why it is important in this case – specifically, because the address 0x10001014 is surely not referenced anywhere else and so would otherwise be dropped from the final .hex output.

So now, I have no idea why it causes an error when it is included. It should be fine.

I have to get on with other stuff now. At least I finally learned linker script usage. Handy stuff.

Have a great afternoon and a better evening – or else! :stuck_out_tongue:


Hi @eric @gruvin, I am also having the same issue. OTA flash appears to work but nothing is happening. I put the above code in bootloader_nrf51.ld but OTA flash is not working.

Please tell me the issue :slight_smile:


Can you provide more details about the device? What have you changed on it? Did you flash any custom bootloader to it?

What version of firmware are you using?

When the OTA update is finished, does the device stay solid blue for a few seconds before it reboots?


Thank you for your reply @eric!
Firstly I have flashed the firmware(version=1.1.47) using STLINK then after that, When I am flashing another code on that bluz using PARTICLE web IDE then initially it gets magenta and did flashing successful but nothing changes i.e. previous code is running only.
then I write .uicrBootStartAddress :
but I am getting error in building bootloader then I remove KEEP(
(.uicrBootStartAddress)) then there is no error.but nothing is changing means still not able to flash using particle web IDE.


You must have those lines in your bootloader, that is almost certainly the issue.

What is the error you see when you compile with those lines?


When I am compiling with the above lines, I am getting following error:

Building target: ../build/target/bootloader/platform-103-lto/bootloader.elf
Invoking: ARM GCC C++ Linker
mkdir -p ../build/target/bootloader/platform-103-lto/
arm-none-eabi-g++ -DSTM32_DEVICE -DNRF51 -DPLATFORM_THREADING=0 -DPLATFORM_ID=103 -DPLATFORM_NAME=bluz -DUSBD_VID_SPARK=0x1D50 -DUSBD_PID_DFU=0x607F -DUSBD_PID_CDC=0x607D -g3 -Os -mcpu=cortex-m0 -mthumb -mfloat-abi=soft -mabi=aapcs -DSOFTDEVICE_PRESENT -DBLE_STACK_SUPPORT_REQUIRED -DNRF51 -DNRF51822_QFAA_CA -DBLE_STACK_SUPPORT_REQD -DUSE_CUSTOM_STATIC_ASSERT -DBLUZ -flto -DUSE_STDPERIPH_DRIVER -DDFU_BUILD_ENABLE -DSYSTEM_VERSION_STRING=2.0.50 -DRELEASE_BUILD -Werror -I./src/bluz -I./src/bluz/config -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/libraries -I../platform/shared/inc -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/device -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/drivers_nrf/common -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/drivers_nrf/config -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/drivers_nrf/gpiote -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/drivers_nrf/hal -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/drivers_nrf/ppi -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/drivers_nrf/simple_uart -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/drivers_nrf/spi_master -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/drivers_nrf/spi_slave -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/drivers_nrf/ble_flash -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/drivers_nrf/pstorage -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/drivers_nrf/pstorage/config -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/drivers_nrf/timer -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/drivers_nrf/twi_master -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/drivers_nrf/uart -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/drivers_nrf/wdt -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/softdevice/common/softdevice_handler -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/ble/common -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/ble/ble_db_discovery -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/ble/device_manager -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/ble/ble_radio_notification -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/ble/device_manager/config -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/ble/ble_error_log -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/ble/ble_debug_assert_handler -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/libraries/bootloader_dfu -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/libraries/crc16 -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/libraries/timer -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/libraries/pwm -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/libraries/scheduler -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/libraries/gpiote -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/libraries/fifo -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/libraries/button -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/libraries/trace -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/libraries/util -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/libraries/timer -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/toolchain -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/toolchain/gcc -I../platform/MCU/NRF51/NRF51_StdPeriph_Driver/inc/softdevice/s110/headers -I../platform/MCU/NRF51/SPARK_Firmware_Driver/inc -I../hal/inc -I../hal/shared -I../hal/src/bluz -I../hal/src/nrf51 -I../services/inc -I../dynalib/inc -I. -MD -MP -MF ../build/target/bootloader/platform-103-lto/bootloader.elf.d -ffunction-sections -fdata-sections -Wall -Wno-switch -Wno-error=deprecated-declarations -fmessage-length=0 -fno-strict-aliasing -DSPARK=1 -DPARTICLE=1 -DSTART_DFU_FLASHER_SERIAL_SPEED=14400 -DSTART_YMODEM_FLASHER_SERIAL_SPEED=28800 -DUSE_STDPERIPH_DRIVER -DBOOTLOADER_VERSION=7 -DMODULE_VERSION=7 -DMODULE_FUNCTION=2 -DMODULE_DEPENDENCY=0,0,0 ../build/target/bootloader/platform-103-lto/./src/bluz/main.o ../build/target/bootloader/platform-103-lto/./src/module_info.o  ../build/target/bootloader/platform-103-lto/startup/startup_NRF51.o --output ../build/target/bootloader/platform-103-lto/bootloader.elf -Xlinker --gc-sections -lc -lnosys -flto -Os -fuse-linker-plugin --specs=nano.specs -lc -lnosys  -L../build/target/platform/platform-103-lto/ -L../build/target/services/platform-103-lto/ -L../build/arm/linker -Wl,--whole-archive -lplatform -lservices -Wl,--no-whole-archive -T../build/arm/linker/bootloader_nrf51.ld -T../build/arm/linker/bootloader_nrf51_common.ld -Wl,-Map,../build/target/bootloader/platform-103-lto/bootloader.map
/usr/lib/gcc/arm-none-eabi/4.9.3/../../../arm-none-eabi/bin/ld:../build/arm/linker/bootloader_nrf51.ld:40: syntax error
collect2: error: ld returned 1 exit status
../build/module.mk:186: recipe for target '../build/target/bootloader/platform-103-lto/bootloader.elf' failed
make: *** [../build/target/bootloader/platform-103-lto/bootloader.elf] Error 1

What to do now ??


This seems to be reported above as well, not sure why it isn’t compiling. Only thing I can think of is that it require gcc 4.8, but that is just a theory. I wI’ll take a look as soon as I can and report back


This is my gcc version:

amitt@Amitt-System:~/bluzDK-firmware/modules$ gcc --version
gcc (Ubuntu 4.8.5-4ubuntu2) 4.8.5
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO


I don’t think this is the problem.

I am also looking over it, please let me know if you find any solutions asap.

Thanks :slight_smile:


This is the same issue I still have, though I haven’t gotten back to it since my posts above.

@Amitt – in the meantime, you can probably fix the problem manually, as I did. But first I would ned to know exactly which programmer/flashing device and software you are using, please? What I mean is, what hardware brand/make/model and software (and which OS platform) are you using to do local flashing?

Once I know that, I should be able to guide you through manually resetting that register.



@gruvin and @Amitt: Ok, it is all coming back to me now!

TLDR: You don’t need to compile the bootloader locally. Download the bootloader.hex file from here and flash this to your device EVERY time you flash locally with an STLink. https://github.com/bluzDK/bluzDK-firmware/releases/tag/v2.0.50-beta.5

The issue has to do with where the UICR register is on the nrf51822. It is at address 0x10001014, and the flash starts at address 0x0000. Binary files are just 100% representations of each bit, there is no concept of address. So when we keep the section at address 0x10001014, the binary file generator actually creates a binary file that stretches from 0x000 to that address. That creates a 268MB file!

There are some things that the Particle makefile does to the binary file, such as adding CRC checks, that blow up when dealing with such a large file. That is why you are getting an error.

Normally this isn’t a big deal, the UICR register only needs to get updated once when the flash chip is programmed at the factory. But since the STLink erases it each time, it blows it away and you need to reprogram it.

The way I did it was to bypass the Particle CRC checks, which is ok in this instance, and then to build the HEX file manually. HEX files are different then binary, they specify addresses, so it doesn’t have to make a 256MB file. It only has to write the address and what to write to, so it is much smaller.

So, VERY long story short, there are extra steps needed to compile the bootloader with the UICR programmer properly, but you really don’t need to worry about it. So, you can download the bootloader.hex file from the latest release and use that.