This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts
This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

bootloader_app_start vs NVIC_SystemReset();

Hi, i want to jump from my app to the bootloader, i used the function

void bootloader_app_start(void)

{

    vMBt_eStopAdv_Exe() ;// Stoping the BLE ADV 
    sd_power_gpregret_clr(POWER_GPREGRET_GPREGRET_Msk); 
sd_power_gpregret_set(BOOTLOADER_DFU_START); 
sd_softdevice_disable(); 
interrupts_disable(); 
sd_softdevice_vector_table_base_set(NRF_UICR->BOOTLOADERADDR); 
bootloader_util_app_start(NRF_UICR->BOOTLOADERADDR);

}

and it's OK , but when i use NVIC_SystemReset(); instead of bootloader_util_app_start it dosen't work and the bootloader dosen't start. although i added in the script of the bootloader to enter the bootloader program if GPREGRET=BOOTLOADERADDR or GPREGRET=0x00 ( case of a reset is handled )

this the modfication in the bootloader code :

if (dfu_start || (!bootloader_app_is_valid(DFU_BANK_0_REGION_START)) ||NRF_POWER->GPREGRET == 0x00)... this the condition part to enter dfu_mode , i just added the case where GPREGRET=0x00

Remarks:

1- the initialisation of the softdevice is always done in the case of a reset because we have :

-static bool dfu_start = false;

  • bool app_reset = (NRF_POWER->GPREGRET == BOOTLOADER_DFU_START);

  • ble_stack_init(!app_reset );

2- no button check is included , i commented that part as follow

//dfu_start |= ((nrf_gpio_pin_read(BOOTLOADER_BUTTON_PIN) == 0) ? true: false);

Questions :

  1. Why it dosen't work with the nvic reset ?
  2. can you explain to me the process of jump ..i have a small idea about assembly code but i don't know what are the registers used there when jumping...(thread mode .. )
  3. If i want to use Nvic_Reset() what should i do ? ( i don't care about the bonding service !! )
  4. This function ( __asm static void bootloader_util_reset(uint32_t start_addr) , used for the jump) is really confusing me !! in fact it's invoking a parameter that it never uses ..any explanation please
  • Hi Toto,

    Could you provide the SDK version you are using ? You most likely got the issue because of the check inside ble_stack_init() if the softdevice need to be re-init or not. If you jump using bootloader_app_start() the stack doesn't need to be re-init, if you jump using softreset you should reinit the stack.

  • Hi Hung Bui,

    frankly i don't know which SDK used, because i downloaded the project from GitHub ... I remember that i faced some problems, the BLE for example didn't work from the biginning, so i read the s130_nrf51822_0.9.0-1.releasenotes and i added the function sd_ble_enable() to enable the BLE... Any way to know the SKD i'm using from the files it contains ? i have been working on this project for many days, and i tested many app i don't really remember, what i did.. i remember that the bootloader project i downloaded missed some files, so i took two folders ( Source and Include ) from a folder called nrf51822 ( i think this is the SDK you are talking about ) ...I'm sorry for my unprecise replies, this is my first project using nordic.

    I want to ask concenrning the BLE re-init : are you talking about this function ?

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

    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_INIT(NRF_CLOCK_LFCLKSRC_XTAL_20_PPM, true);
    
    // Enable BLE stack 
    ble_enable_params_t ble_enable_params;
    memset(&ble_enable_params, 0, sizeof(ble_enable_params));
    ble_enable_params.gatts_enable_params.service_changed = IS_SRVC_CHANGED_CHARACT_PRESENT;
    err_code = sd_ble_enable(&ble_enable_params);
    APP_ERROR_CHECK(err_code);
    
    err_code = softdevice_sys_evt_handler_set(sys_evt_dispatch);
    APP_ERROR_CHECK(err_code);
    

    }

    And the check inside the ble_stack_init() is only about re-initializing the softdevice or not ...so i tested with this way ble_stack_init(!app_reset ||NRF_POWER->GPREGRET ==0) and i have the same issue. i didn't understand your point of view about reinit the stack ? what part of the code in the function ble_stack_init() ?

    Something important i forgot to say : the hard reset is working very well, when the bootloader or the app is running if i click reset button the chip jump to bootloader...

  • Hi ToTo,

    It should work with what you did here: ble_stack_init(!app_reset ||NRF_POWER->GPREGRET ==0) assuming you have NRF_POWER->GPREGRET ==0 when you do softreset. I suggest you to setup the bootloader in debug mode (as described at question F in this FAQ)

    And step into the bootloader when you are doing soft reset to see what could be wrong here. Make sure err_code = sd_mbr_command(&com); is called in the bootloader after you do a softreset.

    This is because when you jump directly from application to bootloader, the vector table is already forwarded to the softdevice so we don't have to do it again. If you get to bootloader by soft reset, we have to call the mbr api to forward the vector table to the softdevice (SD_MBR_COMMAND_INIT_SD) .

  • Hi Hung Bui Ok, good news, i did what you want me to do but with a different way. in fact i cancaled the check as fellow :

    //if (init_softdevice)

    //{
    
        err_code = sd_mbr_command(&com);
    
        APP_ERROR_CHECK(err_code);
    

    // }

    so here i'm sure that err_code = sd_mbr_command(&com) is called. I did a soft reset from the app and it's working very well. The hard reset is working well also ( if it's generated while the bootloader or the app is running the chip jumps to the bootloader program ).

    As i understand here, that the problem as you have said, is because err_code = sd_mbr_command(&com) was not really called .. So logically the only reason that when i added ble_stack_init(!app_reset ||NRF_POWER->GPREGRET ==0) it didn't work is that NRF_POWER->GPREGRET !=0 and app_reset =false (means NRF_POWER->GPREGRET == BOOTLOADER_DFU_START ) !! so how it works that after a soft reset the GPREGRET register dosen't change to 0x00 ? is that logic ?

    I want to know something else please, what's the difference between the soft and hard reset ( or chip reset ) ?

  • Hi Toto,

    I could have suggested you to remove the if statement, but then we wouldn't know why it wouldn't work at the first place with your modification.

    The main difference between hard reset and softreset is the retention registers will keep the value when you do soft reset. In this case it's GPREGRET register. Have you made sure you don't set GPREGRET to something else before you do softreset ?

    Simply set the bootloader in debug mode and step in to the code can tell why it didn't work earlier.

Related