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_tick_signed_t)(vsf_systimer_get_tick() - due) >= 0);
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 return VSF_ERR_NONE;
187}
188
189VSF_CAL_SECTION(".text.vsf.kernel.teda")
191{
192 return vsf_systimer_get();
193}
194#endif // VSF_KERNEL_CFG_TIMER_MODE == VSF_KERNEL_CFG_TIMER_MODE_TICKLESS
195
196VSF_CAL_SECTION(".text.vsf.kernel.teda")
197static void __vsf_systimer_init(void)
198{
199#if VSF_KERNEL_CFG_TIMER_MODE == VSF_KERNEL_CFG_TIMER_MODE_TICKLESS
200 __vsf_eda.timer.processing = false;
201#endif
202 vsf_timq_init(&__vsf_eda.timer.timq);
203#if VSF_KERNEL_CFG_SUPPORT_CALLBACK_TIMER == ENABLED
204 vsf_callback_timq_init(&__vsf_eda.timer.callback_timq);
205 vsf_callback_timq_init(&__vsf_eda.timer.callback_timq_done);
206#endif
207
208#if VSF_SYSTIMER_CFG_IMPL_MODE != VSF_SYSTIMER_IMPL_NONE
210#endif
211}
212
213VSF_CAL_SECTION(".text.vsf.kernel.teda")
214static void __vsf_teda_timer_enqueue(vsf_teda_t *this_ptr, vsf_systimer_tick_t due)
215{
216 VSF_KERNEL_ASSERT((this_ptr != NULL) && !this_ptr->use_as__vsf_eda_t.flag.state.is_timed);
217 this_ptr->due = due;
218
219 vsf_timq_insert(&__vsf_eda.timer.timq, this_ptr);
220 this_ptr->use_as__vsf_eda_t.flag.state.is_timed = true;
221#if VSF_KERNEL_OPT_AVOID_UNNECESSARY_YIELD_EVT == ENABLED
222 vsf_protect_t origlevel = vsf_protect_int();
223 this_ptr->use_as__vsf_eda_t.is_evt_incoming = true;
224 vsf_unprotect_int(origlevel);
225#endif
226}
227
228#if VSF_KERNEL_CFG_SUPPORT_CALLBACK_TIMER == ENABLED
229VSF_CAL_SECTION(".text.vsf.kernel.vsf_callback_timer_init")
231{
232 timer->due = 0;
233}
234
235VSF_CAL_SECTION(".text.vsf.kernel.vsf_callback_timer_add_due")
237{
238 vsf_protect_t origlevel;
239# if VSF_CALLBACK_TIMER_CFG_SUPPORT_ISR == ENABLED
240 vsf_protect_t lock_status;
241# endif
242 bool is_to_update = false;
243 VSF_KERNEL_ASSERT(timer != NULL);
244 VSF_KERNEL_ASSERT(due != 0);
245
246 if (timer->due != 0) {
248 return VSF_ERR_FAIL;
249 }
250
251 origlevel = vsf_protect_sched();
252# if VSF_CALLBACK_TIMER_CFG_SUPPORT_ISR == ENABLED
253 lock_status = __vsf_callback_timer_protect();
254# endif
255 timer->due = due;
256 vsf_callback_timq_insert(&__vsf_eda.timer.callback_timq, timer);
257 if (NULL == timer->timer_node.prev) {
258 is_to_update = true;
259 }
260# if VSF_CALLBACK_TIMER_CFG_SUPPORT_ISR == ENABLED
261 __vsf_callback_timer_unprotect(lock_status);
262# endif
263 if (is_to_update) {
264 __vsf_teda_cancel_timer((vsf_teda_t *)&__vsf_eda.task);
265 __vsf_teda_set_timer_imp((vsf_teda_t *)&__vsf_eda.task, timer->due);
266 }
267 vsf_unprotect_sched(origlevel);
268 return VSF_ERR_NONE;
269}
270
271VSF_CAL_SECTION(".text.vsf.kernel.vsf_callback_timer_add")
273{
275}
276
277VSF_CAL_SECTION(".text.vsf.kernel.vsf_callback_timer_remove")
279{
280 vsf_protect_t lock_status;
281 VSF_KERNEL_ASSERT(timer != NULL);
282
283 lock_status = __vsf_callback_timer_protect();
284 if (timer->due != 0) {
285 timer->due = 0;
286 vsf_callback_timq_remove(&__vsf_eda.timer.callback_timq, timer);
287 }
288 __vsf_callback_timer_unprotect(lock_status);
289 return VSF_ERR_NONE;
290}
291
292# if VSF_CALLBACK_TIMER_CFG_SUPPORT_ISR == ENABLED
293VSF_CAL_SECTION(".text.vsf.kernel.vsf_callback_timer_add_due_isr")
295{
296 VSF_KERNEL_ASSERT(timer != NULL);
297 if (timer->due != 0) {
299 return VSF_ERR_FAIL;
300 }
301
302 timer->due = due;
303 return vsf_eda_post_evt_msg((vsf_eda_t *)&__vsf_eda.task, VSF_KERNEL_EVT_CALLBACK_TIMER_ADD, timer);
304}
305
306VSF_CAL_SECTION(".text.vsf.kernel.vsf_callback_timer_add_isr")
308{
310}
311
312VSF_CAL_SECTION(".text.vsf.kernel.vsf_callback_timer_remove_isr")
314{
315 return vsf_callback_timer_remove(timer);
316}
317# endif // VSF_CALLBACK_TIMER_CFG_SUPPORT_ISR
318#endif // VSF_KERNEL_CFG_SUPPORT_CALLBACK_TIMER
319
320VSF_CAL_SECTION(".text.vsf.kernel.vsf_systimer_get_duration")
322{
323 if (to_time >= from_time) {
324 return (vsf_systimer_tick_t)(to_time - from_time);
325 } else {
326 return (vsf_systimer_tick_t)(to_time + 0xFFFFFFFF - from_time);
327 }
328}
329
330VSF_CAL_SECTION(".text.vsf.kernel.vsf_systimer_get_elapsed")
332{
334}
335
336VSF_CAL_SECTION(".text.vsf.kernel.vsf_teda_start")
338{
339 VSF_KERNEL_ASSERT(this_ptr != NULL);
340 return vsf_eda_start(&(this_ptr->use_as__vsf_eda_t), cfg);
341}
342
343VSF_CAL_SECTION(".text.vsf.kernel.vsf_teda_set_due_ex")
345{
346 vsf_protect_t origlevel;
347 vsf_err_t err;
348
349 origlevel = vsf_protect_sched();
350 err = __vsf_teda_set_timer_imp(this_ptr, due);
351 vsf_unprotect_sched(origlevel);
352 return err;
353}
354
355VSF_CAL_SECTION(".text.vsf.kernel.vsf_teda_set_timer_ex")
357{
358 if (0 == tick) {
359 VSF_KERNEL_ASSERT(false);
361 }
362 return vsf_teda_set_due_ex(this_ptr, vsf_systimer_get_tick() + tick);
363}
364
365#if __IS_COMPILER_ARM_COMPILER_6__
366# pragma clang diagnostic push
367# pragma clang diagnostic ignored "-Wcast-align"
368#endif
369
370#if __IS_COMPILER_GCC__
371# pragma GCC diagnostic push
372# pragma GCC diagnostic ignored "-Wcast-align"
373#endif
374
375VSF_CAL_SECTION(".text.vsf.kernel.vsf_teda_set_timer")
377{
379 VSF_KERNEL_ASSERT(teda != NULL);
380 return vsf_teda_set_timer_ex(teda, tick);
381}
382
383#if __IS_COMPILER_ARM_COMPILER_6__
384# pragma clang diagnostic pop
385#endif
386
387#if __IS_COMPILER_GCC__
388# pragma GCC diagnostic pop
389#endif
390
391#if __IS_COMPILER_ARM_COMPILER_6__
392# pragma clang diagnostic push
393# pragma clang diagnostic ignored "-Wcast-align"
394#endif
395
396#if __IS_COMPILER_GCC__
397# pragma GCC diagnostic push
398# pragma GCC diagnostic ignored "-Wcast-align"
399#endif
400
401VSF_CAL_SECTION(".text.vsf.kernel.__vsf_teda_cancel_timer")
403{
404 vsf_protect_t lock_status;
405 this_ptr = (vsf_teda_t *)__vsf_eda_get_valid_eda((vsf_eda_t *)this_ptr);
406
407 VSF_KERNEL_ASSERT(this_ptr != NULL);
408
409 lock_status = vsf_protect_sched();
410 if (this_ptr->use_as__vsf_eda_t.flag.state.is_timed) {
411 vsf_timq_remove(&__vsf_eda.timer.timq, this_ptr);
412 this_ptr->use_as__vsf_eda_t.flag.state.is_timed = false;
413 }
414 this_ptr->use_as__vsf_eda_t.flag.state.is_to_set_due = false;
415 vsf_unprotect_sched(lock_status);
416 return VSF_ERR_NONE;
417}
418
419VSF_CAL_SECTION(".text.vsf.kernel.vsf_teda_cancel_timer")
421{
423#if VSF_KERNEL_CFG_ALLOW_KERNEL_BEING_PREEMPTED == ENABLED
425#endif
426 return VSF_ERR_NONE;
427}
428
429#if __IS_COMPILER_ARM_COMPILER_6__
430# pragma clang diagnostic pop
431#endif
432
433#if __IS_COMPILER_GCC__
434# pragma GCC diagnostic pop
435#endif
436
437#endif // VSF_KERNEL_CFG_EDA_SUPPORT_TIMER
438
439#if __IS_COMPILER_IAR__
441# pragma diag_warning=pe111
442#endif
443
444#endif // VSF_USE_KERNEL && __EDA_GADGET__
#define VSF_CAL_SECTION(__SEC_STR)
Definition __compiler.h:186
#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:73
void vsf_systimer_prio_set(vsf_arch_prio_t priority)
Definition cortex_m_generic.c:244
int vsf_get_interrupt_id(void)
Definition cortex_m_generic.c:429
vsf_systimer_tick_t vsf_systimer_get(void)
Definition linux_generic.c:402
void vsf_systimer_set_idle(void)
Definition linux_generic.c:398
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
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
int32_t vsf_systimer_tick_signed_t
Definition mcs51_generic.h:58
unsigned int uint_fast32_t
Definition stdint.h:27
Definition vsf_eda.h:758
uintalu_t vsf_protect_t
Definition vsf_arch_abstraction.h:53
#define vsf_protect_int
Definition vsf_arch_abstraction.h:369
#define vsf_unprotect_int
Definition vsf_arch_abstraction.h:370
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_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_KERNEL_EVT_CALLBACK_TIMER_ADD
Definition vsf_eda.h:627
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_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_EVT_TIMER
Definition vsf_eda.h:612
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
#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@f33b89f