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

How to run app directly after burning bootloader?

Hi, 

I am using NRF52832 and SDK 11

I tried to include DFU function into the device. I merged bootloader (from modified bootloader example), application, softdevice into one HEX file, and use nRFgo Studio to burn the HEX into the device. But after powered on, the device always immediately advertising as "DfuTarg" instead of running the main application. If I use nRFConnect App to connect this "DfuTarg", then I can use OTA to update the application to the device, then it will run the main application with DFU perfectly.

Why is that? Did I miss something?

Thanks

  • My full bootloader code here:

    #define IS_SRVC_CHANGED_CHARACT_PRESENT 1 

    #define BOOTLOADER_BUTTON BSP_BUTTON_3
    #define UPDATE_IN_PROGRESS_LED BSP_LED_2

    #define APP_TIMER_PRESCALER 0 
    #define APP_TIMER_OP_QUEUE_SIZE 4

    #define SCHED_MAX_EVENT_DATA_SIZE MAX(APP_TIMER_SCHED_EVT_SIZE, 0) 

    #define SCHED_QUEUE_SIZE 20 


    void assert_nrf_callback(uint16_t line_num, const uint8_t * p_file_name)
    {
    app_error_handler(0xDEADBEEF, line_num, p_file_name);
    }


    static void leds_init(void)
    {
    nrf_gpio_range_cfg_output(LED_START, LED_STOP);
    nrf_gpio_pins_set(LEDS_MASK);
    }



    static void timers_init(void)
    {
    APP_TIMER_APPSH_INIT(APP_TIMER_PRESCALER, APP_TIMER_OP_QUEUE_SIZE, true);
    }


    static void buttons_init(void)
    {
    nrf_gpio_cfg_sense_input(BOOTLOADER_BUTTON,
    BUTTON_PULL,
    NRF_GPIO_PIN_SENSE_LOW);

    }


    static void sys_evt_dispatch(uint32_t event)
    {
    pstorage_sys_event_handler(event);
    }



    static void ble_stack_init(bool init_softdevice)
    {
    uint32_t err_code;
    sd_mbr_command_t com = {SD_MBR_COMMAND_INIT_SD, };
    nrf_clock_lf_cfg_t clock_lf_cfg = NRF_CLOCK_LFCLKSRC;

    if (init_softdevice)
    {
    err_code = sd_mbr_command(&com);
    APP_ERROR_CHECK(err_code);
    }

    err_code = sd_softdevice_vector_table_base_set(BOOTLOADER_REGION_START);
    APP_ERROR_CHECK(err_code);

    SOFTDEVICE_HANDLER_APPSH_INIT(&clock_lf_cfg, true);


    ble_enable_params_t ble_enable_params;

    err_code = softdevice_enable_get_default_config(1, 1, &ble_enable_params);
    APP_ERROR_CHECK(err_code);

    ble_enable_params.gatts_enable_params.service_changed = IS_SRVC_CHANGED_CHARACT_PRESENT;
    err_code = softdevice_enable(&ble_enable_params);
    APP_ERROR_CHECK(err_code);

    err_code = softdevice_sys_evt_handler_set(sys_evt_dispatch);
    APP_ERROR_CHECK(err_code);
    }


    static void scheduler_init(void)
    {
    APP_SCHED_INIT(SCHED_MAX_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE);
    }


    int main(void)
    {
    uint32_t err_code;
    bool dfu_start = false;
    bool app_reset = (NRF_POWER->GPREGRET == BOOTLOADER_DFU_START);

    if (app_reset)
    {
    NRF_POWER->GPREGRET = 0;
    }

    leds_init();


    APP_ERROR_CHECK_BOOL(*((uint32_t *)NRF_UICR_BOOT_START_ADDRESS) == BOOTLOADER_REGION_START);
    APP_ERROR_CHECK_BOOL(NRF_FICR->CODEPAGESIZE == CODE_PAGE_SIZE);


    timers_init();
    buttons_init();

    (void)bootloader_init();

    if (bootloader_dfu_sd_in_progress())
    {
    nrf_gpio_pin_clear(UPDATE_IN_PROGRESS_LED);

    err_code = bootloader_dfu_sd_update_continue();
    APP_ERROR_CHECK(err_code);

    ble_stack_init(!app_reset);
    scheduler_init();

    err_code = bootloader_dfu_sd_update_finalize();
    APP_ERROR_CHECK(err_code);

    nrf_gpio_pin_set(UPDATE_IN_PROGRESS_LED);
    }
    else
    {

    ble_stack_init(!app_reset);
    scheduler_init();
    }

    dfu_start = app_reset;




    if (dfu_start || (!bootloader_app_is_valid(DFU_BANK_0_REGION_START)))
    {
    nrf_gpio_pin_clear(UPDATE_IN_PROGRESS_LED);


    err_code = bootloader_dfu_start();
    APP_ERROR_CHECK(err_code);

    nrf_gpio_pin_set(UPDATE_IN_PROGRESS_LED);
    }

    if (bootloader_app_is_valid(DFU_BANK_0_REGION_START) && !bootloader_dfu_sd_in_progress())
    {

    bootloader_app_start(DFU_BANK_0_REGION_START);
    }

    NVIC_SystemReset();
    }

  • Does it have something to do with the bootloader code here:    dfu_start  = app_reset;   ?

    Sorry I am not very familiar with the bootloader code.

  • I tried to get rid of the dfu_start  = app_reset; part and test furtuer.

    I found that the problem seemed to be caused by function bootloader_app_is_valid(DFU_BANK_0_REGION_START) returns false.

    And anyone knows how to fix this?

  • Hi,

    On startup, the bootloader will check if there is a valid app in bank 0 (memory layout) by checking the value of p_bootloader_settings->bank_0 stored in the bootloader settings page @ 0x3FC00. It will only boot the app if the bank code == BANK_VALID_APP (0x01). 

    The settings page is managed by the bootloader when you do DFU and it will set the bank0 code to BANK_VALID_APP after a successful application update. However, it will not be set if you program sd+bl+app with a debugger so the bootloader will not know that a valid application is present in bank 0. But you can mark the application as valid by setting the flag manually valid with nrfjprog after you've programmed everything : 

    > nrfjprog --memwr 0x3FC00 --val 1 (BANK_VALID_APP)

    > nrfjprog -r // Reset device - app should start on subsequent boot

    Also, since you are using SDK 11 with nRF52, it's important that you use a more recent version of system_nrf52.c that includes workaround for errata #108. This file is distributed with our MDK

     

  • Hi Vidar,

    Thanks for your reply. 

    But both "nrfjprog --memwr 0x3FC00 --val 1" and "nrfjprog -r" return ERROR: There is no debugger connected to the PC with the given serial number.

    However, if I use "nrfjprog -f NRF52 --program "C:\myfile.hex" --verify --chiperase" command to program the chip, then it won't ask about serial number and can sucessfully download the file to the chip.

Related