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

app_timer crashes

Hi devzone-team,

my application (custom board with nrf52840, sdk 16.0.098) uses 12 timers and it's organize in the 3 parts: uart, a pwm-bus (proprietary) and ble-scan-advertising (no connections).

The application is based on the beacon-example and is expanded with uart-, scheduler, and io-functionality.

If only one of the program-component works, all is fine. If there are 2 or all 3 components works at the same time, after a few minutes the timer-module crashes. The most times the debugger show an error on line 299 in app_timer2

static void on_compare_evt(drv_rtc_t const * const  p_instance)
{
    if (mp_active_timer)
    {
        /* If assert fails it suggests that safe window should be increased. */
        ASSERT(app_timer_cnt_diff_compute(drv_rtc_counter_get(p_instance),
--> line 299 -->                          mp_active_timer->end_val & RTC_COUNTER_COUNTER_Msk) < APP_TIMER_SAFE_WINDOW);

        NRF_LOG_INST_DEBUG(mp_active_timer->p_log, "Compare EVT");
        UNUSED_RETURN_VALUE(timer_expire(mp_active_timer));
        mp_active_timer = NULL;
    }
    else
    {
        NRF_LOG_WARNING("Compare event but no active timer (already stopped?)");
    }
}

sdk_config.h, the app_timer area

// <e> APP_TIMER_ENABLED - app_timer - Application timer functionality
//==========================================================
#ifndef APP_TIMER_ENABLED
#define APP_TIMER_ENABLED 1
#endif
// <o> APP_TIMER_CONFIG_RTC_FREQUENCY  - Configure RTC prescaler.
 
// <0=> 32768 Hz 
// <1=> 16384 Hz 
// <3=> 8192 Hz 
// <7=> 4096 Hz 
// <15=> 2048 Hz 
// <31=> 1024 Hz 

#ifndef APP_TIMER_CONFIG_RTC_FREQUENCY
#define APP_TIMER_CONFIG_RTC_FREQUENCY 1
#endif

// <o> APP_TIMER_CONFIG_IRQ_PRIORITY  - Interrupt priority
 

// <i> Priorities 0,2 (nRF51) and 0,1,4,5 (nRF52) are reserved for SoftDevice
// <0=> 0 (highest) 
// <1=> 1 
// <2=> 2 
// <3=> 3 
// <4=> 4 
// <5=> 5 
// <6=> 6 
// <7=> 7 

#ifndef APP_TIMER_CONFIG_IRQ_PRIORITY
#define APP_TIMER_CONFIG_IRQ_PRIORITY 6
#endif

// <o> APP_TIMER_CONFIG_OP_QUEUE_SIZE - Capacity of timer requests queue. 
// <i> Size of the queue depends on how many timers are used
// <i> in the system, how often timers are started and overall
// <i> system latency. If queue size is too small app_timer calls
// <i> will fail.

#ifndef APP_TIMER_CONFIG_OP_QUEUE_SIZE
#define APP_TIMER_CONFIG_OP_QUEUE_SIZE 32
#endif

// <q> APP_TIMER_CONFIG_USE_SCHEDULER  - Enable scheduling app_timer events to app_scheduler
 

#ifndef APP_TIMER_CONFIG_USE_SCHEDULER
#define APP_TIMER_CONFIG_USE_SCHEDULER 0
#endif

// <q> APP_TIMER_KEEPS_RTC_ACTIVE  - Enable RTC always on
 

// <i> If option is enabled RTC is kept running even if there is no active timers.
// <i> This option can be used when app_timer is used for timestamping.

#ifndef APP_TIMER_KEEPS_RTC_ACTIVE
#define APP_TIMER_KEEPS_RTC_ACTIVE 1
#endif

// <o> APP_TIMER_SAFE_WINDOW_MS - Maximum possible latency (in milliseconds) of handling app_timer event. 
// <i> Maximum possible timeout that can be set is reduced by safe window.
// <i> Example: RTC frequency 16384 Hz, maximum possible timeout 1024 seconds - APP_TIMER_SAFE_WINDOW_MS.
// <i> Since RTC is not stopped when processor is halted in debugging session, this value
// <i> must cover it if debugging is needed. It is possible to halt processor for APP_TIMER_SAFE_WINDOW_MS
// <i> without corrupting app_timer behavior.

#ifndef APP_TIMER_SAFE_WINDOW_MS
#define APP_TIMER_SAFE_WINDOW_MS 1000000
//#define APP_TIMER_SAFE_WINDOW_MS 500000
#endif

I test many things

* start only timers in scheduler (or normal functions), never in interrupt handlers

* makes timer in scheduler (what makes the error come faster)

* makes timer in interrupt

* works with global variables, works with scheduler-copy memory

But the final result is, thats the timer crashes the most times in minutes (sometimes after 1h or more).

My guess is that two or more timers overlap and the app_timer2 is pointing on a wrong timer and makes the assert.

Questions:

1) Can timer restarted in timer-handler (single shot timer)?

2) Can timer works with global variables (in interrupt and/or scheduler mode)?

3) I only make changes on sdk_config in APP_TIMER_CONFIG_OP_QUEUE_SIZE=32 but there is no possibility to change the MAX_TIMER value, perhaps the application cant work with 12 timer or more?

4) Is there a MAX-TIMER-counter, which have to be larger?

best regards

Bjoern

Parents
  • Hi Krzysztof,

    thanks for reply.

    The maximum app_timer timeout in application is 100ms, and I play with APP_TIMER_SAFE_WINDOW_MS to find a solution. But there was no dependency. Only if I hit the limits (0xFF FF FF and 0) I got error indepently of program parts.

    In my application there are to many timers, fifo, and/or interrupts to make a real debugging possible. If I break more than a second, I get an a abortion with error. My guess is, thats app_timers and interrupts fill the event-list (timer and scheduler) or other fifos.

    But your post explains the meaning of APP_TIMER_SAFE_WINDOW_MS, I dont real understand it before.

    Thanks.

    best regards

    Bjoern

Reply
  • Hi Krzysztof,

    thanks for reply.

    The maximum app_timer timeout in application is 100ms, and I play with APP_TIMER_SAFE_WINDOW_MS to find a solution. But there was no dependency. Only if I hit the limits (0xFF FF FF and 0) I got error indepently of program parts.

    In my application there are to many timers, fifo, and/or interrupts to make a real debugging possible. If I break more than a second, I get an a abortion with error. My guess is, thats app_timers and interrupts fill the event-list (timer and scheduler) or other fifos.

    But your post explains the meaning of APP_TIMER_SAFE_WINDOW_MS, I dont real understand it before.

    Thanks.

    best regards

    Bjoern

Children
Related