Giovanni wrote:Hi,
The system time is meant to overflow, chVTIsSystemTimeWithinX() also works when end<start.
The size of the counter is HW constrained but if you disable tickless mode in chconf.h then you can use a 32 bits system time, in normal mode the counter becomes a normal variable increased by an interrupt.
Giovanni
Hi Giovanni,
Well, let me explain a little better my situation.
I have a state machine in the main thread, basically a switch case, with states. In some cases, when I switch to another state, I store 2 variables(cycle_start_time/cycle_end_time), using this function:
Code: Select all
static inline void jumpState(app_state_t new_state, uint16_t interval)
{
app_state = new_state;
if (interval > 0)
{
cycle_start_time = chVTGetSystemTimeX();
cycle_end_time = cycle_start_time + TIME_MS2I(interval);
}
else
{
cycle_start_time = 0;
cycle_end_time = 0;
}
}
Parameter new_state is the state I must switch to, interval is an integer, ranging from 2000 to 5000 milis, or zero, which I'll not check if the timeout has passed.
In my main thread I have the switch case:
Code: Select all
switch (app_state)
{
case ST_APP_INIT:
if (stButtonGetAndClearState(LINE_BTN_START) == ST_BUTTON_SHORT_PRESSED)
{
jumpState(ST_APP_CALIBRATION, 0);
}
else if (!isWithinInterval())
{
jumpState(ST_APP_READY, 0);
}
break;
case ST_APP_CALIBRATION:
if (!isWithinInterval())
{
// Basically I switch to the next state when the condition is true(Not within interval).
...
}
... More cases ...
}
isWithinInterval is a macro:
Code: Select all
#define isWithinInterval() chVTIsSystemTimeWithinX(cycle_start_time, cycle_end_time)
The switch case is inside a while(true) loop, with a chThdSleepMilliseconds(50); in the end.
I have other threads that do the heavy lift, everything is working great, except that if the process starts with the chVTGetSystemTimeX() in the end of the range(0xFFFF), when I check if it is within the start/end, it returns false, but it should return true:
In my log(I print this to debug the timer) I have:
Code: Select all
... a lot of entries == 1 ...
chVTIsSystemTimeWithinX(56074, 62074) == 1, when chVTGetSystemTimeX() == 62049
chVTIsSystemTimeWithinX(56074, 62074) == 0, when chVTGetSystemTimeX() == 62109
When the last line is printed, my state machine switch state to the next state, and the start/end variables are updated to:
Code: Select all
Start: 63489 (Current chVTGetSystemTimeX())
End: 3953 (chVTGetSystemTimeX() + TIME_MS2I(5000))
The first check of this new start/end configuration I get:
Code: Select all
New State: 5(4)
New Time: 63489, 3953
chVTIsSystemTimeWithinX(63489, 3953) == 0, when chVTGetSystemTimeX() == 63549
So my app switches to the new state immediately, it doesn't wait for the 5000 milis.
If the check would be made after the chVTGetSystemTimeX() overflows, the check would return true.
I'll write a function that checks if the start is greater then the end, if so, if the chVTGetSystemTimeX() returns greater than the end, I'll consider within interval. I belive that it will solve, as my timeouts are much smaller than the system time.