In Scheduler.cpp in Scheduler:schedule_next_interval(), these lines of code:
Scheduler_global_timer->ARR = current_interval_us_ - 1u;
if (Scheduler_global_timer->CNT > Scheduler_global_timer->ARR) [[unlikely]] {
uint32_t cnt_temp = Scheduler_global_timer->CNT; // problem here
Scheduler_global_timer->CNT = 0; // problem here
global_tick_us_ += cnt_temp;
}
I believe getting the cnt and then setting it to 0 causes the global_tick_us_ to be offset by about a single cycle.
What does this mean?
tasks will be executed slightly less wait time (but very little) - a 20us task with a DigitalOutput toggle made a pwm with period of 19.95us
Note that it is not a percentage of the task time but only a 'constant' offset. Why 'constant' with quotes? Every time this code is executed it will likely add a single cycle offset, so a having a single task that waits 5ms will probably have it wait for 4.99995ms but having that and a task that waits 20us will likely have this 5ms task wait less, so more like 4.95ms at least. Still, this code is only executed when the scheduler didn't have time to run the whole interrupt callback before the timer CNT (counter) overcame the new ARR (automatic reload register), which usually only happens when the next wait time is very low (1-10us) so it's pretty unlikely.
What's the solution?
The easy solution would be to have an instruction that can read and destroy (clear) in the same cycle but it doesn't seem like there is one
In
Scheduler.cppinScheduler:schedule_next_interval(), these lines of code:I believe getting the cnt and then setting it to 0 causes the global_tick_us_ to be offset by about a single cycle.
What does this mean?
Note that it is not a percentage of the task time but only a 'constant' offset. Why 'constant' with quotes? Every time this code is executed it will likely add a single cycle offset, so a having a single task that waits 5ms will probably have it wait for 4.99995ms but having that and a task that waits 20us will likely have this 5ms task wait less, so more like 4.95ms at least. Still, this code is only executed when the scheduler didn't have time to run the whole interrupt callback before the timer CNT (counter) overcame the new ARR (automatic reload register), which usually only happens when the next wait time is very low (1-10us) so it's pretty unlikely.
What's the solution?