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

nRF51822 over the air bootloader with gcc

For my current project, I need to compile the »over the air bootloader« with gcc (because our buildserver runs on linux, developers using Mac … no Windows and no Keil so far).

But unfortunaly, the bootloader example from the sdk (5.1) examples won't compile with gcc. It's missing gcc makefile and even there are at least 2 Keil specific files in the project (arm_startup_nrf51.s and bootloader_util_arm.c).

Could you provide support to help me on this topic?

I'd also checked:- devzone.nordicsemi.com/index.php/nrf51822-bootloader-with-gcc

  • About codesize:

    • Your CFLAGS+=-Os is ignored because the Sdk Makefile.common sets CFLAGS+=-O0 for debug target and CFLAGS+=-O3 for release target. You could either patch that away from the Sdk Makefile.common or hack it using INCLUDEPATHS+=-Os (see the gcc/Makefile in my attached BleblGcc-V2.zip above).
    • Your -ffunction-sections etc. is counterproductive if you have no unused functions. In this case -ffunction-sections will blow your binary size a bit up.
    • Which gcc version are you using? I tried gcc 4.7.4 and 4.8.3 and investigeted a slightly smaller codesize when using 4.8.3.
    • I worked the above solution (accepted answer) by using Sdk 5.1.0 and the bootloader matches to 15k (+1k flash for persistent data).

    About linkerscript: Your "FLASH (rx) : ORIGIN = 0x0003C000, LENGTH = 0x4000" is wrong. You have to reserve the last page (1k) for the bootloader's persistent data. So you have to configure e.g. "FLASH (rx) : ORIGIN = 0x0003C000, LENGTH = 0x3C00" instead, what gives you 15k for your bin file (code & const data).

    About bin versus hex: Unfortunately, the JLinkExe won't accept hex files and nrfjprog is not available for Linux (and maybe also not for Mac, isn't it?). That's why I have to use bin files for Jtag flashing.

  • Hi Joe, thanks for your answer.

    Yes, I have noticed that the Makefile.common was discarding the -Os flag, so I slightly modified it and now I'm able to compile with the -Os flag set.

    Regarding the linker script, I don't think it's wrong, it depends on how you define the MEMORY blocks and the sections in the other file. If you put the .bootloader_settings section inside the FLASH memory block, I think it should work too. In other words, I think that you can define the FLASH with ORIGIN = 0x3C000 and LENGTH = 0x4000 as a memory block and then in the other file define the bootloader_settings section as: .bootloader_settings 0x3FC00 : { KEEP(*(.bootloader_settings)) } > FLASH but you should put it in the right place in the script.

    Regarding the .bin file format, the only small workaround I've found is the rknrfgo software (on SourceForge), that runs on OSX and seems to be able to program the nRF51822 using hex files, but I still haven't tried it yet.

    Thanks for all your considerations and suggestions!

  • I am trying to build using 4.8-2014-q1-update gcc toolchain from launchpad on OSX

    I am using same settings that Nikita mentions above but my linker seems to be putting the UICR and bootloader settings in the data section.

    
    SEARCH_DIR(.)
    GROUP(-lgcc -lc -lnosys)
    
    MEMORY
    {
      FLASH (rx) : ORIGIN = 0x0003B800, LENGTH = 0x4400
      bootloader_settings (rwx) : ORIGIN = 0x0003FC00, LENGTH = 0x400
      NRF_UICR_BOOT_START (rwx) : ORIGIN = 0x10001014, LENGTH = 0x4
      RAM (rwx) :  ORIGIN = 0x20002000, LENGTH = 0x2000
    }
    
    
    INCLUDE "gcc_nrf51_common.ld"
    
    
    
    ENTRY(Reset_Handler)
    
    SECTIONS
    {
        .bootloader_settings_block 0x0003FC00 :
        {
            KEEP(*(.bootloader_settings_sect))
        } > bootloader_settings
    
        .NRF_UICR_BOOT_START_BLOCK 0x10001014 :
        {
            KEEP(*(.NRF_UICR_BOOT_START_SECT))
        } > NRF_UICR_BOOT_START
    
        .text : ALIGN(4)
    	{
    ....
    
    
    
    uint8_t __attribute__((section (".bootloader_settings_sect"))) m_boot_settings[CODE_PAGE_SIZE] __attribute__((used));
    uint32_t __attribute__((section (".NRF_UICR_BOOT_START_SECT"))) m_uicr_bootloader_start_address = BOOTLOADER_REGION_START;
    
    void StartApplication(uint32_t start_addr)
    {
        __asm__ volatile (
        "LDR   R2, [R0]\n\t"                //Get App MSP.
        "MSR   MSP, R2\n\t"                 //Set the main stack pointer to the applications MSP.
        "LDR   R3, [R0, #0x00000004]\n\t"   //Get application reset vector address.
        "BX    R3\n\t"                      //No return - stack code is now activated only through SVC and plain interrupts.
        ".ALIGN"
                    );
    }
    
    
    

    but here's what my bootloader.map shows

    
    o
                    0x000000002000244c                . = ALIGN (0x4)
                    0x000000002000244c                __data_end__ = .
    
    .igot.plt       0x000000002000244c        0x0 load address 0x000000000003ff7c
     .igot.plt      0x0000000000000000        0x0 /Users/huckym/software/arm-launchpad-tools-v4.8-2014-q1/bin/../lib/gcc/arm-none-eabi/4.8.3/armv6-m/crtbegin.o
    
    .bootloader_settings_sect
                    0x000000002000244c      0x400 load address 0x000000000003ff7c
     .bootloader_settings_sect
                    0x000000002000244c      0x400 obj/bootloader_util_arm.o
                    0x000000002000244c                m_boot_settings
    
    .NRF_UICR_BOOT_START_SECT
                    0x000000002000284c        0x4 load address 0x000000000004037c
     .NRF_UICR_BOOT_START_SECT
                    0x000000002000284c        0x4 obj/bootloader_util_arm.o
                    0x000000002000284c                m_uicr_bootloader_start_address
    
    .bss            0x0000000020002850      0x800 load address 0x0000000000040380
                    0x0000000020002850                . = ALIGN (0x4)
                    0x0000000020002850                __bss_start__ = .
     *(.bss*)
    
    

    Makefile.zip

    project.zip

  • With what eclipse settings or makefile you compiled this code? Upload your eclipse project so I can check it.

Related