@@ -92,7 +92,9 @@ uint8_t check_timetag3(TimeTag* timetag, uint32_t now, uint32_t period)
9292 */
9393uint64_t systime_now_us (void )
9494{
95+ uint32_t systick_us_before = 0 ;
9596 uint32_t systick_us = 0 ;
97+ uint64_t time_now_ms_before ;
9698 uint64_t time_now_ms ;
9799 uint64_t now_us ;
98100 static uint64_t monotonic_us = 0 ;
@@ -102,25 +104,28 @@ uint64_t systime_now_us(void)
102104 return 0 ;
103105 }
104106
107+ time_now_ms_before = __systime .msPeriod ;
108+ rt_device_read (systick_dev , SYSTICK_RD_TIME_US , & systick_us_before , sizeof (uint32_t ));
109+
105110 level = rt_hw_interrupt_disable ();
106- rt_device_read (systick_dev , SYSTICK_RD_TIME_US , & systick_us , sizeof (uint32_t ));
107- /* atomic read */
111+
108112 time_now_ms = __systime .msPeriod ;
113+ rt_device_read (systick_dev , SYSTICK_RD_TIME_US , & systick_us , sizeof (uint32_t ));
114+
115+ rt_hw_interrupt_enable (level );
109116
110117 now_us = time_now_ms * 1000ULL + systick_us ;
111118
112119 /* Fix the race condition where the SysTick hardware timer has wrapped around */
113- if (now_us < monotonic_us ) {
120+ if (systick_us < systick_us_before && time_now_ms == time_now_ms_before ) {
114121 now_us += (uint64_t )__systime .msPerPeriod * 1000ULL ;
115122 }
116123
117- /* Ensure strict monotonicity */
118- if (now_us > monotonic_us ) {
119- monotonic_us = now_us ;
120- } else {
121- now_us = monotonic_us ;
124+ /* Ensure monotonic time */
125+ while (now_us < monotonic_us ) {
126+ now_us += (uint64_t )__systime .msPerPeriod * 1000ULL ;
122127 }
123- rt_hw_interrupt_enable ( level ) ;
128+ monotonic_us = now_us ;
124129
125130 return now_us ;
126131}
@@ -132,7 +137,7 @@ uint64_t systime_now_us(void)
132137 */
133138uint32_t systime_now_ms (void )
134139{
135- uint32_t time_now_ms = systime_now_us () / 1e3 ;
140+ uint32_t time_now_ms = systime_now_us () / 1000ULL ;
136141
137142 return time_now_ms ;
138143}
@@ -161,7 +166,7 @@ void systime_udelay(uint32_t time_us)
161166 */
162167inline void systime_mdelay (uint32_t time_ms )
163168{
164- systime_udelay (time_ms * 1000 );
169+ systime_udelay (time_ms * 1000ULL );
165170}
166171
167172/**
0 commit comments