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

issues with app timer module

Hi,

      I am developing firmware for a custom NRF52840 based board. I am using softdevice 6.0.0 with SDK 15.0 and the SES environment.

I am trying to use three application timers:

1) driving the battery service to update a couple of characteristics every 30 seconds. This has been working fine since the very start of this project about 6 months ago

2) calling a handler that does sampling, filtering of data and writing a characteristic every 20ms. Time in this handler is in the order of 10-15 ms.

3) calling a handler that does 3 x i2c reads every 20ms however the same behaviour is seen with trigger rate of 10ms.

sdk_config is setup as follows.

// <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 0
#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 1
#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

// <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 0
#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 for the battery service just works and has worked for months.

I then tried to add the timer for the sampling handler. The handler is called very slowly say once a second unless APP_TIMER_CONFIG_USE_SCHEDULER is set to 1. This is the only reason it is set in sdk_config. With APP_TIMER_CONFIG_USE_SCHEDULER set, the calls to the handler speed up and are probably running every 20ms but I haven't timed it yet.

Adding the third timer causes a hard NRF_ERROR_NOMEM on the call to  app_sched_event_put in app_timer.c. I have increased the queue up to 800 with no change in behaviour.

As far as I can see

  •  app_timer_init() is called from the main function on startup before any other calls to the module.
  • The sample timer is created from the main function at startup and started and stopped when the application needs to sample. Bluetooth is connected while sampling.
  • The battery timer gets created and started from the main function at startup.
  • The third timer is created and started on bluetooth connection. It is stopped when bluetooth disconnects.

This application is fairly large and complex. I am happy to provide code but need to narrow down what you want to see.

Many thanks in advance

Cheers Paul

Parents
  • Hi,

     

    Just to make sure you are adjusting the correct queue size (not APP_TIMER_CONFIG_OP_QUEUE_SIZE).

    Have you tried upping the scheduler queue size? It's normally set in main:

    static void scheduler_init(void)
    {
        APP_SCHED_INIT(SCHED_MAX_EVENT_DATA_SIZE, SCHED_QUEUE_SIZE);
    }

     

    Kind regards,

    Håkon

  • Hi Hakon,

                     One of the issues I have is that I don't want to use the app scheduler for this. 

    My real issue is that:

    1) I can only get the sample timer to run at ms rates if I use the app scheduler

    2) the third timer doesn't run at all.

    I think that this problem is related to the length of time in the sample handler - ~10-15ms. It is supposed to be called every 20ms and then the third timer every 10ms. The timing budget just doesn't work (15 + 10 > 20). Using the app scheduler just serialises the calls on a first come first served basis and moves the work out of interrupt time/context.

    In any case I dropped the use of the sample timer and am progressing. 

    Cheers Paul

Reply
  • Hi Hakon,

                     One of the issues I have is that I don't want to use the app scheduler for this. 

    My real issue is that:

    1) I can only get the sample timer to run at ms rates if I use the app scheduler

    2) the third timer doesn't run at all.

    I think that this problem is related to the length of time in the sample handler - ~10-15ms. It is supposed to be called every 20ms and then the third timer every 10ms. The timing budget just doesn't work (15 + 10 > 20). Using the app scheduler just serialises the calls on a first come first served basis and moves the work out of interrupt time/context.

    In any case I dropped the use of the sample timer and am progressing. 

    Cheers Paul

Children
No Data
Related