Runtime Statistics

Nano-RK has the ability to collect data about tasks during runtime. This can be useful for watching worst-case execution time of tasks as well as observing their total CPU consumption.

In order to enable runtime tracking you need to add the following to your project's nrk_cfg.h

1#define NRK_STATS_TRACKER

Here is a sample from calling nrk_stats_display_all():

Nano-RK Task Statistics:
 Task ID: 0
   Total System Uptime: 12 secs 508 ms
   Idle Task Deep Sleep Time: 11 secs 690 ms
   Total CPU: 12 secs 178 ms
   Time [Min,Last,Max]: 0 secs 9 ms, 0 secs 9 ms, 0 secs 237 ms
   Swap-ins: 100
   Preemptions: 100
   Kernel Violations: 0
   Overflow Error Status: 0
 Task ID: 1
   Total CPU: 0 secs 154 ms
   Time [Min,Last,Max]: 0 secs 2 ms, 0 secs 2 ms, 0 secs 7 ms
   Swap-ins: 51
   Preemptions: 0
   Kernel Violations: 0
   Overflow Error Status: 0
 Task ID: 2
   Total CPU: 0 secs 106 ms
   Time [Min,Last,Max]: 0 secs 3 ms, 0 secs 3 ms, 0 secs 4 ms
   Swap-ins: 27
   Preemptions: 0
   Kernel Violations: 0
   Overflow Error Status: 0
The parameters are as follows:
  • Total CPU:
    • This is the total CPU runtime the task has consumed
  • Min Time:
    • This is the shortest time the task executed before suspending
  • Max Time:
    • This is the longest time the task executed before suspending
  • Last Time:
    • This is the time consumed the last time the task was scheduled
  • Swap-ins:
    • This is the number of times the task was scheduled to run
  • Preemptions:
    • This is the number of times the task was interrupted by a higher priority task
  • Kernel Violations:
    • This is the number of times this task has generated a kernel panic
  • Overflow Error Status:
    • This is set to 1, if any counting parameter in the task would have overflowed
    • If this is set to 1, then statistic aggregation was halted at some point, call nrk_stats_reset() to continue.
  • Idle Task Deep Sleep Time:
    • This value appears for the idle task. It lets you know how often the idle task is able to put the CPU in deep sleep mode compared to just idle.
  • Total System Update:
    • This is the amount of time the OS has been running. It is displayed with the Idle task data.
  • Note, these times refer to the task's actual runtime. Time taken by a higher priority task that preempted this task is not counted against it. That time is accumulated in the higher priority tasks execution time.

We provide the following functions for inspecting your tasks.

void nrk_stats_display_all();

This prints all tasks statistics. Sometimes it is useful to call nrk_halt() after if you wish to freeze the OS.

void nrk_stats_display_pid(uint8_t pid);

This function will print the stats for a task specified by pid. For example if you want to print the currently running task's stats you could do:

1nrk_stats_display_pid( nrk_get_pid() );

void nrk_stats_reset();

This function will reset all task statistics information. For extremely long duration tasks, this should be called to prevent an overflow. If one of the statistics accumulates to the point where it will roll over, all statistic collecting for that task will be halted. Overflows can be detected by looking at the "Overflow Error Status" printout. This function does not reset the total system time.

int8_t nrk_stats_get(uint8_t pid, nrk_task_stat_t *t)

This function returns the kernel statistics data in a application usable structure as defined below:

 1typedef struct task_stat {
 2        uint32_t total_ticks;
 3        uint32_t min_exec_ticks;
 4        uint32_t max_exec_ticks;
 5        uint32_t last_exec_ticks;
 6        uint32_t swapped_in;
 7        uint32_t cur_ticks;
 8        uint32_t preempted;
 9        uint8_t violations;
10        uint8_t overflow;
11} nrk_task_stat_t;

For an example of how to best utilize this function see the basic_task_stats project. Note that since nrk_task_stat_t is a large structure, it should be defined by your application globally to avoid being pushed onto the stack. Below is an example of how to convert the tick units to time and display them in a similar fashion to nrk_stats_display_pid().

 1        // defined globally somewhere...
 2        nrk_task_stat_t my_stats;
 3        nrk_time_t t;
 4        uint8_t val;
 5
 6        // in your function
 7        val=nrk_stats_get(nrk_get_pid(), &my_stats);
 8        nrk_kprintf( PSTR( "\r\n   Total CPU: "));
 9        t=_nrk_ticks_to_time(my_stats.total_ticks);
10        printf( "%lu secs %lu ms", t.secs, t.nano_secs/NANOS_PER_MS );
11        nrk_kprintf( PSTR( "\r\n   Time [Min,Last,Max]: "));
12        t=_nrk_ticks_to_time(my_stats.min_exec_ticks);
13        printf( "%lu secs %lu ms, ", t.secs, t.nano_secs/NANOS_PER_MS );
14        t=_nrk_ticks_to_time(my_stats.last_exec_ticks);
15        printf( "%lu secs %lu ms, ", t.secs, t.nano_secs/NANOS_PER_MS );
16        t=_nrk_ticks_to_time(my_stats.max_exec_ticks);
17        printf( "%lu secs %lu ms", t.secs, t.nano_secs/NANOS_PER_MS );
18        nrk_kprintf( PSTR( "\r\n   Swap-ins: "));
19        printf( "%lu",my_stats.swapped_in );
20        nrk_kprintf( PSTR( "\r\n   Preemptions: "));
21        printf( "%lu",my_stats.preempted);
22        nrk_kprintf( PSTR( "\r\n   Kernel Violations: "));
23        printf( "%u",my_stats.violations);
24        nrk_kprintf( PSTR( "\r\n   Overflow Error Status: "));
25        printf( "%u",my_stats.overflow);
26        nrk_kprintf( PSTR("\r\n") );
27

This function returns NRK_OK upon success and NRK_ERROR if the pid entered is greater than NRK_MAX_TASKS.

void nrk_stats_get_deep_sleep(nrk_time_t *t);

This function fills a passed in time structure with the OS deep sleep time.

Prev: Power Next: EEPROM Top