1 /**
2  * @file lv_nuttx_profiler.c
3  *
4  */
5 
6 /*********************
7  *      INCLUDES
8  *********************/
9 
10 #include "lv_nuttx_profiler.h"
11 #include "../../../lvgl.h"
12 
13 #if LV_USE_NUTTX && LV_USE_PROFILER && LV_USE_PROFILER_BUILTIN
14 
15 #include <nuttx/arch.h>
16 #include <stdio.h>
17 
18 /*********************
19  *      DEFINES
20  *********************/
21 
22 #define TICK_TO_NSEC(tick) ((tick) * 1000 / cpu_freq)
23 
24 /**********************
25  *      TYPEDEFS
26  **********************/
27 
28 /**********************
29  *  STATIC PROTOTYPES
30  **********************/
31 
32 static uint32_t cpu_freq = 0; /* MHz */
33 
34 /**********************
35  *  STATIC VARIABLES
36  **********************/
37 
38 static uint64_t tick_get_cb(void);
39 static void flush_cb(const char * buf);
40 
41 /**********************
42  *      MACROS
43  **********************/
44 
45 /**********************
46  *   GLOBAL FUNCTIONS
47  **********************/
48 
lv_nuttx_profiler_init(void)49 void lv_nuttx_profiler_init(void)
50 {
51     cpu_freq = (uint32_t)up_perf_getfreq() / 1000000;
52     if(cpu_freq == 0) {
53         LV_LOG_ERROR("Failed to get CPU frequency");
54         return;
55     }
56     LV_LOG_USER("CPU frequency: %" LV_PRIu32 " MHz", cpu_freq);
57 
58     lv_profiler_builtin_config_t config;
59     lv_profiler_builtin_config_init(&config);
60     config.tick_per_sec = 1000000000; /* 1 sec = 1000000000 nsec */
61     config.tick_get_cb = tick_get_cb;
62     config.flush_cb = flush_cb;
63     lv_profiler_builtin_init(&config);
64 }
65 
66 /**********************
67  *   STATIC FUNCTIONS
68  **********************/
69 
tick_get_cb(void)70 static uint64_t tick_get_cb(void)
71 {
72     static uint32_t prev_tick = 0;
73     static uint64_t cur_tick_ns = 0;
74     uint32_t act_time = up_perf_gettime();
75     uint32_t elaps;
76 
77     /*If there is no overflow in sys_time simple subtract*/
78     if(act_time >= prev_tick) {
79         elaps = act_time - prev_tick;
80     }
81     else {
82         elaps = UINT32_MAX - prev_tick + 1;
83         elaps += act_time;
84     }
85 
86     cur_tick_ns += TICK_TO_NSEC(elaps);
87     prev_tick = act_time;
88     return cur_tick_ns;
89 }
90 
flush_cb(const char * buf)91 static void flush_cb(const char * buf)
92 {
93     printf("%s", buf);
94 }
95 
96 #endif
97