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

[bugreport] app_timer_stop() resets RTC1 counter when APP_TIMER_KEEPS_RTC_ACTIVE is set

My setup is as follows: nRF5 SDK 13.1 with s132 5.1.0 nRF52832_AA Keil 5.25pre

I use RTC1 counter for timestamping along with app_timer timers. My get_timestamp() function retrieves it's time value by calling app_timer_cnt_get() and then uses app_timer_cnt_diff_compute() to check how much time passed since it was called. Result is used to increment monotonous timer tick counter which is then processed to obtain timestamp:

  uint64_t get_timestamp()
  {
    static uint32_t last_ticks=0;
	static uint64_t timestamp_ticks=0;
	uint32_t curr_ticks=app_timer_cnt_get();

	timestamp_ticks+=app_timer_cnt_diff_compute(curr_ticks, last_ticks);
	last_ticks=curr_ticks;

	return timestamp_ticks;
  }

It is working well in few applications but I've noticed that when I use app_timer_stop() timestamp jumps by large value. It turns out that calling this function on last running timer resets RTC1 counter by calling timer_list_remove() which contains following code snippet:

// Timer is the first in the list
    if (p_previous == p_current)
    {
        mp_timer_id_head = mp_timer_id_head->next;

        // No more timers in the list. Reset RTC1 in case Start timer operations are present in the queue.
        if (mp_timer_id_head == NULL)
        {
            NRF_RTC1->TASKS_CLEAR = 1;
            m_ticks_latest        = 0;
            m_rtc1_reset          = true;
            nrf_delay_us(MAX_RTC_TASKS_DELAY);
        }
    }

IMHO this is a bug because setting APP_TIMER_KEEPS_RTC_ACTIVE=1 in sdk_config.h according to infocenter documentation should result in always running RTC1 which can be used 'for timestamping'. Introducing large and unpredictable jumps in counter values contradicts this.

As a workaround I've started always running recurring timer which does nothing. This works but it's not ideal since nRF will wake from sleep to process timeout events for this timer.

In attempt to have more reliable fix I've patched snippet above so it looks like this:

    // Timer is the first in the list
    if (p_previous == p_current)
    {
        mp_timer_id_head = mp_timer_id_head->next;

        // No more timers in the list. Reset RTC1 in case Start timer operations are present in the queue.
        if (mp_timer_id_head == NULL)
        {
//do not reset RTC counter when it's used for timestamp
#if (APP_TIMER_KEEPS_RTC_ACTIVE == 0)
            NRF_RTC1->TASKS_CLEAR = 1;
            m_ticks_latest        = 0;
            m_rtc1_reset          = true;
            nrf_delay_us(MAX_RTC_TASKS_DELAY);
#else
			m_rtc1_reset          = false;
#endif

        }
    }

I'd appreciate If someone from Nordic could take a look and check if this won't break something or propose different solution.

Parents
  • Hi,

    The SDK team is aware of the vulnerability, but they haven't looked thoroughly into it because they have been working on an entirely new implementation of the library. The new implementation is scheduled to be included in SDK 15.

  • Glad to hear it fixed the problem. Unfortunately we can't talk about timeline here but it shouldn't take too long to be released. I would say 1 2 months.

  • HungBui - Thanks for the rapid response.
    sorry about this, but I do not completely understand what you mean

    The function timer_list_remove() in apptimer.c file in SDK15 looks identical to the one in 14.2 -  so I don't know how porting SDK15 timer library helps.

    The apptimer2.c file in my copy of nRF5_SDK_15.3.0_59ac345 is in a subdirectory called "experimental."

    Please clarify - am I supposed to replace apptimer.c in my project source list with apptimer2.c from experimental subdirectory in 15.3?

    Are there any other files need replacing at the same time?

    Are there other things required such as #define APP_TIMER_V2 and if so, where to define that?

    What side effects of this "experimental"  version are known since release? 

    Thanks

    Edit: addition - trying to put the experimental version from 15.3  back into my 14.2 project falls over heavily on the lack of nrfx.  Please advise before I get too deep into this.

  • Hi Nick, 

    I'm sorry for the confusion. It was an old case and I wasn't following it earlier.

    I had a look at the implementation we have now on SDK v15.3 and it turned out that we had little development on this over the last 2 years. 

    So the official app timer implementation we have in SDK v15.3 remains unchanged compare to what on SDK v13.x/14.x 

    The new implementation, app_timer2.c, was introduced but remains in experimental. This means it can be used as an example code but it's not extensively tested. 

    The solution for now is either:

    - Adding a dummy timer to keep the RTC running

    - Use app_timer2 which requries you to copy all the dependencies (nrfx drivers) into SDK v14.2 

    I will check internally with R&D if we can do anything. 

  • Thanks for the help so far.

    We have been gradually breaking our product as I fixed each of the inconsistencies between app_timer2 and app_timer.  We have a BLE stack enabled, and a scheduler.  Using app_timer2 and app_timer_rtc from your zip file earlier with a modification to avoid the use of NRFX,  we get error 4097 from nrf_sdh_enable_request if we initialize the BLE after the timers, the code locks up if we initialize the BLE before the app_timers and continually restarts if we initialise scheduler before the timers. 

    Obviously, since we cannot do in-circuit debugging with a BLE stack, this whole thing is working "blind".

    As I have one more week in which to try to fix this, I plan to revert this branch and start over. 

    The actual requirement is to get a reliable timestamp with BLE stack running, an event scheduler and sleep/wake power-modes invoked.  Fundamental requirement really,

    Any help appreciated.

  • The actual requirement is to get a reliable timestamp with BLE stack running, an event scheduler and sleep/wake power-modes invoked.  Fundamental requirement really,

    I struggled with the same situation, though I'm using SDK 15.2. The easiest workaround is to make sure you always have at least one app_timer running. So even if you don't need any app_timers, keep a dummy one running in the background.

  • Hi Nick, 

    I'm really sorry for the inconvenience. 

    You may hit the same issue as this one.

    It's a limitation of app_timer, is it possible to enable the app timer after the softdevice, or stop the timer (to avoid any interrupt) when you enable the softdevice ? 

    Since app_timer2 is not intensively tested I would suggest you follow Markku suggestion to keep a dummy app_timer running all the time. 

Reply Children
No Data
Related