SDK 17.1.0: secure bootloader runtime failure when compiled with current gcc (11.2.0)

Hi, I have encountered the following problem, using SDK 17.1.0:

secure bootloader compiled with current gcc stable version (11.2.0) fails during runtime with the following error:

<info> app: Entering DFU mode.
<debug> app: Initializing transports (found: 1)
<debug> nrf_dfu_ble: Initializing BLE DFU transport
<debug> app: Failed to initialize transport 0, error 9
<error> app: Could not initalize DFU transport: 0x00000009
<error> app: Received an error: 0x00000003!

And sometimes, when trying many combinations of everything, I was getting error 7.

There's also small problem during compilation with components/libraries/bootloader/ble_dfu/nrf_dfu_ble.c file - there are warnings treated as errors, but temporary removal of

CFLAGS += -Wall -Werror

from Makefile silences this.

Earlier I noticed that whole SDK somewhat suggests gcc 9.3.0 (I had to modify components/toolchain/gcc/Makefile.posix to use my system-wide installed compiler, instead of the path hardcoded there). So, I finally tried compilation with this version of compiler. I had to install it side by side with the current compiler, compile the bootloader with it, and voila - bootloader works.

So there's certainly some problem depending on the compiler version. And that's odd, because I have dozen of various ARM projects here, using MCUs from NXP, Freescale, ST, and current compiler version works flawlessly with all of them. Even my own nRF firmware that I'm currently working on, works just fine with the fresh compiler. Bootloader is the only piece of code that's causing trouble.

Yes, I can hear you - just use that old compiler. That's acceptable as temporary solution, but not really maintainable, looking into the future.

I'm using unmodified bootloader straight from SDK examples, so I think it'd be easily reproducible.

Please have a look at the issue.

  • I too had this issue. It's caused by the inputs into SVCALL assembly definition not being fully defined and therefore the parameters never get placed on the stack. I found this solution from the link below which is adding this to CFLAGS or within SES. Of course, it should probably be fixed by correctly defining the inputs, but this is an acceptable fix in interim.  

    c_additional_options="-fno-ipa-modref"

    daniel-thompson fix

    You can also isolate the optimization options just for the SVCALL as shown below. I've chosen to apply the above fix as I'm timid of another location running into interprocedural optimization issues with gcc 11. 

    #define SVCALL(number, return_type, signature)          \
      _Pragma("GCC diagnostic push")                        \
      _Pragma("GCC diagnostic ignored \"-Wreturn-type\"")   \
      _Pragma("GCC push_options")                           \
      _Pragma("GCC optimize (\"-fno-ipa-modref\")")         \
      __attribute__((naked))                                \
      __attribute__((unused))                               \
      static return_type signature                          \
      {                                                     \
        __asm(                                              \
            "svc %0\n"                                      \
            "bx r14" : : "I" (GCC_CAST_CPP number) : "r0"   \
        );                                                  \
      }                                                     \
      _Pragma("GCC pop_options")                            \
      _Pragma("GCC diagnostic pop")

Related