VSF Documented
vsf_eda_timer.c
Go to the documentation of this file.
1/*****************************************************************************
2 * Copyright(C)2009-2022 by VSF Team *
3 * *
4 * Licensed under the Apache License, Version 2.0 (the "License"); *
5 * you may not use this file except in compliance with the License. *
6 * You may obtain a copy of the License at *
7 * *
8 * http://www.apache.org/licenses/LICENSE-2.0 *
9 * *
10 * Unless required by applicable law or agreed to in writing, software *
11 * distributed under the License is distributed on an "AS IS" BASIS, *
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
13 * See the License for the specific language governing permissions and *
14 * limitations under the License. *
15 * *
16 ****************************************************************************/
17
18
19/*============================ INCLUDES ======================================*/
20
22
23#if VSF_USE_KERNEL == ENABLED && defined(__EDA_GADGET__)
24
25#if __IS_COMPILER_IAR__
27# pragma diag_suppress=pe111
28#endif
29
30/*============================ MACROS ========================================*/
31/*============================ MACROFIED FUNCTIONS ===========================*/
32
33#if VSF_CALLBACK_TIMER_CFG_SUPPORT_ISR == ENABLED
34# define __vsf_callback_timer_protect vsf_protect(interrupt)
35# define __vsf_callback_timer_unprotect vsf_unprotect(interrupt)
36#else
37# define __vsf_callback_timer_protect vsf_protect(scheduler)
38# define __vsf_callback_timer_unprotect vsf_unprotect(scheduler)
39#endif
40
41/*============================ TYPES =========================================*/
42/*============================ GLOBAL VARIABLES ==============================*/
43/*============================ LOCAL VARIABLES ===============================*/
44/*============================ PROTOTYPES ====================================*/
45
46#if VSF_KERNEL_CFG_EDA_SUPPORT_TIMER == ENABLED
47# if VSF_SYSTIMER_CFG_IMPL_MODE != VSF_SYSTIMER_IMPL_NONE
48# if (VSF_KERNEL_CFG_TIMER_MODE == VSF_KERNEL_CFG_TIMER_MODE_TICKLESS) \
49 && (VSF_SYSTIMER_CFG_IMPL_MODE == VSF_SYSTIMER_IMPL_TICK_MODE)
50# error systimer is in tick mode while tickless mode is required on kernel
51# endif
52# if (VSF_KERNEL_CFG_TIMER_MODE == VSF_KERNEL_CFG_TIMER_MODE_TICK) \
53 && (VSF_SYSTIMER_CFG_IMPL_MODE != VSF_SYSTIMER_IMPL_TICK_MODE)
54# warning systimer is not in tick mode while tick mode is required on kernel,\
55 ignore this warning if your arch does not support tick mode systimer,\
56 or set VSF_SYSTIMER_CFG_IMPL_MODE to VSF_SYSTIMER_IMPL_TICK_MODE\
57 for better optimization.
58# endif
59# endif
60
61# if VSF_KERNEL_CFG_TIMER_MODE == VSF_KERNEL_CFG_TIMER_MODE_TICKLESS \
62 && (VSF_SYSTIMER_CFG_IMPL_MODE == VSF_SYSTIMER_IMPL_NONE)
64extern vsf_err_t vsf_systimer_start(void);
70# endif
71
72VSF_CAL_SECTION(".text.vsf.kernel.teda")
73static void __vsf_teda_timer_enqueue(vsf_teda_t *this_ptr, vsf_systimer_tick_t due);
74
77#endif
78
79/*============================ IMPLEMENTATION ================================*/
80
81#if VSF_KERNEL_CFG_EDA_SUPPORT_TIMER == ENABLED
82#if VSF_KERNEL_CFG_TIMER_MODE == VSF_KERNEL_CFG_TIMER_MODE_TICKLESS
83
84static void __vsf_systimer_wakeup(void)
85{
86 if (!__vsf_eda.timer.processing) {
87 __vsf_eda.timer.processing = true;
88 if (vsf_eda_post_evt((vsf_eda_t *)&__vsf_eda.task, VSF_EVT_TIMER)) {
89 __vsf_eda.timer.processing = false;
90 }
91 }
92}
93
94#if VSF_SYSTIMER_CFG_IMPL_MODE != VSF_SYSTIMER_IMPL_NONE
95static void __vsf_systimer_update(bool force)
96{
97 vsf_teda_t *teda;
98
99 // TODO: need protect here?
100 vsf_timq_peek(&__vsf_eda.timer.timq, teda);
101 if (NULL == teda) {
103 } else if (force || (teda->due != __vsf_eda.timer.pre_tick)) {
104 __vsf_eda.timer.pre_tick = teda->due;
105 if (!vsf_systimer_set(teda->due)) {
106 __vsf_systimer_wakeup();
107 }
108 }
109}
110#else
111static void __vsf_systimer_update(bool force)
112{
113
114}
115#endif
116
117VSF_CAL_SECTION(".text.vsf.kernel.teda")
118static bool __vsf_systimer_is_due(vsf_systimer_tick_t due)
119{
120 return vsf_systimer_is_due(due);
121}
122
123VSF_CAL_SECTION(".text.vsf.kernel.teda")
124static void __vsf_systimer_start(void)
125{
126 vsf_systimer_prio_set(__vsf_eda.timer.arch_prio);
127
129}
130
131// DO NOT add section on vsf_systimer_evthandler, it's a weak function in arch
132void vsf_systimer_evthandler(vsf_systimer_tick_t tick)
133{
134#if VSF_KERNEL_CFG_TRACE == ENABLED
135 if (!__vsf_eda.timer.is_isr_info_sent) {
136 __vsf_eda.timer.is_isr_info_sent = true;
137 vsf_kernel_trace_isr_info(vsf_get_interrupt_id(), "systimer");
138 }
139 vsf_kernel_trace_isr_enter(vsf_get_interrupt_id());
140#endif
141
142 VSF_UNUSED_PARAM(tick);
143 __vsf_systimer_wakeup();
144
145#if VSF_KERNEL_CFG_TRACE == ENABLED
146 vsf_kernel_trace_isr_leave(vsf_get_interrupt_id());
147#endif
148}
149
150VSF_CAL_SECTION(".text.vsf.kernel.teda")
151static vsf_err_t __vsf_teda_set_timer_imp(vsf_teda_t *this_ptr, vsf_systimer_tick_t due)
152{
153 __vsf_teda_timer_enqueue(this_ptr, due);
154 __vsf_systimer_update(false);
155 return VSF_ERR_NONE;
156}
157
158VSF_CAL_SECTION(".text.vsf.kernel.teda")
160{
161 return vsf_systimer_get();
162}
163#else // VSF_KERNEL_CFG_TIMER_MODE == VSF_KERNEL_CFG_TIMER_MODE_TICKLESS
164VSF_CAL_SECTION(".text.vsf.kernel.teda")
165static void __vsf_systimer_start(void)
166{
167 // in tick timer mode, user will initialize timer and call vsf_systimer_on_tick
168}
169
170VSF_CAL_SECTION(".text.vsf.kernel.teda")
171static bool __vsf_systimer_is_due(vsf_systimer_tick_t due)
172{
173 return vsf_systimer_is_due(due);
174}
175
176VSF_CAL_SECTION(".text.vsf.kernel.teda")
177void vsf_systimer_on_tick(void)
178{
179 vsf_eda_post_evt((vsf_eda_t *)&__vsf_eda.task, VSF_EVT_TIMER);
180}
181
182VSF_CAL_SECTION(".text.vsf.kernel.teda")
183static vsf_err_t __vsf_teda_set_timer_imp(vsf_teda_t *this_ptr, vsf_systimer_tick_t due)
184{
185 __vsf_teda_timer_enqueue(this_ptr, due);
186 // reprogram the systimer for the new earliest due(compare match or
187 // reload value, impl dependent), so the first timeout can fire an
188 // interrupt - mandatory on COMP_TIMER targets(no periodic round
189 // would fire otherwise), and avoids a one-round latency on
190 // NORMAL_TIMER targets
191 __vsf_systimer_update(false);
192 return VSF_ERR_NONE;
193}
194
195VSF_CAL_SECTION(".text.vsf.kernel.teda")
197{
198 return vsf_systimer_get();
199}
200#endif // VSF_KERNEL_CFG_TIMER_MODE == VSF_KERNEL_CFG_TIMER_MODE_TICKLESS
201
202VSF_CAL_SECTION(".text.vsf.kernel.teda")
203static void __vsf_systimer_init(void)
204{
205#if VSF_KERNEL_CFG_TIMER_MODE == VSF_KERNEL_CFG_TIMER_MODE_TICKLESS
206 __vsf_eda.timer.processing = false;
207#endif
208 vsf_timq_init(&__vsf_eda.timer.timq);
209#if VSF_KERNEL_CFG_SUPPORT_CALLBACK_TIMER == ENABLED
210 vsf_callback_timq_init(&__vsf_eda.timer.callback_timq);
211 vsf_callback_timq_init(&__vsf_eda.timer.callback_timq_done);
212#endif
213
214#if VSF_SYSTIMER_CFG_IMPL_MODE != VSF_SYSTIMER_IMPL_NONE
216#endif
217}
218
219VSF_CAL_SECTION(".text.vsf.kernel.teda")
220static void __vsf_teda_timer_enqueue(vsf_teda_t *this_ptr, vsf_systimer_tick_t due)
221{
222 VSF_KERNEL_ASSERT((this_ptr != NULL) && !this_ptr->use_as__vsf_eda_t.flag.state.is_timed);
223 this_ptr->due = due;
224
225 vsf_timq_insert(&__vsf_eda.timer.timq, this_ptr);
226 this_ptr->use_as__vsf_eda_t.flag.state.is_timed = true;
227#if VSF_KERNEL_OPT_AVOID_UNNECESSARY_YIELD_EVT == ENABLED
228 vsf_protect_t origlevel = vsf_protect_int();
229 this_ptr->use_as__vsf_eda_t.is_evt_incoming = true;
230 vsf_unprotect_int(origlevel);
231#endif
232}
233
234#if VSF_KERNEL_CFG_SUPPORT_CALLBACK_TIMER == ENABLED
235VSF_CAL_SECTION(".text.vsf.kernel.vsf_callback_timer_init")
237{
238 timer->due = 0;
239}
240
241VSF_CAL_SECTION(".text.vsf.kernel.vsf_callback_timer_add_due")
243{
244 vsf_protect_t origlevel;
245# if VSF_CALLBACK_TIMER_CFG_SUPPORT_ISR == ENABLED
246 vsf_protect_t lock_status;
247# endif
248 bool is_to_update = false;
249 VSF_KERNEL_ASSERT(timer != NULL);
250 VSF_KERNEL_ASSERT(due != 0);
251
252 if (timer->due != 0) {
254 return VSF_ERR_FAIL;
255 }
256
257 origlevel = vsf_protect_sched();
258# if VSF_CALLBACK_TIMER_CFG_SUPPORT_ISR == ENABLED
259 lock_status = __vsf_callback_timer_protect();
260# endif
261 timer->due = due;
262 vsf_callback_timq_insert(&__vsf_eda.timer.callback_timq, timer);
263 if (NULL == timer->timer_node.prev) {
264 is_to_update = true;
265 }
266# if VSF_CALLBACK_TIMER_CFG_SUPPORT_ISR == ENABLED
267 __vsf_callback_timer_unprotect(lock_status);
268# endif
269 if (is_to_update) {
270 __vsf_teda_cancel_timer((vsf_teda_t *)&__vsf_eda.task);
271 __vsf_teda_set_timer_imp((vsf_teda_t *)&__vsf_eda.task, timer->due);
272 }
273 vsf_unprotect_sched(origlevel);
274 return VSF_ERR_NONE;
275}
276
277VSF_CAL_SECTION(".text.vsf.kernel.vsf_callback_timer_add")
279{
281}
282
283VSF_CAL_SECTION(".text.vsf.kernel.vsf_callback_timer_remove")
285{
286 vsf_protect_t lock_status;
287 VSF_KERNEL_ASSERT(timer != NULL);
288
289 lock_status = __vsf_callback_timer_protect();
290 if (timer->due != 0) {
291 timer->due = 0;
292 vsf_callback_timq_remove(&__vsf_eda.timer.callback_timq, timer);
293 }
294 __vsf_callback_timer_unprotect(lock_status);
295 return VSF_ERR_NONE;
296}
297
298# if VSF_CALLBACK_TIMER_CFG_SUPPORT_ISR == ENABLED
299VSF_CAL_SECTION(".text.vsf.kernel.vsf_callback_timer_add_due_isr")
301{
302 VSF_KERNEL_ASSERT(timer != NULL);
303 if (timer->due != 0) {
305 return VSF_ERR_FAIL;
306 }
307
308 timer->due = due;
309 return vsf_eda_post_evt_msg((vsf_eda_t *)&__vsf_eda.task, VSF_KERNEL_EVT_CALLBACK_TIMER_ADD, timer);
310}
311
312VSF_CAL_SECTION(".text.vsf.kernel.vsf_callback_timer_add_isr")
314{
316}
317
318VSF_CAL_SECTION(".text.vsf.kernel.vsf_callback_timer_remove_isr")
320{
321 return vsf_callback_timer_remove(timer);
322}
323# endif // VSF_CALLBACK_TIMER_CFG_SUPPORT_ISR
324#endif // VSF_KERNEL_CFG_SUPPORT_CALLBACK_TIMER
325
326VSF_CAL_SECTION(".text.vsf.kernel.vsf_systimer_get_duration")
328{
329 return (vsf_systimer_tick_t)(to_time - from_time);
330}
331
332VSF_CAL_SECTION(".text.vsf.kernel.vsf_systimer_get_elapsed")
334{
336}
337
338VSF_CAL_SECTION(".text.vsf.kernel.vsf_teda_start")
340{
341 VSF_KERNEL_ASSERT(this_ptr != NULL);
342 return vsf_eda_start(&(this_ptr->use_as__vsf_eda_t), cfg);
343}
344
345VSF_CAL_SECTION(".text.vsf.kernel.vsf_teda_set_due_ex")
347{
348 vsf_protect_t origlevel;
349 vsf_err_t err;
350
351 origlevel = vsf_protect_sched();
352 err = __vsf_teda_set_timer_imp(this_ptr, due);
353 vsf_unprotect_sched(origlevel);
354 return err;
355}
356
357VSF_CAL_SECTION(".text.vsf.kernel.vsf_teda_set_timer_ex")
359{
360 if (0 == tick) {
361 VSF_KERNEL_ASSERT(false);
363 }
364 return vsf_teda_set_due_ex(this_ptr, vsf_systimer_get_tick() + tick);
365}
366
367#if __IS_COMPILER_ARM_COMPILER_6__
368# pragma clang diagnostic push
369# pragma clang diagnostic ignored "-Wcast-align"
370#endif
371
372#if __IS_COMPILER_GCC__
373# pragma GCC diagnostic push
374# pragma GCC diagnostic ignored "-Wcast-align"
375#endif
376
377VSF_CAL_SECTION(".text.vsf.kernel.vsf_teda_set_timer")
379{
381 VSF_KERNEL_ASSERT(teda != NULL);
382 return vsf_teda_set_timer_ex(teda, tick);
383}
384
385#if __IS_COMPILER_ARM_COMPILER_6__
386# pragma clang diagnostic pop
387#endif
388
389#if __IS_COMPILER_GCC__
390# pragma GCC diagnostic pop
391#endif
392
393#if __IS_COMPILER_ARM_COMPILER_6__
394# pragma clang diagnostic push
395# pragma clang diagnostic ignored "-Wcast-align"
396#endif
397
398#if __IS_COMPILER_GCC__
399# pragma GCC diagnostic push
400# pragma GCC diagnostic ignored "-Wcast-align"
401#endif
402
403VSF_CAL_SECTION(".text.vsf.kernel.__vsf_teda_cancel_timer")
405{
406 vsf_protect_t lock_status;
407 this_ptr = (vsf_teda_t *)__vsf_eda_get_valid_eda((vsf_eda_t *)this_ptr);
408
409 VSF_KERNEL_ASSERT(this_ptr != NULL);
410
411 lock_status = vsf_protect_sched();
412 if (this_ptr->use_as__vsf_eda_t.flag.state.is_timed) {
413 vsf_timq_remove(&__vsf_eda.timer.timq, this_ptr);
414 this_ptr->use_as__vsf_eda_t.flag.state.is_timed = false;
415 }
416#if (VSF_KERNEL_CFG_SUPPORT_SYNC == ENABLED) && defined(__VSF_OS_CFG_EVTQ_LIST)
417 this_ptr->use_as__vsf_eda_t.flag.state.is_to_set_due = false;
418#endif
419 vsf_unprotect_sched(lock_status);
420 return VSF_ERR_NONE;
421}
422
423VSF_CAL_SECTION(".text.vsf.kernel.vsf_teda_cancel_timer")
425{
427#if VSF_KERNEL_CFG_ALLOW_KERNEL_BEING_PREEMPTED == ENABLED
429#endif
430 return VSF_ERR_NONE;
431}
432
433#if __IS_COMPILER_ARM_COMPILER_6__
434# pragma clang diagnostic pop
435#endif
436
437#if __IS_COMPILER_GCC__
438# pragma GCC diagnostic pop
439#endif
440
441#endif // VSF_KERNEL_CFG_EDA_SUPPORT_TIMER
442
443#if __IS_COMPILER_IAR__
445# pragma diag_warning=pe111
446#endif
447
448#endif // VSF_USE_KERNEL && __EDA_GADGET__
#define VSF_CAL_SECTION(__SEC_STR)
Definition __compiler.h:189
#define VSF_UNUSED_PARAM(__VAL)
Definition __type.h:190
vsf_err_t
Definition __type.h:42
@ VSF_ERR_NONE
none error
Definition __type.h:44
@ VSF_ERR_NOT_AVAILABLE
service not available
Definition __type.h:47
@ VSF_ERR_FAIL
failed
Definition __type.h:51
Definition vsf_eda.h:851
Definition vsf_eda.h:769
Definition vsf_eda.h:837
uint64_t vsf_systimer_tick_t
Definition cortex_a_generic.h:70
void vsf_systimer_prio_set(vsf_arch_prio_t priority)
Definition cortex_m_generic.c:249
int vsf_get_interrupt_id(void)
Definition cortex_m_generic.c:434
void vsf_systimer_set_idle(void)
Definition linux_generic.c:398
bool vsf_systimer_is_due(vsf_systimer_tick_t due)
Definition linux_generic.c:430
vsf_systimer_tick_t vsf_systimer_ms_to_tick(uint_fast32_t time_ms)
Definition linux_generic.c:440
vsf_systimer_tick_t vsf_systimer_us_to_tick(uint_fast32_t time_us)
Definition linux_generic.c:435
vsf_systimer_tick_t vsf_systimer_tick_to_ms(vsf_systimer_tick_t tick)
Definition linux_generic.c:450
vsf_err_t vsf_systimer_start(void)
Definition linux_generic.c:390
bool vsf_systimer_set(vsf_systimer_tick_t due)
Definition linux_generic.c:409
#define NULL
Definition lvgl.h:26
unsigned int uint_fast32_t
Definition stdint.h:27
Definition vsf_eda.h:758
uintalu_t vsf_protect_t
Definition vsf_arch_abstraction.h:60
#define vsf_protect_int
Definition vsf_arch_abstraction.h:376
#define vsf_unprotect_int
Definition vsf_arch_abstraction.h:377
vsf_err_t vsf_eda_post_evt(vsf_eda_t *pthis, vsf_evt_t evt)
Definition vsf_eda.c:935
vsf_err_t vsf_eda_post_evt_msg(vsf_eda_t *pthis, vsf_evt_t evt, void *msg)
Definition vsf_eda.c:969
vsf_eda_t * vsf_eda_get_cur(void)
Definition vsf_eda.c:416
vsf_err_t vsf_eda_start(vsf_eda_t *pthis, vsf_eda_cfg_t *cfg_ptr)
Definition vsf_eda.c:835
void vsf_kernel_err_report(enum vsf_kernel_error_t err)
Definition vsf_eda.c:409
void vsf_systimer_on_tick(void)
vsf_err_t vsf_teda_cancel_timer(void)
vsf_err_t vsf_callback_timer_add_isr(vsf_callback_timer_t *timer, vsf_systimer_tick_t tick)
vsf_err_t vsf_callback_timer_remove_isr(vsf_callback_timer_t *timer)
vsf_err_t vsf_teda_set_timer(vsf_systimer_tick_t tick)
@ VSF_KERNEL_EVT_CALLBACK_TIMER_ADD
Definition vsf_eda.h:627
@ VSF_KERNEL_ERR_INVALID_USAGE
Definition vsf_eda.h:1089
void vsf_callback_timer_init(vsf_callback_timer_t *timer)
vsf_systimer_tick_t vsf_systimer_get_elapsed(vsf_systimer_tick_t from_time)
vsf_systimer_tick_t vsf_systimer_get_tick(void)
vsf_err_t vsf_callback_timer_add_due(vsf_callback_timer_t *timer, vsf_systimer_tick_t due)
vsf_err_t vsf_teda_set_timer_ex(vsf_teda_t *pthis, vsf_systimer_tick_t tick)
vsf_err_t vsf_callback_timer_add(vsf_callback_timer_t *timer, vsf_systimer_tick_t tick)
vsf_err_t vsf_teda_start(vsf_teda_t *pthis, vsf_eda_cfg_t *cfg)
vsf_err_t vsf_teda_set_due_ex(vsf_teda_t *this_ptr, vsf_systimer_tick_t due)
@ VSF_EVT_TIMER
Definition vsf_eda.h:612
vsf_err_t vsf_callback_timer_add_due_isr(vsf_callback_timer_t *timer, vsf_systimer_tick_t due)
vsf_systimer_tick_t vsf_systimer_get_duration(vsf_systimer_tick_t from_time, vsf_systimer_tick_t to_time)
vsf_err_t __vsf_teda_cancel_timer(vsf_teda_t *pthis)
vsf_err_t vsf_callback_timer_remove(vsf_callback_timer_t *timer)
void vsf_evtq_clean_evt(vsf_evt_t evt)
Definition vsf_evtq_list.c:256
#define VSF_KERNEL_ASSERT
Definition vsf_kernel_cfg.h:32
#define vsf_protect_sched()
Definition vsf_os.h:88
#define vsf_unprotect_sched(__prot)
Definition vsf_os.h:89
vsf_systimer_tick_t vsf_systimer_get(void)
Definition linux_generic.c:402
vsf_systimer_tick_t vsf_systimer_tick_to_us(vsf_systimer_tick_t tick)
Definition linux_generic.c:445
vsf_err_t vsf_systimer_init(void)
initialise SysTick to generate a system timer !
Definition linux_generic.c:365
#define vsf_callback_timq_remove(__queue, __timer)
Definition vsf_timq_dlist.h:76
#define vsf_timq_peek(__queue, __teda)
Definition vsf_timq_dlist.h:47
#define vsf_timq_init(__queue)
Definition vsf_timq_dlist.h:32
#define vsf_timq_insert(__queue, __teda)
Definition vsf_timq_dlist.h:34
#define vsf_callback_timq_init(__queue)
Definition vsf_timq_dlist.h:61
#define vsf_timq_remove(__queue, __teda)
Definition vsf_timq_dlist.h:41
#define vsf_callback_timq_insert(__queue, __timer)
Definition vsf_timq_dlist.h:69
Generated from commit: vsfteam/vsf@4327394