17
17
* 2014-07-12 Bernard does not lock scheduler when invoking soft-timer
18
18
* timeout function.
19
19
* 2021-08-15 supperthomas add the comment
20
+ * 2021-12-20 THEWON reload timeout_tick with absolute base value
20
21
*/
21
22
22
23
#include <rtthread.h>
@@ -27,9 +28,6 @@ static rt_list_t _timer_list[RT_TIMER_SKIP_LIST_LEVEL];
27
28
28
29
#ifdef RT_USING_TIMER_SOFT
29
30
30
- #define RT_SOFT_TIMER_IDLE 1
31
- #define RT_SOFT_TIMER_BUSY 0
32
-
33
31
#ifndef RT_TIMER_THREAD_STACK_SIZE
34
32
#define RT_TIMER_THREAD_STACK_SIZE 512
35
33
#endif /* RT_TIMER_THREAD_STACK_SIZE */
@@ -38,8 +36,6 @@ static rt_list_t _timer_list[RT_TIMER_SKIP_LIST_LEVEL];
38
36
#define RT_TIMER_THREAD_PRIO 0
39
37
#endif /* RT_TIMER_THREAD_PRIO */
40
38
41
- /* soft timer status */
42
- static rt_uint8_t _soft_timer_status = RT_SOFT_TIMER_IDLE ;
43
39
/* soft timer list */
44
40
static rt_list_t _soft_timer_list [RT_TIMER_SKIP_LIST_LEVEL ];
45
41
static struct rt_thread _timer_thread ;
@@ -355,28 +351,19 @@ rt_err_t rt_timer_delete(rt_timer_t timer)
355
351
RTM_EXPORT (rt_timer_delete );
356
352
#endif /* RT_USING_HEAP */
357
353
358
- /**
359
- * @brief This function will start the timer
360
- *
361
- * @param timer the timer to be started
362
- *
363
- * @return the operation status, RT_EOK on OK, -RT_ERROR on error
364
- */
365
- rt_err_t rt_timer_start (rt_timer_t timer )
354
+ static rt_err_t _timer_start (rt_timer_t timer , rt_tick_t current_tick )
366
355
{
367
356
unsigned int row_lvl ;
368
357
rt_list_t * timer_list ;
369
358
register rt_base_t level ;
370
- register rt_bool_t need_schedule ;
371
359
rt_list_t * row_head [RT_TIMER_SKIP_LIST_LEVEL ];
372
360
unsigned int tst_nr ;
373
361
static unsigned int random_nr ;
374
362
375
363
/* timer check */
376
364
RT_ASSERT (timer != RT_NULL );
377
365
RT_ASSERT (rt_object_get_type (& timer -> parent ) == RT_Object_Class_Timer );
378
-
379
- need_schedule = RT_FALSE ;
366
+ RT_ASSERT (timer -> init_tick < RT_TICK_MAX / 2 );
380
367
381
368
/* stop timer firstly */
382
369
level = rt_hw_interrupt_disable ();
@@ -391,8 +378,7 @@ rt_err_t rt_timer_start(rt_timer_t timer)
391
378
* get timeout tick,
392
379
* the max timeout tick shall not great than RT_TICK_MAX/2
393
380
*/
394
- RT_ASSERT (timer -> init_tick < RT_TICK_MAX / 2 );
395
- timer -> timeout_tick = rt_tick_get () + timer -> init_tick ;
381
+ timer -> timeout_tick = current_tick + timer -> init_tick ;
396
382
397
383
#ifdef RT_USING_TIMER_SOFT
398
384
if (timer -> parent .flag & RT_TIMER_FLAG_SOFT_TIMER )
@@ -469,21 +455,36 @@ rt_err_t rt_timer_start(rt_timer_t timer)
469
455
{
470
456
/* resume timer thread to check soft timer */
471
457
rt_thread_resume (& _timer_thread );
472
- need_schedule = RT_TRUE ;
458
+ /* enable interrupt */
459
+ rt_hw_interrupt_enable (level );
460
+
461
+ rt_schedule ();
462
+
463
+ return RT_EOK ;
473
464
}
474
465
}
475
466
#endif /* RT_USING_TIMER_SOFT */
476
467
477
468
/* enable interrupt */
478
469
rt_hw_interrupt_enable (level );
479
470
480
- if (need_schedule )
481
- {
482
- rt_schedule ();
483
- }
484
-
485
471
return RT_EOK ;
486
472
}
473
+
474
+ /**
475
+ * @brief This function will start the timer
476
+ *
477
+ * @param timer the timer to be started
478
+ *
479
+ * @return the operation status, RT_EOK on OK, -RT_ERROR on error
480
+ */
481
+ rt_err_t rt_timer_start (rt_timer_t timer )
482
+ {
483
+ rt_tick_t current_tick ;
484
+
485
+ current_tick = rt_tick_get ();
486
+ return _timer_start (timer , current_tick );
487
+ }
487
488
RTM_EXPORT (rt_timer_start );
488
489
489
490
/**
@@ -589,9 +590,6 @@ void rt_timer_check(void)
589
590
struct rt_timer * t ;
590
591
rt_tick_t current_tick ;
591
592
register rt_base_t level ;
592
- rt_list_t list ;
593
-
594
- rt_list_init (& list );
595
593
596
594
RT_DEBUG_LOG (RT_DEBUG_TIMER , ("timer check enter\n" ));
597
595
@@ -611,16 +609,22 @@ void rt_timer_check(void)
611
609
*/
612
610
if ((current_tick - t -> timeout_tick ) < RT_TICK_MAX / 2 )
613
611
{
614
- RT_OBJECT_HOOK_CALL (rt_timer_enter_hook , (t ));
615
-
616
612
/* remove timer from timer list firstly */
617
613
_timer_remove (t );
618
- if (!(t -> parent .flag & RT_TIMER_FLAG_PERIODIC ))
614
+
615
+ if ((t -> parent .flag & RT_TIMER_FLAG_PERIODIC ) &&
616
+ (t -> parent .flag & RT_TIMER_FLAG_ACTIVATED ))
617
+ {
618
+ /* start it */
619
+ _timer_start (t , t -> timeout_tick );
620
+ }
621
+ else
619
622
{
620
623
t -> parent .flag &= ~RT_TIMER_FLAG_ACTIVATED ;
621
624
}
622
- /* add timer to temporary list */
623
- rt_list_insert_after (& list , & (t -> row [RT_TIMER_SKIP_LIST_LEVEL - 1 ]));
625
+
626
+ RT_OBJECT_HOOK_CALL (rt_timer_enter_hook , (t ));
627
+
624
628
/* call timeout function */
625
629
t -> timeout_func (t -> parameter );
626
630
@@ -629,20 +633,6 @@ void rt_timer_check(void)
629
633
630
634
RT_OBJECT_HOOK_CALL (rt_timer_exit_hook , (t ));
631
635
RT_DEBUG_LOG (RT_DEBUG_TIMER , ("current tick: %d\n" , current_tick ));
632
-
633
- /* Check whether the timer object is detached or started again */
634
- if (rt_list_isempty (& list ))
635
- {
636
- continue ;
637
- }
638
- rt_list_remove (& (t -> row [RT_TIMER_SKIP_LIST_LEVEL - 1 ]));
639
- if ((t -> parent .flag & RT_TIMER_FLAG_PERIODIC ) &&
640
- (t -> parent .flag & RT_TIMER_FLAG_ACTIVATED ))
641
- {
642
- /* start it */
643
- t -> parent .flag &= ~RT_TIMER_FLAG_ACTIVATED ;
644
- rt_timer_start (t );
645
- }
646
636
}
647
637
else break ;
648
638
}
@@ -673,12 +663,11 @@ void rt_soft_timer_check(void)
673
663
rt_tick_t current_tick ;
674
664
struct rt_timer * t ;
675
665
register rt_base_t level ;
676
- rt_list_t list ;
677
-
678
- rt_list_init (& list );
679
666
680
667
RT_DEBUG_LOG (RT_DEBUG_TIMER , ("software timer check enter\n" ));
681
668
669
+ current_tick = rt_tick_get ();
670
+
682
671
/* disable interrupt */
683
672
level = rt_hw_interrupt_disable ();
684
673
@@ -687,29 +676,30 @@ void rt_soft_timer_check(void)
687
676
t = rt_list_entry (_soft_timer_list [RT_TIMER_SKIP_LIST_LEVEL - 1 ].next ,
688
677
struct rt_timer , row [RT_TIMER_SKIP_LIST_LEVEL - 1 ]);
689
678
690
- current_tick = rt_tick_get ();
691
-
692
679
/*
693
680
* It supposes that the new tick shall less than the half duration of
694
681
* tick max.
695
682
*/
696
683
if ((current_tick - t -> timeout_tick ) < RT_TICK_MAX / 2 )
697
684
{
698
- RT_OBJECT_HOOK_CALL (rt_timer_enter_hook , (t ));
699
-
700
685
/* remove timer from timer list firstly */
701
686
_timer_remove (t );
702
- if (!(t -> parent .flag & RT_TIMER_FLAG_PERIODIC ))
687
+ if ((t -> parent .flag & RT_TIMER_FLAG_PERIODIC )) & &
688
+ (t -> parent .flag & RT_TIMER_FLAG_ACTIVATED )
689
+ {
690
+ /* start it */
691
+ _timer_start (t , t -> timeout_tick );
692
+ }
693
+ else
703
694
{
704
695
t -> parent .flag &= ~RT_TIMER_FLAG_ACTIVATED ;
705
696
}
706
- /* add timer to temporary list */
707
- rt_list_insert_after (& list , & (t -> row [RT_TIMER_SKIP_LIST_LEVEL - 1 ]));
708
697
709
- _soft_timer_status = RT_SOFT_TIMER_BUSY ;
710
698
/* enable interrupt */
711
699
rt_hw_interrupt_enable (level );
712
700
701
+ RT_OBJECT_HOOK_CALL (rt_timer_enter_hook , (t ));
702
+
713
703
/* call timeout function */
714
704
t -> timeout_func (t -> parameter );
715
705
@@ -718,20 +708,6 @@ void rt_soft_timer_check(void)
718
708
719
709
/* disable interrupt */
720
710
level = rt_hw_interrupt_disable ();
721
-
722
- _soft_timer_status = RT_SOFT_TIMER_IDLE ;
723
- /* Check whether the timer object is detached or started again */
724
- if (rt_list_isempty (& list ))
725
- {
726
- continue ;
727
- }
728
- rt_list_remove (& (t -> row [RT_TIMER_SKIP_LIST_LEVEL - 1 ]));
729
- if ((t -> parent .flag & RT_TIMER_FLAG_PERIODIC ) &&
730
- (t -> parent .flag & RT_TIMER_FLAG_ACTIVATED ))
731
- {
732
- /* start it */
733
- t -> parent .flag &= ~RT_TIMER_FLAG_ACTIVATED ;
734
- rt_timer_start (t );
735
711
}
736
712
}
737
713
else break ; /* not check anymore */
0 commit comments