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

FreeRTOS+WDT+SDK17 problem

I have added WDT to the blinky_freertos sample.

/** add **/
static nrf_drv_wdt_channel_id m_channel_id;

static void wdt_event_handler(void)
{
}
/**********/

int main(void)
{
    ret_code_t err_code;

    /* Initialize clock driver for better time accuracy in FREERTOS */
    err_code = nrf_drv_clock_init();
    APP_ERROR_CHECK(err_code);

    /* Configure LED-pins as outputs */
    bsp_board_init(BSP_INIT_LEDS);

    /* Create task for LED0 blinking with priority set to 2 */
    UNUSED_VARIABLE(xTaskCreate(led_toggle_task_function, "LED0", configMINIMAL_STACK_SIZE + 200, NULL, 2, &led_toggle_task_handle));

    /* Start timer for LED1 blinking */
    led_toggle_timer_handle = xTimerCreate( "LED1", TIMER_PERIOD, pdTRUE, NULL, led_toggle_timer_callback);
    UNUSED_VARIABLE(xTimerStart(led_toggle_timer_handle, 0));

    /* Activate deep sleep mode */
    SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;

/** add **/
    nrf_drv_wdt_config_t config = NRF_DRV_WDT_DEAFULT_CONFIG;
    err_code = nrf_drv_wdt_init(&config, wdt_event_handler);
    APP_ERROR_CHECK(err_code);
    err_code = nrf_drv_wdt_channel_alloc(&m_channel_id);
    APP_ERROR_CHECK(err_code);
    nrf_drv_wdt_enable();
/*********/

	/* Start FreeRTOS scheduler. */
    vTaskStartScheduler();

    while (true)
    {
        /* FreeRTOS should not be here... FreeRTOS goes back to the start of stack
         * in vTaskStartScheduler function. */
    }
}

And I am debugging with SEGGER ozone.

building with SDK17:

If you reset the software in the debugger and start it, the application freezes.
t stops in the following loop.
And RTC1 is not counting up.

*********************************************************************
port_cmsis_systick.c

     /* No SD -  we would just block interrupts globally.
      * BASEPRI cannot be used for that because it would prevent WFE from wake up.
     */
      do{
         __WFE();
      } while (0 == (NVIC->ISPR[0] | NVIC->ISPR[1]));

**********************************************************************
However, after WDT reset, blinky works normally.

I have built the same application with SDK15.
It was perfectly fine.

SDK17 seems to have a problem.

I found a difference with SDK15.

SDK17 nrf_drv_clock.c
*****************************************
nrf_drv_clock_init()
...
    if (nrf_wdt_started())
    {
        m_clock_cb.lfclk_on = true;
    }
