[sys_time] make time thread work at SYS_TIME_FREQ for ChibiOS

This is making the ChibiOS implementation behave the same way than the
other arch.
The get_sys_time functions for milli and micor seconds are also more
accurate.
This commit is contained in:
Gautier Hattenberger
2021-07-27 13:37:51 +02:00
parent 2ed729731a
commit 869adb2794
2 changed files with 22 additions and 17 deletions
@@ -46,6 +46,9 @@ static void thd_sys_tick(void *arg);
static THD_WORKING_AREA(wa_thd_sys_tick, 1024);
static void sys_tick_handler(void);
static uint32_t cpu_ticks = 0;
static uint32_t cpu_counter = 0;
void sys_time_arch_init(void)
{
@@ -68,9 +71,10 @@ void sys_time_arch_init(void)
uint32_t get_sys_time_usec(void)
{
chMtxLock(&sys_time_mtx);
uint32_t current = chSysGetRealtimeCounterX();
uint32_t t = sys_time.nb_sec * 1000000 +
usec_of_sys_time_ticks(sys_time.nb_sec_rem) +
usec_of_sys_time_ticks(chVTGetSystemTime() - sys_time.nb_tick);
TIME_I2US(sys_time.nb_sec_rem) +
RTC2US(STM32_SYSCLK, current - cpu_counter);
chMtxUnlock(&sys_time_mtx);
return t;
}
@@ -78,9 +82,10 @@ uint32_t get_sys_time_usec(void)
uint32_t get_sys_time_msec(void)
{
chMtxLock(&sys_time_mtx);
uint32_t current = chSysGetRealtimeCounterX();
uint32_t t = sys_time.nb_sec * 1000 +
msec_of_sys_time_ticks(sys_time.nb_sec_rem) +
msec_of_sys_time_ticks(chVTGetSystemTime() - sys_time.nb_tick);
TIME_I2MS(sys_time.nb_sec_rem) +
RTC2MS(STM32_SYSCLK, current - cpu_counter);
chMtxUnlock(&sys_time_mtx);
return t;
}
@@ -100,22 +105,21 @@ void sys_time_usleep(uint32_t us)
chSysPolledDelayX(US2RTC(STM32_HCLK, us));
chSysEnable();
} else {
uint64_t wait_st = ((uint64_t)us * CH_CFG_ST_FREQUENCY) / 1000000UL;
chThdSleep((systime_t)wait_st);
chThdSleepMicroseconds(us);
}
}
void sys_time_msleep(uint16_t ms)
{
uint64_t wait_st = ((uint64_t)ms * CH_CFG_ST_FREQUENCY) / 1000UL;
chThdSleep((systime_t)wait_st);
chThdSleepMilliseconds(ms);
}
void sys_time_ssleep(uint8_t s)
{
chThdSleep(TIME_S2I(s));
chThdSleepSeconds(s);
}
/*
* Sys_tick thread
*/
@@ -125,8 +129,9 @@ static __attribute__((noreturn)) void thd_sys_tick(void *arg)
chRegSetThreadName("sys_tick_handler");
while (TRUE) {
systime_t t = chVTGetSystemTime();
sys_tick_handler();
chThdSleepMilliseconds(1);
chThdSleepUntilWindowed(t, t + TIME_US2I(USEC_OF_SEC(1.f/(SYS_TIME_FREQUENCY))));
}
}
@@ -134,16 +139,20 @@ static void sys_tick_handler(void)
{
chMtxLock(&sys_time_mtx);
/* current time in sys_ticks */
sys_time.nb_tick = chVTGetSystemTime();
sys_time.nb_tick++;
/* max time is 2^32 / CH_CFG_ST_FREQUENCY, i.e. around 10 days at 10kHz */
uint32_t sec = sys_time.nb_tick / CH_CFG_ST_FREQUENCY;
cpu_ticks = chVTGetSystemTime();
/* store high resolution counter for accurate timing */
cpu_counter = chSysGetRealtimeCounterX();
/* increment secondes and remainder */
uint32_t sec = cpu_ticks / CH_CFG_ST_FREQUENCY;
#ifdef SYS_TIME_LED
if (sec > sys_time.nb_sec) {
LED_TOGGLE(SYS_TIME_LED);
}
#endif
sys_time.nb_sec = sec;
sys_time.nb_sec_rem = sys_time.nb_tick - sys_time_ticks_of_sec(sys_time.nb_sec);
sys_time.nb_sec_rem = cpu_ticks - cpu_ticks_of_sec(sys_time.nb_sec); // in CPU ticks
/* advance virtual timers */
for (unsigned int i = 0; i < SYS_TIME_NB_TIMER; i++) {
-4
View File
@@ -46,15 +46,11 @@
* sys_time.resolution is set from this define.
*/
#ifndef SYS_TIME_FREQUENCY
#if USE_CHIBIOS_RTOS
#define SYS_TIME_FREQUENCY CH_CFG_ST_FREQUENCY
#else /* NO RTOS */
#if defined PERIODIC_FREQUENCY
#define SYS_TIME_FREQUENCY (2 * PERIODIC_FREQUENCY)
#else /* !defined PERIODIC_FREQUENCY */
#define SYS_TIME_FREQUENCY 1000
#endif
#endif /* USE_CHIBIOS_RTOS */
#endif
typedef int8_t tid_t; ///< sys_time timer id type