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 )
@@ -464,26 +450,40 @@ rt_err_t rt_timer_start(rt_timer_t timer)
464
450
if (timer -> parent .flag & RT_TIMER_FLAG_SOFT_TIMER )
465
451
{
466
452
/* check whether timer thread is ready */
467
- if ((_soft_timer_status == RT_SOFT_TIMER_IDLE ) &&
468
- ((_timer_thread .stat & RT_THREAD_STAT_MASK ) == RT_THREAD_SUSPEND ))
453
+ if ((_timer_thread .stat & RT_THREAD_STAT_MASK ) == RT_THREAD_SUSPEND )
469
454
{
470
455
/* resume timer thread to check soft timer */
471
456
rt_thread_resume (& _timer_thread );
472
- need_schedule = RT_TRUE ;
457
+ /* enable interrupt */
458
+ rt_hw_interrupt_enable (level );
459
+
460
+ rt_schedule ();
461
+
462
+ return RT_EOK ;
473
463
}
474
464
}
475
465
#endif /* RT_USING_TIMER_SOFT */
476
466
477
467
/* enable interrupt */
478
468
rt_hw_interrupt_enable (level );
479
469
480
- if (need_schedule )
481
- {
482
- rt_schedule ();
483
- }
484
-
485
470
return RT_EOK ;
486
471
}
472
+
473
+ /**
474
+ * @brief This function will start the timer
475
+ *
476
+ * @param timer the timer to be started
477
+ *
478
+ * @return the operation status, RT_EOK on OK, -RT_ERROR on error
479
+ */
480
+ rt_err_t rt_timer_start (rt_timer_t timer )
481
+ {
482
+ rt_tick_t current_tick ;
483
+
484
+ current_tick = rt_tick_get ();
485
+ return _timer_start (timer , current_tick );
486
+ }
487
487
RTM_EXPORT (rt_timer_start );
488
488
489
489
/**
@@ -589,9 +589,6 @@ void rt_timer_check(void)
589
589
struct rt_timer * t ;
590
590
rt_tick_t current_tick ;
591
591
register rt_base_t level ;
592
- rt_list_t list ;
593
-
594
- rt_list_init (& list );
595
592
596
593
RT_DEBUG_LOG (RT_DEBUG_TIMER , ("timer check enter\n" ));
597
594
@@ -611,16 +608,22 @@ void rt_timer_check(void)
611
608
*/
612
609
if ((current_tick - t -> timeout_tick ) < RT_TICK_MAX / 2 )
613
610
{
614
- RT_OBJECT_HOOK_CALL (rt_timer_enter_hook , (t ));
615
-
616
611
/* remove timer from timer list firstly */
617
612
_timer_remove (t );
618
- if (!(t -> parent .flag & RT_TIMER_FLAG_PERIODIC ))
613
+
614
+ if ((t -> parent .flag & RT_TIMER_FLAG_PERIODIC ) &&
615
+ (t -> parent .flag & RT_TIMER_FLAG_ACTIVATED ))
616
+ {
617
+ /* start it */
618
+ _timer_start (t , t -> timeout_tick );
619
+ }
620
+ else
619
621
{
620
622
t -> parent .flag &= ~RT_TIMER_FLAG_ACTIVATED ;
621
623
}
622
- /* add timer to temporary list */
623
- rt_list_insert_after (& list , & (t -> row [RT_TIMER_SKIP_LIST_LEVEL - 1 ]));
624
+
625
+ RT_OBJECT_HOOK_CALL (rt_timer_enter_hook , (t ));
626
+
624
627
/* call timeout function */
625
628
t -> timeout_func (t -> parameter );
626
629
@@ -629,20 +632,6 @@ void rt_timer_check(void)
629
632
630
633
RT_OBJECT_HOOK_CALL (rt_timer_exit_hook , (t ));
631
634
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
635
}
647
636
else break ;
648
637
}
@@ -673,12 +662,11 @@ void rt_soft_timer_check(void)
673
662
rt_tick_t current_tick ;
674
663
struct rt_timer * t ;
675
664
register rt_base_t level ;
676
- rt_list_t list ;
677
-
678
- rt_list_init (& list );
679
665
680
666
RT_DEBUG_LOG (RT_DEBUG_TIMER , ("software timer check enter\n" ));
681
667
668
+ current_tick = rt_tick_get ();
669
+
682
670
/* disable interrupt */
683
671
level = rt_hw_interrupt_disable ();
684
672
@@ -687,29 +675,30 @@ void rt_soft_timer_check(void)
687
675
t = rt_list_entry (_soft_timer_list [RT_TIMER_SKIP_LIST_LEVEL - 1 ].next ,
688
676
struct rt_timer , row [RT_TIMER_SKIP_LIST_LEVEL - 1 ]);
689
677
690
- current_tick = rt_tick_get ();
691
-
692
678
/*
693
679
* It supposes that the new tick shall less than the half duration of
694
680
* tick max.
695
681
*/
696
682
if ((current_tick - t -> timeout_tick ) < RT_TICK_MAX / 2 )
697
683
{
698
- RT_OBJECT_HOOK_CALL (rt_timer_enter_hook , (t ));
699
-
700
684
/* remove timer from timer list firstly */
701
685
_timer_remove (t );
702
- if (!(t -> parent .flag & RT_TIMER_FLAG_PERIODIC ))
686
+ if ((t -> parent .flag & RT_TIMER_FLAG_PERIODIC ) &&
687
+ (t -> parent .flag & RT_TIMER_FLAG_ACTIVATED ))
688
+ {
689
+ /* start it */
690
+ _timer_start (t , t -> timeout_tick );
691
+ }
692
+ else
703
693
{
704
694
t -> parent .flag &= ~RT_TIMER_FLAG_ACTIVATED ;
705
695
}
706
- /* add timer to temporary list */
707
- rt_list_insert_after (& list , & (t -> row [RT_TIMER_SKIP_LIST_LEVEL - 1 ]));
708
696
709
- _soft_timer_status = RT_SOFT_TIMER_BUSY ;
710
697
/* enable interrupt */
711
698
rt_hw_interrupt_enable (level );
712
699
700
+ RT_OBJECT_HOOK_CALL (rt_timer_enter_hook , (t ));
701
+
713
702
/* call timeout function */
714
703
t -> timeout_func (t -> parameter );
715
704
@@ -718,21 +707,6 @@ void rt_soft_timer_check(void)
718
707
719
708
/* disable interrupt */
720
709
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
- }
736
710
}
737
711
else break ; /* not check anymore */
738
712
}
0 commit comments