*****************************************
If a software reset occurs after WDT is activated, WDT remains activated after the reset. However, LFCLK is stopped.
As a result, the above process does not start LFCLK, so even if RTC1 is started, it will not be counted up.

  • Syuji,

    Sorry for late response, we started coming back from summer holidays. I will take a look at this problem today, will come back to you soon.

  • Where are you feeding the watchdog? (where is your application calling nrf_drv_wdt_channel_feed?)

    For me it is working fine if i feed the wdt in the bsp_event_callback with a button press. the wdt reset happens if i do not press the button.

  • I add feeding the watchdog in led_toggle_task_function.

    But the problem is not there.
    The problem is that if a software reset occurs while WtchDog is running, FreeRTOS will not work properly.
    And the cause is that LFCLK is not initialized properly.

  • loquat said:
    The problem is that if a software reset occurs while WtchDog is running, FreeRTOS will not work properly.
    And the cause is that LFCLK is not initialized properly.

    i cannot see this behavior in my quick test on the desk. No software resets have happened in my test. Can you please attach your project so that i can test this. 

  • Target board is PCA10056(nRF52840).

    /**
     * Copyright (c) 2015 - 2020, Nordic Semiconductor ASA
     *
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     *
     * 1. Redistributions of source code must retain the above copyright notice, this
     *    list of conditions and the following disclaimer.
     *
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     *
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     *
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     *
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     *
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     *
     */
    /** @file
     * @defgroup blinky_example_main main.c
     * @{
     * @ingroup blinky_example_freertos
     *
     * @brief Blinky FreeRTOS Example Application main file.
     *
     * This file contains the source code for a sample application using FreeRTOS to blink LEDs.
     *
     */
    
    #include <stdbool.h>
    #include <stdint.h>
    
    #include "FreeRTOS.h"
    #include "task.h"
    #include "timers.h"
    #include "bsp.h"
    #include "nordic_common.h"
    #include "nrf_drv_clock.h"
    #include "sdk_errors.h"
    #include "app_error.h"
    #include "nrf_drv_wdt.h"
    
    #define	WDT_ENABLE			1
    
    #if LEDS_NUMBER <= 2
    #error "Board is not equipped with enough amount of LEDs"
    #endif
    
    #define TASK_DELAY        200           /**< Task delay. Delays a LED0 task for 200 ms */
    #define TIMER_PERIOD      1000          /**< Timer period. LED1 timer will expire after 1000 ms */
    
    TaskHandle_t  led_toggle_task_handle;   /**< Reference to LED0 toggling FreeRTOS task. */
    TimerHandle_t led_toggle_timer_handle;  /**< Reference to LED1 toggling FreeRTOS timer. */
    
    /**@brief LED0 task entry function.
     *
     * @param[in] pvParameter   Pointer that will be used as the parameter for the task.
     */
    static void led_toggle_task_function (void * pvParameter)
    {
        UNUSED_PARAMETER(pvParameter);
        while (true)
        {
    #if WDT_ENABLE
        	nrf_drv_wdt_feed();
    #endif
            bsp_board_led_invert(BSP_BOARD_LED_0);
    
            /* Delay a task for a given number of ticks */
            vTaskDelay(TASK_DELAY);
    
            /* Tasks must be implemented to never return... */
        }
    }
    
    /**@brief The function to call when the LED1 FreeRTOS timer expires.
     *
     * @param[in] pvParameter   Pointer that will be used as the parameter for the timer.
     */
    static void led_toggle_timer_callback (void * pvParameter)
    {
        UNUSED_PARAMETER(pvParameter);
        bsp_board_led_invert(BSP_BOARD_LED_1);
    }
    
    #if WDT_ENABLE
    static nrf_drv_wdt_channel_id m_channel_id;
    
    static void wdt_event_handler(void)
    {
    }
    #endif
    
    static void bsp_evt_handler(bsp_event_t evt)
    {
        switch (evt)
        {
            case BSP_EVENT_KEY_0:
        	NVIC_SystemReset(); /* Software Reset */
                break;
        	
        default:
        		break;
        }
    }
    
    int main(void)
    {
        ret_code_t err_code;
    
        /* Initialize clock driver for better time accuracy in FREERTOS */
        err_code = nrf_drv_clock_init();
        APP_ERROR_CHECK(err_code);
    
        /* Configure LED-pins as outputs */
        err_code = bsp_init(BSP_INIT_LEDS | BSP_INIT_BUTTONS, bsp_evt_handler);
        APP_ERROR_CHECK(err_code);
    
        /* Create task for LED0 blinking with priority set to 2 */
        UNUSED_VARIABLE(xTaskCreate(led_toggle_task_function, "LED0", configMINIMAL_STACK_SIZE + 200, NULL, 2, &led_toggle_task_handle));
    
        /* Start timer for LED1 blinking */
        led_toggle_timer_handle = xTimerCreate( "LED1", TIMER_PERIOD, pdTRUE, NULL, led_toggle_timer_callback);
        UNUSED_VARIABLE(xTimerStart(led_toggle_timer_handle, 0));
    
        /* Activate deep sleep mode */
        SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;
    
    #if WDT_ENABLE
        nrf_drv_wdt_config_t config = NRF_DRV_WDT_DEAFULT_CONFIG;
        err_code = nrf_drv_wdt_init(&config, wdt_event_handler);
        APP_ERROR_CHECK(err_code);
        err_code = nrf_drv_wdt_channel_alloc(&m_channel_id);
        APP_ERROR_CHECK(err_code);
        nrf_drv_wdt_enable();
    #endif
    	/* Start FreeRTOS scheduler. */
        vTaskStartScheduler();
    
        while (true)
        {
            /* FreeRTOS should not be here... FreeRTOS goes back to the start of stack
             * in vTaskStartScheduler function. */
        }
    }
    
    /**
     *@}
     **/
    

    And sdk_config.h modified
    #define NRFX_WDT_CONFIG_RELOAD_VALUE 10000

    If #define WDT_ENABLE 1.  (WDT enabled)
    1. When PoweOnReset, LED is blinking.
    2. When Button 1 pushed(execute SoftwareReset), LED blinking is stopped.
    3. After 10 seconds, LED blinking is started.

    If #define WDT_ENABLE 0. (WDT disabled)
    1. When PoweOnReset, LED is blinking.
    2. When Button 1 pushed(execute SoftwareReset), LED blinking is restarted quickly.

Related