RT-Thread RTOS 1.2.0
An open source embedded real-time operating system
载入中...
搜索中...
未找到
timer.c
浏览该文件的文档.
1/*
2 * Copyright (c) 2006-2024, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2006-03-12 Bernard first version
9 * 2006-04-29 Bernard implement thread timer
10 * 2006-06-04 Bernard implement rt_timer_control
11 * 2006-08-10 Bernard fix the periodic timer bug
12 * 2006-09-03 Bernard implement rt_timer_detach
13 * 2009-11-11 LiJin add soft timer
14 * 2010-05-12 Bernard fix the timer check bug.
15 * 2010-11-02 Charlie re-implement tick overflow issue
16 * 2012-12-15 Bernard fix the next timeout issue in soft timer
17 * 2014-07-12 Bernard does not lock scheduler when invoking soft-timer
18 * timeout function.
19 * 2021-08-15 supperthomas add the comment
20 * 2022-01-07 Gabriel Moving __on_rt_xxxxx_hook to timer.c
21 * 2022-04-19 Stanley Correct descriptions
22 * 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable
23 * 2024-01-25 Shell add RT_TIMER_FLAG_THREAD_TIMER for timer to sync with sched
24 * 2024-05-01 wdfk-prog The rt_timer_check and _soft_timer_check functions are merged
25 */
26
27#include <rtthread.h>
28#include <rthw.h>
29
30#define DBG_TAG "kernel.timer"
31#define DBG_LVL DBG_INFO
32#include <rtdbg.h>
33
34#ifndef RT_USING_TIMER_ALL_SOFT
35/* hard timer list */
36static rt_list_t _timer_list[RT_TIMER_SKIP_LIST_LEVEL];
37static struct rt_spinlock _htimer_lock;
38#endif
39
40#ifdef RT_USING_TIMER_SOFT
41
42#ifndef RT_TIMER_THREAD_STACK_SIZE
43#define RT_TIMER_THREAD_STACK_SIZE 512
44#endif /* RT_TIMER_THREAD_STACK_SIZE */
45
46#ifndef RT_TIMER_THREAD_PRIO
47#define RT_TIMER_THREAD_PRIO 0
48#endif /* RT_TIMER_THREAD_PRIO */
49
50/* soft timer list */
51static rt_list_t _soft_timer_list[RT_TIMER_SKIP_LIST_LEVEL];
52static struct rt_spinlock _stimer_lock;
53static struct rt_thread _timer_thread;
54static struct rt_semaphore _soft_timer_sem;
55rt_align(RT_ALIGN_SIZE)
56static rt_uint8_t _timer_thread_stack[RT_TIMER_THREAD_STACK_SIZE];
57#endif /* RT_USING_TIMER_SOFT */
58
59#if defined(RT_USING_HOOK) && defined(RT_HOOK_USING_FUNC_PTR)
60extern void (*rt_object_take_hook)(struct rt_object *object);
61extern void (*rt_object_put_hook)(struct rt_object *object);
62static void (*rt_timer_enter_hook)(struct rt_timer *timer);
63static void (*rt_timer_exit_hook)(struct rt_timer *timer);
64
68
70
77void rt_timer_enter_sethook(void (*hook)(struct rt_timer *timer))
78{
79 rt_timer_enter_hook = hook;
80}
81
88void rt_timer_exit_sethook(void (*hook)(struct rt_timer *timer))
89{
90 rt_timer_exit_hook = hook;
91}
92
94#endif /* RT_USING_HOOK */
95
96rt_inline struct rt_spinlock* _timerlock_idx(struct rt_timer *timer)
97{
98#ifdef RT_USING_TIMER_ALL_SOFT
99 return &_stimer_lock;
100#else
101#ifdef RT_USING_TIMER_SOFT
103 {
104 return &_stimer_lock;
105 }
106 else
107#endif /* RT_USING_TIMER_SOFT */
108 {
109 return &_htimer_lock;
110 }
111#endif
112}
113
131static void _timer_init(rt_timer_t timer,
132 void (*timeout)(void *parameter),
133 void *parameter,
134 rt_tick_t time,
135 rt_uint8_t flag)
136{
137 int i;
138
139#ifdef RT_USING_TIMER_ALL_SOFT
141#endif
142
143 /* set flag */
144 timer->parent.flag = flag;
145
146 /* set deactivated */
148
149 timer->timeout_func = timeout;
150 timer->parameter = parameter;
151
152 timer->timeout_tick = 0;
153 timer->init_tick = time;
154
155 /* initialize timer list */
156 for (i = 0; i < RT_TIMER_SKIP_LIST_LEVEL; i++)
157 {
158 rt_list_init(&(timer->row[i]));
159 }
160}
161
172static rt_err_t _timer_list_next_timeout(rt_list_t timer_list[], rt_tick_t *timeout_tick)
173{
174 struct rt_timer *timer;
175
176 if (!rt_list_isempty(&timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1]))
177 {
178 timer = rt_list_entry(timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1].next,
180 *timeout_tick = timer->timeout_tick;
181 return RT_EOK;
182 }
183 return -RT_ERROR;
184}
185
191rt_inline void _timer_remove(rt_timer_t timer)
192{
193 int i;
194
195 for (i = 0; i < RT_TIMER_SKIP_LIST_LEVEL; i++)
196 {
197 rt_list_remove(&timer->row[i]);
198 }
199}
200
201#if (DBG_LVL == DBG_LOG)
209static int _timer_count_height(struct rt_timer *timer)
210{
211 int i, cnt = 0;
212
213 for (i = 0; i < RT_TIMER_SKIP_LIST_LEVEL; i++)
214 {
215 if (!rt_list_isempty(&timer->row[i]))
216 cnt++;
217 }
218 return cnt;
219}
225void rt_timer_dump(rt_list_t timer_heads[])
226{
227 rt_list_t *list;
228
229 for (list = timer_heads[RT_TIMER_SKIP_LIST_LEVEL - 1].next;
230 list != &timer_heads[RT_TIMER_SKIP_LIST_LEVEL - 1];
231 list = list->next)
232 {
233 struct rt_timer *timer = rt_list_entry(list,
234 struct rt_timer,
236 rt_kprintf("%d", _timer_count_height(timer));
237 }
238 rt_kprintf("\n");
239}
240#endif /* (DBG_LVL == DBG_LOG) */
241
245
247
268 const char *name,
269 void (*timeout)(void *parameter),
270 void *parameter,
271 rt_tick_t time,
272 rt_uint8_t flag)
273{
274 /* parameter check */
275 RT_ASSERT(timer != RT_NULL);
276 RT_ASSERT(timeout != RT_NULL);
277 RT_ASSERT(time < RT_TICK_MAX / 2);
278
279 /* timer object initialization */
281
282 _timer_init(timer, timeout, parameter, time, flag);
283}
285
294{
295 rt_base_t level;
296 struct rt_spinlock *spinlock;
297
298 /* parameter check */
299 RT_ASSERT(timer != RT_NULL);
302
303 spinlock = _timerlock_idx(timer);
304 level = rt_spin_lock_irqsave(spinlock);
305
306 _timer_remove(timer);
307 /* stop timer */
309
310 rt_spin_unlock_irqrestore(spinlock, level);
311 rt_object_detach(&(timer->parent));
312
313 return RT_EOK;
314}
316
317#ifdef RT_USING_HEAP
346 void (*timeout)(void *parameter),
347 void *parameter,
348 rt_tick_t time,
349 rt_uint8_t flag)
350{
351 struct rt_timer *timer;
352
353 /* parameter check */
354 RT_ASSERT(timeout != RT_NULL);
355 RT_ASSERT(time < RT_TICK_MAX / 2);
356
357 /* allocate a object */
358 timer = (struct rt_timer *)rt_object_allocate(RT_Object_Class_Timer, name);
359 if (timer == RT_NULL)
360 {
361 return RT_NULL;
362 }
363
364 _timer_init(timer, timeout, parameter, time, flag);
365
366 return timer;
367}
369
378{
379 rt_base_t level;
380 struct rt_spinlock *spinlock;
381
382 /* parameter check */
383 RT_ASSERT(timer != RT_NULL);
386
387 spinlock = _timerlock_idx(timer);
388
389 level = rt_spin_lock_irqsave(spinlock);
390
391 _timer_remove(timer);
392 /* stop timer */
394 rt_spin_unlock_irqrestore(spinlock, level);
395 rt_object_delete(&(timer->parent));
396
397 return RT_EOK;
398}
400#endif /* RT_USING_HEAP */
401
409static rt_err_t _timer_start(rt_list_t *timer_list, rt_timer_t timer)
410{
411 unsigned int row_lvl;
413 unsigned int tst_nr;
414 static unsigned int random_nr;
415
416 /* remove timer from list */
417 _timer_remove(timer);
418 /* change status of timer */
420
421 RT_OBJECT_HOOK_CALL(rt_object_take_hook, (&(timer->parent)));
422
423 timer->timeout_tick = rt_tick_get() + timer->init_tick;
424
425 row_head[0] = &timer_list[0];
426 for (row_lvl = 0; row_lvl < RT_TIMER_SKIP_LIST_LEVEL; row_lvl++)
427 {
428 for (; row_head[row_lvl] != timer_list[row_lvl].prev;
429 row_head[row_lvl] = row_head[row_lvl]->next)
430 {
431 struct rt_timer *t;
432 rt_list_t *p = row_head[row_lvl]->next;
433
434 /* fix up the entry pointer */
435 t = rt_list_entry(p, struct rt_timer, row[row_lvl]);
436
437 /* If we have two timers that timeout at the same time, it's
438 * preferred that the timer inserted early get called early.
439 * So insert the new timer to the end the the some-timeout timer
440 * list.
441 */
442 if ((t->timeout_tick - timer->timeout_tick) == 0)
443 {
444 continue;
445 }
446 else if ((t->timeout_tick - timer->timeout_tick) < RT_TICK_MAX / 2)
447 {
448 break;
449 }
450 }
451 if (row_lvl != RT_TIMER_SKIP_LIST_LEVEL - 1)
452 row_head[row_lvl + 1] = row_head[row_lvl] + 1;
453 }
454
455 /* Interestingly, this super simple timer insert counter works very very
456 * well on distributing the list height uniformly. By means of "very very
457 * well", I mean it beats the randomness of timer->timeout_tick very easily
458 * (actually, the timeout_tick is not random and easy to be attacked). */
459 random_nr++;
460 tst_nr = random_nr;
461
463 &(timer->row[RT_TIMER_SKIP_LIST_LEVEL - 1]));
464 for (row_lvl = 2; row_lvl <= RT_TIMER_SKIP_LIST_LEVEL; row_lvl++)
465 {
466 if (!(tst_nr & RT_TIMER_SKIP_LIST_MASK))
468 &(timer->row[RT_TIMER_SKIP_LIST_LEVEL - row_lvl]));
469 else
470 break;
471 /* Shift over the bits we have tested. Works well with 1 bit and 2
472 * bits. */
473 tst_nr >>= (RT_TIMER_SKIP_LIST_MASK + 1) >> 1;
474 }
475
477
478 return RT_EOK;
479}
480
488static void _timer_check(rt_list_t *timer_list, struct rt_spinlock *lock)
489{
490 struct rt_timer *t;
491 rt_tick_t current_tick;
492 rt_base_t level;
493 rt_list_t list;
494
495 level = rt_spin_lock_irqsave(lock);
496
497 current_tick = rt_tick_get();
498
499 rt_list_init(&list);
500
501 while (!rt_list_isempty(&timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1]))
502 {
503 t = rt_list_entry(timer_list[RT_TIMER_SKIP_LIST_LEVEL - 1].next,
505
506 /* re-get tick */
507 current_tick = rt_tick_get();
508
509 /*
510 * It supposes that the new tick shall less than the half duration of
511 * tick max.
512 */
513 if ((current_tick - t->timeout_tick) < RT_TICK_MAX / 2)
514 {
515 RT_OBJECT_HOOK_CALL(rt_timer_enter_hook, (t));
516
517 /* remove timer from timer list firstly */
518 _timer_remove(t);
520 {
522 }
523
524 /* add timer to temporary list */
526
527 rt_spin_unlock_irqrestore(lock, level);
528
529 /* call timeout function */
530 t->timeout_func(t->parameter);
531
532 RT_OBJECT_HOOK_CALL(rt_timer_exit_hook, (t));
533
534 level = rt_spin_lock_irqsave(lock);
535
536 /* Check whether the timer object is detached or started again */
537 if (rt_list_isempty(&list))
538 {
539 continue;
540 }
544 {
545 /* start it */
547 _timer_start(timer_list, t);
548 }
549 }
550 else break;
551 }
552 rt_spin_unlock_irqrestore(lock, level);
553}
554
563{
565 int is_thread_timer = 0;
566 struct rt_spinlock *spinlock;
567 rt_list_t *timer_list;
568 rt_base_t level;
569 rt_err_t err;
570
571 /* parameter check */
572 RT_ASSERT(timer != RT_NULL);
574
575#ifdef RT_USING_TIMER_ALL_SOFT
576 timer_list = _soft_timer_list;
577 spinlock = &_stimer_lock;
578#else
579#ifdef RT_USING_TIMER_SOFT
581 {
582 timer_list = _soft_timer_list;
583 spinlock = &_stimer_lock;
584 }
585 else
586#endif /* RT_USING_TIMER_SOFT */
587 {
588 timer_list = _timer_list;
589 spinlock = &_htimer_lock;
590 }
591#endif
592
594 {
595 rt_thread_t thread;
596 is_thread_timer = 1;
597 rt_sched_lock(&slvl);
598
599 thread = rt_container_of(timer, struct rt_thread, thread_timer);
602 }
603
604 level = rt_spin_lock_irqsave(spinlock);
605
606 err = _timer_start(timer_list, timer);
607
608 rt_spin_unlock_irqrestore(spinlock, level);
609
610 if (is_thread_timer)
611 {
612 rt_sched_unlock(slvl);
613 }
614
615 return err;
616}
618
627{
628 rt_base_t level;
629 struct rt_spinlock *spinlock;
630
631 /* timer check */
632 RT_ASSERT(timer != RT_NULL);
634
635 spinlock = _timerlock_idx(timer);
636
637 level = rt_spin_lock_irqsave(spinlock);
638
639 if (!(timer->parent.flag & RT_TIMER_FLAG_ACTIVATED))
640 {
641 rt_spin_unlock_irqrestore(spinlock, level);
642 return -RT_ERROR;
643 }
644 RT_OBJECT_HOOK_CALL(rt_object_put_hook, (&(timer->parent)));
645
646 _timer_remove(timer);
647 /* change status */
649
650 rt_spin_unlock_irqrestore(spinlock, level);
651
652 return RT_EOK;
653}
655
665rt_err_t rt_timer_control(rt_timer_t timer, int cmd, void *arg)
666{
667 struct rt_spinlock *spinlock;
668 rt_base_t level;
669
670 /* parameter check */
671 RT_ASSERT(timer != RT_NULL);
673
674 spinlock = _timerlock_idx(timer);
675
676 level = rt_spin_lock_irqsave(spinlock);
677 switch (cmd)
678 {
680 *(rt_tick_t *)arg = timer->init_tick;
681 break;
682
684 RT_ASSERT((*(rt_tick_t *)arg) < RT_TICK_MAX / 2);
686 {
687 _timer_remove(timer);
689 }
690 timer->init_tick = *(rt_tick_t *)arg;
691 break;
692
695 break;
696
699 break;
700
703 {
704 /*timer is start and run*/
706 }
707 else
708 {
709 /*timer is stop*/
711 }
712 break;
713
715 *(rt_tick_t *)arg = timer->timeout_tick;
716 break;
718 *(void **)arg = (void *)timer->timeout_func;
719 break;
720
722 timer->timeout_func = (void (*)(void*))arg;
723 break;
724
726 *(void **)arg = timer->parameter;
727 break;
728
730 timer->parameter = arg;
731 break;
732
733 default:
734 break;
735 }
736 rt_spin_unlock_irqrestore(spinlock, level);
737
738 return RT_EOK;
739}
741
749{
751
752#ifdef RT_USING_SMP
753 /* Running on core 0 only */
754 if (rt_cpu_get_id() != 0)
755 {
756 return;
757 }
758#endif
759
760#ifdef RT_USING_TIMER_SOFT
761 rt_err_t ret = RT_ERROR;
762 rt_tick_t next_timeout;
763
764 ret = _timer_list_next_timeout(_soft_timer_list, &next_timeout);
765 if ((ret == RT_EOK) && (next_timeout <= rt_tick_get()))
766 {
767 rt_sem_release(&_soft_timer_sem);
768 }
769#endif
770#ifndef RT_USING_TIMER_ALL_SOFT
771 _timer_check(_timer_list, &_htimer_lock);
772#endif
773}
774
781{
782 rt_base_t level;
783 rt_tick_t htimer_next_timeout = RT_TICK_MAX, stimer_next_timeout = RT_TICK_MAX;
784
785#ifndef RT_USING_TIMER_ALL_SOFT
786 level = rt_spin_lock_irqsave(&_htimer_lock);
787 _timer_list_next_timeout(_timer_list, &htimer_next_timeout);
788 rt_spin_unlock_irqrestore(&_htimer_lock, level);
789#endif
790
791#ifdef RT_USING_TIMER_SOFT
792 level = rt_spin_lock_irqsave(&_stimer_lock);
793 _timer_list_next_timeout(_soft_timer_list, &stimer_next_timeout);
794 rt_spin_unlock_irqrestore(&_stimer_lock, level);
795#endif
796
797 return htimer_next_timeout < stimer_next_timeout ? htimer_next_timeout : stimer_next_timeout;
798}
799
800#ifdef RT_USING_TIMER_SOFT
806static void _timer_thread_entry(void *parameter)
807{
808 RT_UNUSED(parameter);
809
810 while (1)
811 {
812 _timer_check(_soft_timer_list, &_stimer_lock); /* check software timer */
813 rt_sem_take(&_soft_timer_sem, RT_WAITING_FOREVER);
814 }
815}
816#endif /* RT_USING_TIMER_SOFT */
817
824{
825#ifndef RT_USING_TIMER_ALL_SOFT
826 rt_size_t i;
827
828 for (i = 0; i < sizeof(_timer_list) / sizeof(_timer_list[0]); i++)
829 {
830 rt_list_init(_timer_list + i);
831 }
832
833 rt_spin_lock_init(&_htimer_lock);
834#endif
835}
836
843{
844#ifdef RT_USING_TIMER_SOFT
845 int i;
846
847 for (i = 0;
848 i < sizeof(_soft_timer_list) / sizeof(_soft_timer_list[0]);
849 i++)
850 {
851 rt_list_init(_soft_timer_list + i);
852 }
853 rt_spin_lock_init(&_stimer_lock);
854 rt_sem_init(&_soft_timer_sem, "stimer", 0, RT_IPC_FLAG_PRIO);
855 rt_sem_control(&_soft_timer_sem, RT_IPC_CMD_SET_VLIMIT, (void*)1);
856 /* start software timer thread */
857 rt_thread_init(&_timer_thread,
858 "timer",
859 _timer_thread_entry,
860 RT_NULL,
861 &_timer_thread_stack[0],
862 sizeof(_timer_thread_stack),
863 RT_TIMER_THREAD_PRIO,
864 10);
865
866 /* startup */
867 rt_thread_startup(&_timer_thread);
868#endif /* RT_USING_TIMER_SOFT */
869}
870
rt_err_t rt_timer_detach(rt_timer_t timer)
This function will detach a timer from timer management.
#define RT_TIMER_CTRL_GET_REMAIN_TIME
#define RT_TIMER_FLAG_SOFT_TIMER
rt_err_t rt_timer_control(rt_timer_t timer, int cmd, void *arg)
This function will get or set some options of the timer
#define RT_TIMER_FLAG_ACTIVATED
void rt_timer_exit_sethook(void(*hook)(struct rt_timer *timer))
#define RT_TIMER_CTRL_GET_TIME
#define RT_TIMER_CTRL_SET_PERIODIC
#define RT_TIMER_CTRL_GET_STATE
struct rt_timer * rt_timer_t
#define RT_TIMER_CTRL_SET_FUNC
void rt_timer_check(void)
This function will check timer list, if a timeout event happens, the corresponding timeout function w...
rt_err_t rt_timer_start(rt_timer_t timer)
This function will start the timer
#define RT_TIMER_CTRL_GET_PARM
#define RT_TIMER_CTRL_SET_ONESHOT
rt_tick_t rt_timer_next_timeout_tick(void)
This function will return the next timeout tick in the system.
#define RT_TIMER_FLAG_PERIODIC
void rt_timer_enter_sethook(void(*hook)(struct rt_timer *timer))
void rt_timer_init(rt_timer_t timer, const char *name, void(*timeout)(void *parameter), void *parameter, rt_tick_t time, rt_uint8_t flag)
This function will initialize a timer normally this function is used to initialize a static timer obj...
rt_tick_t rt_tick_get(void)
This function will return current tick from operating system startup.
定义 clock.c:69
#define RT_TIMER_CTRL_SET_TIME
rt_timer_t rt_timer_create(const char *name, void(*timeout)(void *parameter), void *parameter, rt_tick_t time, rt_uint8_t flag)
This function will create a timer
rt_err_t rt_timer_stop(rt_timer_t timer)
This function will stop the timer
#define RT_TIMER_CTRL_SET_PARM
#define RT_TIMER_CTRL_GET_FUNC
#define RT_TIMER_FLAG_THREAD_TIMER
#define RT_TIMER_SKIP_LIST_MASK
#define RT_TIMER_FLAG_DEACTIVATED
rt_err_t rt_timer_delete(rt_timer_t timer)
This function will delete a timer and release timer memory
#define RT_TIMER_SKIP_LIST_LEVEL
#define RT_IPC_FLAG_PRIO
rt_base_t rt_spin_lock_irqsave(struct rt_spinlock *lock)
This function will disable the local interrupt and then lock the spinlock, will lock the thread sched...
#define RT_WAITING_FOREVER
void rt_spin_lock_init(struct rt_spinlock *lock)
Initialize a static spinlock object.
#define RT_IPC_CMD_SET_VLIMIT
void rt_spin_unlock_irqrestore(struct rt_spinlock *lock, rt_base_t level)
This function will unlock the spinlock and then restore current cpu interrupt status,...
rt_weak rt_uint8_t rt_interrupt_get_nest(void)
This function will return the nest of interrupt.
定义 irq.c:136
void rt_object_delete(rt_object_t object)
This function will delete an object and release object memory.
void rt_object_init(struct rt_object *object, enum rt_object_class_type type, const char *name)
This function will initialize an object and add it to object system management.
rt_bool_t rt_object_is_systemobject(rt_object_t object)
This function will judge the object is system object or not.
#define RT_OBJECT_HOOK_CALL(func, argv)
rt_object_t rt_object_allocate(enum rt_object_class_type type, const char *name)
This function will allocate an object from object system.
rt_uint8_t rt_object_get_type(rt_object_t object)
This function will return the type of object without RT_Object_Class_Static flag.
void rt_object_detach(rt_object_t object)
This function will detach a static object from object system, and the memory of static object is not ...
@ RT_Object_Class_Timer
@ RT_Object_Class_Thread
rt_inline void rt_list_remove(rt_list_t *n)
remove node from list.
rt_inline int rt_list_isempty(const rt_list_t *l)
tests whether a list is empty
#define rt_kprintf(...)
#define rt_list_entry(node, type, member)
get the struct for this entry
#define RT_ASSERT(EX)
rt_inline void rt_list_init(rt_list_t *l)
initialize a list
rt_inline void rt_list_insert_after(rt_list_t *l, rt_list_t *n)
insert a node after a list
#define rt_container_of(ptr, type, member)
void rt_system_timer_init(void)
This function will initialize system timer
void rt_system_timer_thread_init(void)
This function will initialize system timer thread
rt_err_t rt_thread_startup(rt_thread_t thread)
This function will start a thread and put it to system ready queue.
rt_err_t rt_thread_init(struct rt_thread *thread, const char *name, void(*entry)(void *parameter), void *parameter, void *stack_start, rt_uint32_t stack_size, rt_uint8_t priority, rt_uint32_t tick)
This function will initialize a thread. It's used to initialize a static thread object.
struct rt_thread * rt_thread_t
rt_err_t rt_sem_init(rt_sem_t sem, const char *name, rt_uint32_t value, rt_uint8_t flag)
This function will initialize a static semaphore object.
定义 ipc.c:376
rt_err_t rt_sem_control(rt_sem_t sem, int cmd, void *arg)
This function will set some extra attributions of a semaphore object.
定义 ipc.c:759
rt_err_t rt_sem_take(rt_sem_t sem, rt_int32_t time)
定义 ipc.c:644
rt_err_t rt_sem_release(rt_sem_t sem)
This function will release a semaphore. If there is thread suspended on the semaphore,...
定义 ipc.c:695
rt_align(RT_ALIGN_SIZE)
This function sets a hook function to idle thread loop. When the system performs idle loop,...
定义 idle.c:48
#define RT_UNUSED(x)
#define RT_TICK_MAX
#define RTM_EXPORT(symbol)
定义 rtm.h:33
rt_ubase_t rt_sched_lock_level_t
#define rt_cpu_get_id()
rt_int32_t rt_base_t
rt_base_t rt_err_t
unsigned char rt_uint8_t
rt_uint32_t rt_tick_t
rt_ubase_t rt_size_t
struct rt_list_node rt_list_t
unsigned int rt_uint32_t
#define RT_FALSE
#define RT_NULL
rt_err_t rt_sched_thread_timer_start(struct rt_thread *thread)
rt_err_t rt_sched_lock(rt_sched_lock_level_t *plvl)
rt_err_t rt_sched_unlock(rt_sched_lock_level_t level)
struct rt_list_node * next
struct rt_list_node * prev
rt_uint8_t flag
struct rt_object parent
struct rt_object parent
rt_timer_func_t timeout_func
void * parameter
rt_list_t row[RT_TIMER_SKIP_LIST_LEVEL]
rt_tick_t init_tick
rt_tick_t timeout_tick
rt_inline void _timer_remove(rt_timer_t timer)
Remove the timer
rt_inline struct rt_spinlock * _timerlock_idx(struct rt_timer *timer)
定义 timer.c:96
void rt_timer_dump(rt_list_t timer_heads[])
dump the all timer information