Skip to content

Scheduler timing is off by very little #618

@victor-Lopez25

Description

@victor-Lopez25

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

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions