|
|
# Timing the OS overhead with an RMS scheduler.
|
|
|
|
|
|
## Resume and Suspend method
|
|
|
|
|
|
The fastest task has the highest priority and is blocking (cooperative thread)
|
|
|
Other tasks are preemptible. And their priority is tied to their periodicity.
|
|
|
|
|
|
An ISR runs periodically, triggered by PWM clock source.
|
|
|
At each ISR event, the fastest thread is resumed and it executes until it is done
|
|
|
at that point it suspends itself to let lower priority thread execute.
|
|
|
Lower priority threads executes until ISR runs again and preempt them by resuming the
|
|
|
fastest thread.
|
|
|
|
|
|
ISR also resumes preemptible threads at a fixed pace that give their period.
|
|
|
In this exemple Fastest thread executes at 20kHz, app1 executes at 2kHz,
|
|
|
and app2 executes at 200Hz.
|
|
|
|
|
|
# Timing the OS overhead with an RMS scheduler.
|
|
|
|
|
|
## Resume and Suspend method
|
|
|
|
|
|
The fastest task has the highest priority and is blocking (cooperative thread) Other tasks are preemptible. And their priority is tied to their periodicity.
|
|
|
|
|
|
An ISR runs periodically, triggered by PWM clock source. At each ISR event, the fastest thread is resumed and it executes until it is done at that point it suspends itself to let lower priority thread execute. Lower priority threads executes until ISR runs again and preempt them by resuming the fastest thread.
|
|
|
|
|
|
ISR also resumes preemptible threads at a fixed pace that give their period. In this exemple Fastest thread executes at 20kHz, app1 executes at 2kHz, and app2 executes at 200Hz.
|
|
|
|
|
|
OS overhead are measured by looking at gpio state with an oscilloscope.
|
|
|
|
|
|
<table>
|
|
|
<tr>
|
|
|
<th>Worst case timing observed</th>
|
|
|
<th>Time spent in ISR</th>
|
|
|
<th>Time spent switching from Ctrl threaad to app1 thread</th>
|
|
|
<th>Total overhead</th>
|
|
|
<th>Total overhead in % (Ctrl thread @20kHz)</th>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
<td>No optimizations</td>
|
|
|
<td>14 us</td>
|
|
|
<td>11 us</td>
|
|
|
<td>25 us</td>
|
|
|
<td>50 %</td>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
<td>
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<span dir="">CONFIG_SPEED_OPTIMIZATIONS</span>=y
|
|
|
|
|
|
</div>
|
|
|
</div></td>
|
|
|
<td>9 us</td>
|
|
|
<td>11 us</td>
|
|
|
<td>20 us</td>
|
|
|
<td>40 %</td>
|
|
|
</tr>
|
|
|
</table>
|
|
|
|
|
|
## Dynamic priority method
|
|
|
|
|
|
Is this test we use the same high priority "control" thread running at 20kHz and app1 running at 2kHz. \
|
|
|
Instead of using k_suspend, we use k_thread_priority_set to lower the priority of the control thread when it is done. This will cause the scheduler to preempt the control thread and will resume app1. \
|
|
|
The ISR will use k_thread_priority_set to take back the control thread priority level to its normal level.
|
|
|
|
|
|
<table>
|
|
|
<tr>
|
|
|
<th>Worst case timing observed</th>
|
|
|
<th>Time spent in ISR</th>
|
|
|
<th>Time spent switching from Ctrl threaad to app1 thread</th>
|
|
|
<th>Total overhead</th>
|
|
|
<th>Total overhead in % (Ctrl thread @20kHz)</th>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
<td>No optimizations</td>
|
|
|
<td>11 us</td>
|
|
|
<td>14 us</td>
|
|
|
<td>25 us</td>
|
|
|
<td>50 %</td>
|
|
|
</tr>
|
|
|
<tr>
|
|
|
<td>
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<span dir="">CONFIG_SPEED_OPTIMIZATIONS</span>=y
|
|
|
|
|
|
</div>
|
|
|
</div></td>
|
|
|
<td>11 us</td>
|
|
|
<td>12 us</td>
|
|
|
<td>23 us</td>
|
|
|
<td>46 %</td>
|
|
|
</tr>
|
|
|
</table>
|
|
|
|