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

freertos with wdt reset problem, nrfjprog

Hello

my setup is a nrf52840, the sdk15.3, Softdevice s140.

I'm running an application with freertos and wdt and have the openbootloader and s140 also flashed.

- if in freertos the wdt is disabled and i set the GPREGRET register and make a reset with NVIC_SystemReset, i have to make a reset from outside by nrfjprog -r over jlink and then the dfu device comes up...

- and after update the device over dfu it has to be reset by nrfjprog -r and it resetarts in application as wanted

- If the wdt is enabled and do the same, set the GPREGRET register and make a reset with NVIC_SystemReset, the device restarts in application....

How can i make a reset or restart similar to nrfjprog -r from software so that no jlink is needed ?

Thanks in advance

twittich

Parents
  • Hello Twittich,

    The WD timer is not reset through a NVIC_SystemReset (Reset behavior) so it will keep running on subsequent startup when the program enters DFU mode inside the bootloader.  The bootloader feeds the WD by default for this reason. But you may need to adjust the reload interval if you have a short timeout, see NRF_BL_WDT_MAX_SCHEDULER_LATENCY_MS in the bootloader's sdk_config.h file. 

  • Hello

    Thank you. This i tested already but it's still the same. While debugging the bootloader at the function

    static bool dfu_enter_check(void)

    it's not entering in the following

       if (NRF_BL_DFU_ENTER_METHOD_GPREGRET &&
           (nrf_power_gpregret_get() & BOOTLOADER_DFU_START))
        {
            NRF_LOG_DEBUG("DFU mode requested via GPREGRET.");
            return true;
        }

    the problem is at

    nrf_power_gpregret_get()

    i'm not getting 0xb1 .  If I set this hardcoded to 0xb1 it's starting in dfu mode.....

    But in the application i'm setting it and then make a reset.

    Can I use the sd functions ?

    sd_power_gpregret_set(0,0xB1);
    sd_nvic_SystemReset();

    Or use the GPREGRET2 and change that in the application and bootloader ?

    And regarding the reset of the device after the dfu and update, any idea ?

    Thank you for any help....

    twittich

  • I debugged the application... After calling " nrf_power_gpregret_set(0xB1); " it jumps to " 00000A60  4B01 " and ends up at " 0002A968  BE00 "  " NRF_BREAKPOINT_COND; " in  " app_error_weak.c ".

    After that if i do same procedure with nrfjprog -r the dfu isn't coming up. To work like before i have to reflash the device. I have just seen that if i start debug the application the part of the bootloader before the softdevice in flash is deleted,  (checked with nrf connect) 0x00000FF8 - 0x00001000. The mbr is still there 0x00000000 - 0x00000B00

    If i debug the bootloader, i call in the application the function which includes the " nrf_power_gpregret_set(0xB1); " and " self reset " then in bootloader debug it starts at " 00000A60  4B01 " then end up at " 0002A968 BE00". Not coming to the first breakpoint which is "  ret_val = nrf_bootloader_init(dfu_observer); " ( the previous code with flash protect is commented out )  Hanging in Unknon function. After pressing " restart debug " dfu comes up.

    Bluetooth is not used. The bootloader uses dfu over usb-serial.

    In the file see after debug and before.
    flash bootloader part deleted after app debug.pdf

  • twittich said:
    I debugged the application... After calling " nrf_power_gpregret_set(0xB1); " it jumps to " 00000A60  4B01 " and ends up at " 0002A968  BE00 "  " NRF_BREAKPOINT_COND; " in  " app_error_weak.c ".

    nrf_power_gpregret_set() accesses the register directly which is not allowed when you have the Softdevice enabled, see Error handlingMemory isolation and runtime protection and Hardware peripherals. This is why your code ends up in the app error handler. You should use SD APIs you mentioned earlier to access grepregret instead:

    err_code = sd_power_gpregret_clr(0, 0xffffffff);
    VERIFY_SUCCESS(err_code);

    err_code = sd_power_gpregret_set(0, BOOTLOADER_DFU_START);
    VERIFY_SUCCESS(err_code);

    0x6A0 is the address of the Hardfault exception handler inside the MBR. 

  • Yes Slight smile i also just tried the sd function and that was the problem.

    And now i have to feed the dog from the bootloader.

  • Excellent, thanks for the update. So everything works now, or do you need more help with the WD part? 

  • I have to find out where the bootloader is waiting for the dfu update start that i can insert there the wd reload.

    Maybe it will work with the " loop_forever " function in " nrf_bootloader.c " ?

    But there is already a function named " nrf_bootloader_wdt_feed(); " ?

Reply Children
  • It is reloaded in the 'loop_forever' loop, but the CPU also enters sleep there so there must be periodic interrupts to wake the CPU so nrf_bootloader_wdt_feed() can be called in time. Maybe the nrf_bootloader_wdt_feed_timer_start() is not called for some reason? 

  • Yes it should be...

    At the function " void nrf_bootloader_wdt_init(void) "  " nrf_wdt_started() " is true and " nrf_bootloader_wdt_feed_timer_start() " is called.

    I also tried it to call the function directly " nrf_bootloader_wdt_feed () " in main and it goes also into it but the watchdog is not fed or where could it also be placed or do i have to init anything ?

    wake the CPU so nrf_bootloader_wdt_feed() can be called

    How and where do i have to do this ?

    Just to be clear this " NRF_BL_WDT_MAX_SCHEDULER_LATENCY_MS " is set to the same time as the wdt interval ?

  • As a test, please try to comment out the __WFE instruction from the wait for event loop and see if you still a WD timeout. 

    twittich said:
    How and where do i have to do this ?

     Based on the NRF_BL_WDT_MAX_SCHEDULER_LATENCY_MS value, the bootloader implementation should ensure that the CPU is woken at regular intervals. So not sure why it's not working. 

  • I commented out both _WFE and now it works partially.

    wdt interval is 20 sec and NRF_BL_WDT_MAX_SCHEDULER_LATENCY_MS  too, dfu inactivity still set to 0. It stays for 2 min in the dfu mode then it disappears and the application is not restarting, same if i debug the bootlaoder, it comes to " nrf_bootloader_app_start(); " but don't continue...?

  • The inactivity timer expires after 2 minutes by default, and it's supposed to reset the device and on subsequent startup enter DFU mode or boot the main application if one exists. So that part seems to be as expected.  

    twittich said:
    comes to " nrf_bootloader_app_start(); " but don't continue...?

     Are you sure it's not entering the main application? There are no while loops,etc that should cause the program to hang in nrf_bootloader_app_start().

Related