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
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")
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
245 if (timer->due != 0) {
247 return VSF_ERR_FAIL;
248 }
249
250 origlevel = vsf_protect_sched();
251# if VSF_CALLBACK_TIMER_CFG_SUPPORT_ISR == ENABLED
252 lock_status = __vsf_callback_timer_protect();
253# endif
254 timer->due = tick + vsf_systimer_get_tick();
255 vsf_callback_timq_insert(&__vsf_eda.timer.callback_timq, timer);
256 if (NULL == timer->timer_node.prev) {
257 is_to_update = true;
258 }
259# if VSF_CALLBACK_TIMER_CFG_SUPPORT_ISR == ENABLED
260 __vsf_callback_timer_unprotect(lock_status);
261# endif
262 if (is_to_update) {
263 __vsf_teda_cancel_timer((vsf_teda_t *)&__vsf_eda.task);
264 __vsf_teda_set_timer_imp((vsf_teda_t *)&__vsf_eda.task, timer->due);
265 }
266 vsf_unprotect_sched(origlevel);
267 return VSF_ERR_NONE;
268}
269
270VSF_CAL_SECTION(".text.vsf.kernel.vsf_callback_timer_remove")
272{
273 vsf_protect_t lock_status;
274 VSF_KERNEL_ASSERT(timer != NULL);
275
276 lock_status = __vsf_callback_timer_protect();
277 if (timer->due != 0) {
278 timer->due = 0;
279 vsf_callback_timq_remove(&__vsf_eda.timer.callback_timq, timer);
280 }
281 __vsf_callback_timer_unprotect(lock_status);
282 return VSF_ERR_NONE;
283}
284
285# if VSF_CALLBACK_TIMER_CFG_SUPPORT_ISR == ENABLED
286VSF_CAL_SECTION(".text.vsf.kernel.vsf_callback_timer_add_isr")
288{
289 VSF_KERNEL_ASSERT(timer != NULL);
290 if (timer->due != 0) {
292 return VSF_ERR_FAIL;
293 }
294
295 timer->due = tick + vsf_systimer_get_tick();
296 return vsf_eda_post_evt_msg((vsf_eda_t *)&__vsf_eda.task, VSF_KERNEL_EVT_CALLBACK_TIMER_ADD, timer);
297}
298
299VSF_CAL_SECTION(".text.vsf.kernel.vsf_callback_timer_remove_isr")
301{
302 return vsf_callback_timer_remove(timer);
303}
304# endif // VSF_CALLBACK_TIMER_CFG_SUPPORT_ISR
305#endif // VSF_KERNEL_CFG_SUPPORT_CALLBACK_TIMER
306
307VSF_CAL_SECTION(".text.vsf.kernel.vsf_systimer_get_duration")
309{
310 if (to_time >= from_time) {
311 return (vsf_systimer_tick_t)(to_time - from_time);
312 } else {
313 return (vsf_systimer_tick_t)(to_time + 0xFFFFFFFF - from_time);
314 }
315}
316
317VSF_CAL_SECTION(".text.vsf.kernel.vsf_systimer_get_elapsed")
319{
321}
322
323VSF_CAL_SECTION(".text.vsf.kernel.vsf_teda_start")
325{
326 VSF_KERNEL_ASSERT(this_ptr != NULL);
327 return vsf_eda_start(&(this_ptr->use_as__vsf_eda_t), cfg);
328}
329
330VSF_CAL_SECTION(".text.vsf.kernel.vsf_teda_set_timer_ex")
332{
333 vsf_protect_t origlevel;
334 vsf_err_t err;
335
336 if (0 == tick) {
337 VSF_KERNEL_ASSERT(false);
339 }
340 origlevel = vsf_protect_sched();
341 err = __vsf_teda_set_timer_imp(this_ptr, vsf_systimer_get_tick() + tick);
342 vsf_unprotect_sched(origlevel);
343 return err;
344}
345
346#if __IS_COMPILER_ARM_COMPILER_6__
347# pragma clang diagnostic push
348# pragma clang diagnostic ignored "-Wcast-align"
349#endif
350
351#if __IS_COMPILER_GCC__
352# pragma GCC diagnostic push
353# pragma GCC diagnostic ignored "-Wcast-align"
354#endif
355
356VSF_CAL_SECTION(".text.vsf.kernel.vsf_teda_set_timer")
358{
360 VSF_KERNEL_ASSERT(teda != NULL);
361 return vsf_teda_set_timer_ex(teda, tick);
362}
363
364#if __IS_COMPILER_ARM_COMPILER_6__
365# pragma clang diagnostic pop
366#endif
367
368#if __IS_COMPILER_GCC__
369# pragma GCC diagnostic pop
370#endif
371
372#if __IS_COMPILER_ARM_COMPILER_6__
373# pragma clang diagnostic push
374# pragma clang diagnostic ignored "-Wcast-align"
375#endif
376
377#if __IS_COMPILER_GCC__
378# pragma GCC diagnostic push
379# pragma GCC diagnostic ignored "-Wcast-align"
380#endif
381
382VSF_CAL_SECTION(".text.vsf.kernel.__vsf_teda_cancel_timer")
384{
385 vsf_protect_t lock_status;
386 this_ptr = (vsf_teda_t *)__vsf_eda_get_valid_eda((vsf_eda_t *)this_ptr);
387
388 VSF_KERNEL_ASSERT(this_ptr != NULL);
389
390 lock_status = vsf_protect_sched();
391 if (this_ptr->use_as__vsf_eda_t.flag.state.is_timed) {
392 vsf_timq_remove(&__vsf_eda.timer.timq, this_ptr);
393 this_ptr->use_as__vsf_eda_t.flag.state.is_timed = false;
394 }
395 vsf_unprotect_sched(lock_status);
396 return VSF_ERR_NONE;
397}
398
399VSF_CAL_SECTION(".text.vsf.kernel.vsf_teda_cancel_timer")
401{
403#if VSF_KERNEL_CFG_ALLOW_KERNEL_BEING_PREEMPTED == ENABLED
405#endif
406 return VSF_ERR_NONE;
407}
408
409#if __IS_COMPILER_ARM_COMPILER_6__
410# pragma clang diagnostic pop
411#endif
412
413#if __IS_COMPILER_GCC__
414# pragma GCC diagnostic pop
415#endif
416
417#endif // VSF_KERNEL_CFG_EDA_SUPPORT_TIMER
418
419#if __IS_COMPILER_IAR__
421# pragma diag_warning=pe111
422#endif
423
424#endif // VSF_USE_KERNEL && __EDA_GADGET__
#define VSF_CAL_SECTION(__SEC)
Definition __compiler.h:181
#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:848
Definition vsf_eda.h:766
Definition vsf_eda.h:834
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:185
int vsf_get_interrupt_id(void)
Definition cortex_m_generic.c:370
#define NULL
Definition stddef.h:52
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
int32_t vsf_systimer_tick_signed_t
Definition mcs51_generic.h:58
unsigned int uint_fast32_t
Definition stdint.h:27
void vsf_systimer_evthandler(vsf_systimer_tick_t tick)
Definition sthal.c:114
Definition vsf_eda.h:755
uintalu_t vsf_protect_t
Definition vsf_arch_abstraction.h:53
#define vsf_protect_int
Definition vsf_arch_abstraction.h:275
#define vsf_unprotect_int
Definition vsf_arch_abstraction.h:276
vsf_err_t vsf_eda_post_evt(vsf_eda_t *pthis, vsf_evt_t evt)
Definition vsf_eda.c:923
vsf_err_t vsf_eda_post_evt_msg(vsf_eda_t *pthis, vsf_evt_t evt, void *msg)
Definition vsf_eda.c:957
vsf_eda_t * vsf_eda_get_cur(void)
Definition vsf_eda.c:410
vsf_err_t vsf_eda_start(vsf_eda_t *pthis, vsf_eda_cfg_t *cfg_ptr)
Definition vsf_eda.c:826
void vsf_kernel_err_report(enum vsf_kernel_error_t err)
Definition vsf_eda.c:403
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:1086
@ VSF_EVT_TIMER
Definition vsf_eda.h:612
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_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_KERNEL_EVT_CALLBACK_TIMER_ADD
Definition vsf_eda.h:627
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:254
#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