app_timer APP_TIMER_MODE_REPEATED not working after serveral hours

Hi, I'm build an applicaiton using app_timer
Mode: APP_TIMER_MODE_REPEATED
Interval: 5 minutes
Flow:
- after 5 minutes I will restart the timer (stop and create a new one)
- in app_timer_handler I set a flag and logging that has expired to indicate the timer has expired and now it need to restart the timer
- I hang debugging almost 6 hours. Everything worked well, but after 5 hours since I start debug. The app_timer not working (app_timer_handler no longer set the flag and logging the timer has expried like normal)
I'm sure device is working because when I connect BLE device still advertising and connectable and debug terminal display connected normally. 

Note: I'm using 2 libuartes in soft-device BLE application (1 libuarte using app_timer)
SDK:16
nRF52833 custom board
app_timer using internal LFCLK
Here is my sdk_config.h

1016.sdk_config.h
Thank you for your support !
Best Regard

Parents
  • Hi,

    Are you using app_timer2, or the old app_timer implementation? There are known issues with the old implementation that match your symptoms.

    Please try changing to app_timer2 and see if this resolves your issues.

    Best regards,
    Jørgen

  • Hello Team,

    I am facing the same issue with app_timer2 and SDK17.
    My implementation is similar to John12's; I have app_timers running to control the modem state. In the timer handler, a flag is set, on which a function in main reads, executes the modem code, and then clears it.
    Sometimes I need the modem code to execute faster, so I periodically stop and start the timers.

    The code runs for some time; however, after hours, all app_timers stop firing without any error. I have APP_ERROR_CHECK() on both start and stop functions.


    app_timer_cnt_get()  still increments but however all app_timers stops firing.
    Any guide to resolve this is highly appreciated. 

    Thanks.



    sdk config

    // <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 100
    #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 0
    #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 300000
    #endif
    
    // <h> App Timer Legacy configuration - Legacy configuration.
    
    //==========================================================
    // <q> APP_TIMER_WITH_PROFILER  - Enable app_timer profiling
     
    
    #ifndef APP_TIMER_WITH_PROFILER
    #define APP_TIMER_WITH_PROFILER 1
    #endif
    
    // <q> APP_TIMER_CONFIG_SWI_NUMBER  - Configure SWI instance used.
     
    
    #ifndef APP_TIMER_CONFIG_SWI_NUMBER
    #define APP_TIMER_CONFIG_SWI_NUMBER 0
    #endif
    


    app_timer stop/start functon
    void timer_start_v2(uint8_t timerid, uint32_t time){
    	static bool timers_created = false;
    	uint32_t err_code;
    	
    	if(timers_created==false){
    		err_code = app_timer_create(&m_timer0, APP_TIMER_MODE_REPEATED, timer0_timeout_handler);
    		APP_ERROR_CHECK(err_code);
    		
    		err_code = app_timer_create(&m_timer1, APP_TIMER_MODE_REPEATED, timer1_timeout_handler);
    		APP_ERROR_CHECK(err_code);
    		timers_created=true;
    		
    		//err_code = app_timer_create(&m_timer2, APP_TIMER_MODE_REPEATED, timer2_timeout_handler);
    		//APP_ERROR_CHECK(err_code);
    		//timers_created=true;
    	}
    	//convert time in ms to ticks => 16,384 ticks = 1000ms
    	time = (16384*time)/1000;
    
    	
    	switch(timerid){
    		case 0:{
    			if(timer0_started==true){
    				err_code = app_timer_stop(m_timer0); //stop current timer
    				APP_ERROR_CHECK(err_code);
    				timer0_started=false;
    			}
    			err_code = app_timer_start(m_timer0, APP_TIMER_TICKS(time), NULL);
    			APP_ERROR_CHECK(err_code);
    			timer0_time = time;
    			timer0_started = true;
    		}break;
    		case 1:{
    			if(timer1_started==true){
    				err_code = app_timer_stop(m_timer1); //stop current timer
    				APP_ERROR_CHECK(err_code);
    				timer1_started=false;
    			}
    			err_code = app_timer_start(m_timer1, APP_TIMER_TICKS(time), NULL);
    			APP_ERROR_CHECK(err_code);
    			timer1_time = time;
    			timer1_started = true;
    		}break;
    		//case 2:{
    		//	if(timer2_started==true){
    		//		err_code = app_timer_stop(m_timer2); //stop current timer
    		//		APP_ERROR_CHECK(err_code);
    		//		timer2_started=false;
    		//	}
    		//	err_code = app_timer_start(m_timer2, time, NULL);
    		//	APP_ERROR_CHECK(err_code);
    		//	//timer2_time = time;
    		//	timer2_started = true;
    		//}break;
    		
    		default:break;
    	}
    		
    }


    Handlers
    void timer0_timeout_handler(void * p_context)
    {
    	UNUSED_PARAMETER(p_context);
    	//timerhandler0();
    	timer_run_flag |= 0x01;
    }
    
    void timer1_timeout_handler(void * p_context)
    {
    	UNUSED_PARAMETER(p_context);
    	//timerhandler1();
    	timer_run_flag |= 0x02;
    }
    


    Inside Main loop
    ```if(timer_run_flag & 0x01){ //timer0 flag
    		timerhandler0();
    		timer_run_flag &= (uint8_t)~0x01; // Clear the flag
    	}
    	if(timer_run_flag & 0x02){ //timer1 flag
    		timerhandler1();
    		timer_run_flag &= (uint8_t)~0x02; // Clear the flag
    	}
    	




  • Adding more context

    1. Here is where app_timer stops firing


    2. Can still connect with BLE
    (There is a new app_timer created here for monitoring connection time)



    3. Hardfault on ble disconnect
    (Disconnect stops the app_timer above)


    4. map file


    Does the hard fault indicate a problem with the nrf_sortlist_remove function? 

Reply Children
Related