This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

bootloader issues using gcc

Hi

I have been using the DFU for quite a while. I adapted the boot loader to my hardware and compiled it using Keil. All my other code is written in another environment using gcc, so I wanted to be able to do the boot loader in that same environment.

I managed to get the boot loader compiled and working, however, still got 2 issues:

  • apparently, even with the maximum optimization, the size is really at then limit, so I cannot add extra things apparently - is there a way to overcome this?
  • a bigger issue for me is that, when using the bootloader compiled with gcc, I cannot start my program after programming boot loader, soft device and application hex files using a JlinkExe script, I need to program the application using the DFU; with the Keil version that was not necessary;

After reading through the forum, it seems that in the gcc version, no valid flag is written tot he BOOTLOADER_SETTINGS flash space. I tried to fix that by including a write of the good value at this position, as suggested here but apparently that flash location was already written to 0, so cannot write to it anymore, that location or page should be erased first.

Can anyone help me solve this issue?

Is there a way of erasing and re-writing a single byte in flash using JlinkExe? And is this 1 byte the only thing checked at startup of the bootloader, or are there some other integrity checks? Or is the only way editing the boot loader hex file? How does the Keil project do this, make sure the application valid flag is already set in the hex file?

For information: I am using SDK7.2.0 on custom hardware, and I am doing all my development on Mac OSX.

dfu_gcc_nrf51.ld Makefile

Parents
  • Hi wim,

    How did you modify the bootloader for compiling with gcc ?

    1 . If you want to increase the size of the bootloader you can follow this guide.

    2 . Please clarify this part:

    I cannot start my program after programming boot loader, soft device and application hex files using a JlinkExe script, I need to program the application using the DFU; with the Keil version that was not necessary;

    With the original bootloader in the SDK, doesn't matter which toolchain you used to compile and program, the bootloader will still mark the application as invalid until you use DFU to update the bootloader.

    You can have a look at question E in this FAQ to know how to manually change the bootloader setting to tell the bootloader the valid application is flashed.

    Please double check to find why "that flash location was already written to 0", this should not happen, it should be 0xFF = BANK_INVALID_APP.

    My suggestion is to use the bootloader from SDK v8.1 or later, gcc is fully supported from that version.

    nrf51422_xxac.hex

Reply
  • Hi wim,

    How did you modify the bootloader for compiling with gcc ?

    1 . If you want to increase the size of the bootloader you can follow this guide.

    2 . Please clarify this part:

    I cannot start my program after programming boot loader, soft device and application hex files using a JlinkExe script, I need to program the application using the DFU; with the Keil version that was not necessary;

    With the original bootloader in the SDK, doesn't matter which toolchain you used to compile and program, the bootloader will still mark the application as invalid until you use DFU to update the bootloader.

    You can have a look at question E in this FAQ to know how to manually change the bootloader setting to tell the bootloader the valid application is flashed.

    Please double check to find why "that flash location was already written to 0", this should not happen, it should be 0xFF = BANK_INVALID_APP.

    My suggestion is to use the bootloader from SDK v8.1 or later, gcc is fully supported from that version.

    nrf51422_xxac.hex

Children
  • Hi Hung,

    Well for some reason, in my Keil project, this bit seems to be set during compilation: I see 0x01 on position 0x3FC00. But in my gcc project, I do not see it. I vaguely remember changing something in the past to the Keil project, but cannot really recall what exactly.

    Why I am using the SDK7.2.0 version, is because I do not want to move my application to the SDK8.1. And it seems to work now, except for this 1 bit. I did the edit manually and that works just fine.

    Please double check to find why "that flash location was already written to 0", this should not happen, it should be 0xFF = BANK_INVALID_APP.

    Where should I check this? Is this some initialization value somewhere?

  • @Wim: by default we will not write anything to this. And it will be 0xFF by default. You can have a look at the bootloader_settings.c. It's where we write to UICR and use attribute so that we can choose to write to some address in the flash in compile time.

    If you don't want to switch to SDK v8.1, you still can follow what we do in the bootloader (especially the file bootloader_settings.c) to support gcc in SDK v8.1 and use that in your bootloader. They are pretty similar.

    Usually the bootloader setting will be stored using bootloader_settings_save(), you may want to add a breakpoint there or print out a trace.

  • Triggered about your remark about the BANK_INVALID_APP, found my edit in the Keil project : I added something to this line in bootloader_settings_arm.c: const uint8_t m_boot_settings[CODE_PAGE_SIZE] attribute((at(BOOTLOADER_SETTINGS_ADDRESS))) attribute((used)) = {BANK_VALID_APP};

    Not sure how to do this in the GCC equivalent. In my GCC project, I have following line in bootloader_settings.c: attribute ((section(".bootloaderSettings"))) uint8_t m_boot_settings[CODE_PAGE_SIZE];

    What will cause a default of 0x01?

  • @wim: Please follow the bootloader_settings.c file in SDK v8.1

    if you want to pre-set a value in flash, I think you can try:

    uint8_t m_boot_settings[CODE_PAGE_SIZE] attribute ((section(".bootloaderSettings"))) = {BANK_VALID_APP};

  • tried that but that did not seem to change anything. (I guess because it is not declared as a constant?) I am now comparing some things between my code and the SDK8.1 I noticed that in my linker script, there is a difference in the definition of .Bootloadersettings.

    in version 7.2 I have:

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

    In version 8.1 this is:

         /* Ensures the bootloader settings are placed at the last flash page. */
      .bootloaderSettings :
      {
    	
      } > BOOTLOADER_SETTINGS
    

    I am not familiar with the syntax of a gcc link script. What does the "(NOLOAD)" do? Tried to remove it but then I get an error during linking:

    section .bootloaderSettings loaded at [000000000003fc00,000000000003ffff] overlaps section .data loaded at [000000000003fbe8,000000000003fc4f]
    

    Also, in my hex file, there seems to be data in the BOOTLOADER settings flash page, here is an extract from the hex file:

    :10FBE800FFFF00000500000000000000000000000A
    :10FBF80000000000000000000000000000000000FD
    :10FC08000000000000000000D8FB03000000000016
    :10FC180000000000000000000000000000000000DC
    :10FC280000000000000000000000000000000000CC
    :10FC380000000000000000000000000000000000BC
    

    Where does that data come from?

Related