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

  • 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().

Reply
  • 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().

Children
  • Yes it isn't entering the application there are different alive indicators, if i remove the comments from " _WFE " it restarts the application normal.

    What did the uncommenting exactly do that the wdt will not time out ?

    Actual if the wdt is set to 40 seconds, the bootloader inactivity to 0 everything works fine if the dfu update is started immidiatly.

    ------

    Now i set the wdt to 5 secs and do the following and after maximum a minute it makes a restart (maybe the inactivity timeout ?), theoretically it has to stay forever in the dfu mode until the update is started  /done.

    I'll try to write directly in the register and guess it's working. First i fill all regs with 0xffffffff and then with the magic number. thats the first i do in the main of the bootloader and then in the forever loop...

    NRF_WDT->RR[0] = 0x6E524635UL;
    NRF_WDT->RR[1] = 0x6E524635UL;
    NRF_WDT->RR[2] = 0x6E524635UL;
    NRF_WDT->RR[3] = 0x6E524635UL;
    NRF_WDT->RR[4] = 0x6E524635UL;
    NRF_WDT->RR[5] = 0x6E524635UL;
    NRF_WDT->RR[6] = 0x6E524635UL;
    NRF_WDT->RR[7] = 0x6E524635UL;

    And just byside is this correct ?

    in the file " nrf_bootloader_wdt.c " in function " static void wdt_feed(void) " the for loop " for (nrf_wdt_rr_register_t i = NRF_WDT_RR0; i < NRF_WDT_RR7; i++) " counts up to smaller than " NRF_WDT_RR7 " , i guess it has to be " <= " .

    inactivity timer expires after 2 minutes by default,

    where is this timer and where is the 2 minutes set ?

  • twittich said:
    What did the uncommenting exactly do that the wdt will not time out ?

     WFE puts the CPU to sleep as long as there are no pending interrupts. So the frequency of your interrupts will then define the reload interval. Without WFE it will be reloaded almost continuously(is not reloaded when processing scheduler tasks). However, I don't see how removing __WFE could cause the program to crash to app_start. Can you read out the the  Program counter (PC) and xPSR registers when this happens?

    twittich said:
    in the file " nrf_bootloader_wdt.c " in function " static void wdt_feed(void) " the for loop " for (nrf_wdt_rr_register_t i = NRF_WDT_RR0; i < NRF_WDT_RR7; i++) " counts up to smaller than " NRF_WDT_RR7 " , i guess it has to be " <= "

     Good catch! Are you enabling channel 7 in your code? That might explain the unexpected WD resets you saw earlier.  

    twittich said:
    where is this timer and where is the 2 minutes set ?

     If you search for 'NRF_BL_DFU_INACTIVITY_TIMEOUT_MS' in your bootloader project you will see where the timeout is configured and find references to the timer instance used for the bootloader timeout. The timer is reloaded during DFU, so the DFU itself is not limited to 2 minutes.  

  • 'NRF_BL_DFU_INACTIVITY_TIMEOUT_MS

    This i know as i said this was set to 0 but i thought because of that " The inactivity timer expires after 2 minutes by default, " you meant another timer.

    With my fix in the loop, the wd feeding at the beginning in main of bootloader and commenting out of __wfe the wd will not timeout and this is set actually to  1.5 sec.

    There is now one thing left which is not working, if i set the NRF_BL_DFU_INACTIVITY_TIMEOUT_MS it's nothing doing, no difference if set to 0 or any value, no reset at all ?

    Good catch! Are you enabling channel 7 in your code?

    Thank you, yes all ...

  • twittich said:
    There is now one thing left which is not working, if i set the NRF_BL_DFU_INACTIVITY_TIMEOUT_MS it's nothing doing, no difference if set to 0 or any value, no reset at all ?

     '0' disables the inactivity timer so the bootloader will not time out at all. Here's the default setting from sdk_config.h:

    // <i> If 0, no inactivity timer will be used. Values 1-99 are invalid.

    #ifndef NRF_BL_DFU_INACTIVITY_TIMEOUT_MS
    #define NRF_BL_DFU_INACTIVITY_TIMEOUT_MS 120000
    #endif

  • Yes i know the timer and the use of it.

    But i want to use the timer, so that it jumps back to application if no update is started. The wd is now always fed and happy and will not reset the device.

Related