Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs
This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

GPIOTE and secure bootloader

I am using nRF52832 on my custom board. The SoftDevice, secure bootloader and my custom BLE application are flashed on my flash.

After processing a single GPIOTE event, my firmware gets stuck in GPIOTE_IRQHandler.

It all worked fine when I was testing my application without the bootloader, but when I installed the bootloader and ran the application, my firmware gets stuck at seemingly random locations within GPIOTE_IRQHandler.   When I flash the app without bootloader, just with a SoftDevice, everything is fine.

I'm using:

- nRF5 SDK v17.0.2

- SoftDevice S132 v7.2.0

Is there some additional re-initialization necessary after booting through the bootloader ?

As suggested on https://devzone.nordicsemi.com/f/nordic-q-a/38380/gpiote-bootloader_secure-softdevice, I tried modifying the bootloader to call nrf_dfu_transports_close(NULL) before invoking nrf_bootloader_app_start() from nrf_bootloader.c, but this didn't help.

Best regards,

Ivo

  • Hello, 

    What bootloader are you using? pca10040_s132_ble or pca10040_uart?

    What does it look like when you are stuck in the GPIOTE_IRQHandler()? Is there some while loop that you are not getting out of? Perhaps you can show me a screenshot?

    A wild guess:

    About the only gpiote related changes I can think of in the bootloaders are:

    BLE and uart: DFU enter button,

    uart: UART pins.

    Try the following. First, only for testing purposes, and we can look into the solution if any of them seems to be the cause:

    DFU enter button: In the sdk_config.h file of your bootloader, locate NRF_BL_DFU_ENTER_METHOD_BUTTON and set it to 0. (If you are struggling to enter the application without being able to upload it via DFU, let me know, but there is something called bootloader settings that you can generate using the nrfutil command "nrfutil settings generate --help" which you can program together with your application to make the bootloader accept the application).

    UART pins: 

    As far as I can tell, the UART pins are already being disconnected through the uart_dfu_transport_close() function. Is the NRF_DRV_UART_USE_UARTE set to true in your project? (in nrf_drv_uart.h)? Which of the functions, nrfx_uarte_uninit() or nrfx_uart_uninit() are called?

    Try to power cycle the DK after you have updated the application via DFU. Then, the transport should not be initialized, and we can check whether it is the UART pins that trigger your application's GPIOTE_IRQHandler() or not.

    Best regards,

    Edvin

  • Hi Edvin,

    When the lock-up happens, when reading registers with nrfjprog, I get the same "PC:" value within nrfx_gpiote_irq_handler, on successive runs of "nrfjprog", but a different "PC:" value after resetting the board and triggering the lock-up.

    When debugging with Segger Ozone, it's stuck in nrfx_gpiote.c::nrfx_gpiote_irq_handler, in port_event_handle(input), the debugger can step through the code, but never steps out.

    Note that when trying to resume the firmware from Ozone, I get a HardFault error.

    Setting NRF_BL_DFU_ENTER_METHOD_BUTTON to 0 seemed to have made the issue go away: now I no longer get stuck in GPIOTE IRQ handler, with or without bootloader.

    Best regards,

    Ivo.

  • It looks like the button that is set up in the bootloader is not handled in the application's gpiote handler. In case you want to use the button to enter bootloader, I suggest just doing a cleanup of that pin before you start the application. You can use the same function that is used in the uart bootloader's transport_close() function:

    nrf_gpio_cfg_default(NRF_BL_DFU_ENTER_METHOD_BUTTON_PIN);

    before the application is started.

    Actually, you can probably do it right after it is read in dfu_enter_check:

    ret_code_t nrf_bootloader_init(nrf_dfu_observer_t observer)
    {
        NRF_LOG_DEBUG("In nrf_bootloader_init");
    
        ret_code_t                            ret_val;
        nrf_bootloader_fw_activation_result_t activation_result;
        uint32_t                              initial_timeout;
        bool                                  dfu_enter = false;
    
        m_user_observer = observer;
    
        if (NRF_BL_DEBUG_PORT_DISABLE)
        {
            nrf_bootloader_debug_port_disable();
        }
    
    #if NRF_BL_DFU_ENTER_METHOD_BUTTON
        dfu_enter_button_init();
    #endif
    
        ret_val = nrf_dfu_settings_init(false);
        if (ret_val != NRF_SUCCESS)
        {
            return NRF_ERROR_INTERNAL;
        }
    
        #if NRF_BL_DFU_ALLOW_UPDATE_FROM_APP
        // Postvalidate if DFU has signaled that update is ready.
        if (s_dfu_settings.bank_current == NRF_DFU_CURRENT_BANK_1)
        {
            postvalidate();
        }
        #endif
    
        // Check if an update needs to be activated and activate it.
        activation_result = nrf_bootloader_fw_activate();
    
        switch (activation_result)
        {
            case ACTIVATION_NONE:
                initial_timeout = NRF_BOOTLOADER_MS_TO_TICKS(NRF_BL_DFU_INACTIVITY_TIMEOUT_MS);
                dfu_enter       = dfu_enter_check();    // The NRF_BL_DFU_ENTER_METHOD_BUTTON_PIN is read inside dfu_enter_check().
                break;
    
            case ACTIVATION_SUCCESS_EXPECT_ADDITIONAL_UPDATE:
                initial_timeout = NRF_BOOTLOADER_MS_TO_TICKS(NRF_BL_DFU_CONTINUATION_TIMEOUT_MS);
                dfu_enter       = true;
                break;
    
            case ACTIVATION_SUCCESS:
                bootloader_reset(true);
                NRF_LOG_ERROR("Unreachable");
                return NRF_ERROR_INTERNAL; // Should not reach this.
    
            case ACTIVATION_ERROR:
            default:
                return NRF_ERROR_INTERNAL;
        }
        
    #if NRF_BL_DFU_ENTER_METHOD_BUTTON
        nrf_gpio_cfg_default(NRF_BL_DFU_ENTER_METHOD_BUTTON_PIN);
    #endif
    
    ...

    BR,

    Edvin

Related