1 /*
2  * Copyright (c) 2020 Intel Corporation.
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <ksched.h>
9 
10 #include "footprint.h"
11 
12 #define DURATION	100
13 #define PERIOD		50
14 #define EXPIRE_TIMES	4
15 
16 struct timer_data {
17 	uint32_t expire_cnt;
18 	uint32_t stop_cnt;
19 	int64_t timestamp;
20 };
21 
22 static struct k_timer timer0;
23 static FP_BMEM struct timer_data tdata;
24 
init_timer_data(void)25 static void init_timer_data(void)
26 {
27 	tdata.expire_cnt = 0;
28 	tdata.stop_cnt = 0;
29 }
30 
timer_init(struct k_timer * timer,k_timer_expiry_t expiry_fn,k_timer_stop_t stop_fn)31 static void timer_init(struct k_timer *timer, k_timer_expiry_t expiry_fn,
32 		       k_timer_stop_t stop_fn)
33 {
34 	k_object_access_grant(timer, k_current_get());
35 	k_timer_init(timer, expiry_fn, stop_fn);
36 }
37 
timer_stop(struct k_timer * timer)38 static void timer_stop(struct k_timer *timer)
39 {
40 	tdata.stop_cnt++;
41 }
42 
timer_expire(struct k_timer * timer)43 static void timer_expire(struct k_timer *timer)
44 {
45 	tdata.expire_cnt++;
46 }
47 
busy_wait_ms(int32_t ms)48 static void busy_wait_ms(int32_t ms)
49 {
50 	k_busy_wait(ms*1000);
51 }
52 
thread_fn(void * arg1,void * arg2,void * arg3)53 static void thread_fn(void *arg1, void *arg2, void *arg3)
54 {
55 	ARG_UNUSED(arg1);
56 	ARG_UNUSED(arg2);
57 	ARG_UNUSED(arg3);
58 
59 	init_timer_data();
60 	k_timer_start(&timer0, K_MSEC(DURATION), K_MSEC(PERIOD));
61 	tdata.timestamp = k_uptime_get();
62 	busy_wait_ms(DURATION + PERIOD * EXPIRE_TIMES + PERIOD / 2);
63 	k_timer_stop(&timer0);
64 
65 	init_timer_data();
66 	k_timer_start(&timer0, K_MSEC(DURATION), K_MSEC(PERIOD));
67 
68 	/* Call the k_timer_start() again to make sure that
69 	 * the initial timeout request gets cancelled and new
70 	 * one will get added.
71 	 */
72 	busy_wait_ms(DURATION / 2);
73 	k_timer_start(&timer0, K_MSEC(DURATION), K_MSEC(PERIOD));
74 	tdata.timestamp = k_uptime_get();
75 	busy_wait_ms(DURATION + PERIOD * EXPIRE_TIMES + PERIOD / 2);
76 
77 	k_timer_stop(&timer0);
78 }
79 
run_timer(void)80 void run_timer(void)
81 {
82 	k_tid_t tid;
83 
84 	timer_init(&timer0, timer_expire, timer_stop);
85 
86 	tid = k_thread_create(&my_thread, my_stack_area, STACK_SIZE,
87 			      thread_fn, NULL, NULL, NULL,
88 			      0, 0, K_NO_WAIT);
89 
90 	k_thread_join(tid, K_FOREVER);
91 
92 #ifdef CONFIG_USERSPACE
93 	tid = k_thread_create(&my_thread, my_stack_area, STACK_SIZE,
94 			      thread_fn, NULL, NULL, NULL,
95 			      0, K_USER, K_NO_WAIT);
96 
97 	k_mem_domain_add_thread(&footprint_mem_domain, tid);
98 
99 	k_thread_access_grant(tid, &timer0);
100 	k_thread_start(tid);
101 
102 	k_thread_join(tid, K_FOREVER);
103 
104 #endif
105 }
106