Code for multiprogram II
9 examples with code and digital analyzer images
digital pins
DI0 : high when dummy task is running
DI1 : high when task is running
DI2 : high when task2 is running (not all examples has a task2)
DI3: high when task is in critical region (not in alle examples)
DI4: high when task is in critical region (not in alle examples)
Src folder list: here
k01 - one periodic task
task runs in a loop:
Eating 10 msec of CPU time
Sleep for 30 ticks of 1 msec (set on k_init)
code for k1
You can oberserve that
task(DIO 1) is running approx every 40 msec andd eating 10 msec of time.
high indicates running
When task is not active then dummytask (DIO 0) takes over
k02 Two tasks
In K02 both tasks (task(DIO 1) and task2( DIO 2) is
both running an endless loop
is active all time
krnl has timer running at 1 msec (k_init)
task and task2 has same priority so
round robbing between them is every 1 msec
and dummytask (DIO 0) will never run bq task and task2 will use all available time
code for k2
Observe
dummytask(DIO 0) is never runnnig
task and task2 (DIO 1 and DIO 2) is sharing CPU every 1 msec (round robbin)
k03 Two tasks, same priority, eat and sleep
Two tasks: task(DIO 1) and task2 (DIO 2)
Endless loop where they
Eat 10/3 msec of CPU time
Sleep 30/20 msec
Utilization of CPU is approx 1040 + 3/23 = 0.38
Leaving 72% of time to dummtask (DIO 0)
code for k3
You may observe
Endless loop where they
Eat 10/3 msec of CPU time
Sleep 30/20 msec
Utilization of CPU is approx 1040 + 3/23 = 0.38
Leaving 72% of time to dummtask (DIO 0)
when task and task2 both wnat to use CPU they will round robbin every 1 msec bq they have same priority
See that at approx -33 smec to -27msec or so - at the arrow
A rough estimation of worst case duration for eating time for the tasks will be
task 10msec+3msec=13msec (approx the situation on the figure) bq task2 will max runs one time during task eating time
task2 duration is 3 msec and round robbin with task will prolong task will those 3 msec, and prolong task2 with 3 msec as well in this situation
k04 - as k03 but task has higher priority than task2
Two tasks: task(DIO 1) and task2 (DIO 2)
Endless loop where they
Eat 10/3 msec of CPU time
Sleep 30/20 msec
Utilization of CPU is approx 1040 + 3/23 = 0.38
Leaving 72% of time to dummtask (DIO 0)
code for k4
You may observe
Endless loop where they
Eat 10/3 msec of CPU time
Sleep 30/20 msec
Utilization of CPU is approx 1040 + 3/23 = 0.38
Leaving 72% of time to dummtask (DIO 0)
when task and task2 both want to use CPU they will NOT do round robbin but task (DIO 1) will run to end bq task has higher priority than task2
See at arrows where task becomes active and task2 is missing CPU and will get it after second arrow where task has eaten 10 msec of time
So task will runs as alone in the world bq of highest priority in system and task2 will suffer and loosing CPU to task when requested even if task2 is active.
So deadlines will vary for task2 but not for task.
Worst case duration for task is teh duration for all loops and will be 3 msec
Worstcase duration for task2 to execute 3 msec eating will be 3msec + 10msec. The 10 msec comning from waiting on CPU from task.
A total different situation from k03.
INCLIMG
k05 Two tasks fighting for critical region
Critical section implemented by a pair og k_wait and k_signal
Pin 8 to 12 used for indication of who is running and which task is inside the region
pin 8 (DIO 0) - Dummytask (task nr 0
pin 9 (DIO 1) task (task nr 1)
pin 10 (DIO 2) task2 (task nr 2)
pin 11 (DIO 3) task inside region
pin 12 (DIO 4) task2 inside region
Some dirty code for fast pin togling. On Uno pin 8,9,10,.. is from PORTB bit 0,1,2,…
If you are using a MEGA PORTA may be better. pin layout
Interrupt is disabled during PORTB manipulation to ensure it is carried out atomic.
Each task is eating time inside and outside the critical region
code for k5
pin 8 (DIO 0) - Dummytask (task nr 0
pin 9 (DIO 1) task (task nr 1)
pin 10 (DIO 2) task2 (task nr 2)
pin 11 (DIO 3) task inside region
pin 12 (DIO 4) task2 inside region
Each task is eating time inside and outside the critical region
Some observations for task2:
At approx -12msec task2 is eating 3msec inside critical region
At approx -9msec task2 is leaving critical region and sleep for 1 msec
At approx -8 msec task2 is eating 1 msec
At approx -7 msec task2 sleep for 20 msec
At approx 23 msec task2 wake up loop to top of while and get critical region at once
and repeat as above
What did happen at -40 msec ?
Seems that
before -40 msec is task inside critical region and task is waiting outside
As soon as task release critical region task2 enter the region.
k06 - as k05 but task2 has lower priority than task
Task has higher priority than task2
task will take CPU when needed
At approx 22 msec task take CPU after a 1msec sleep after critical region
And the stay inside the region is prolonged for task2
code for k6
Observe at approx 22 msec that task taskes CPU bq task has higher priority than task2
Which prolongs the stay of task inside the critical region (Seen on DIO 4) at 24msec
k09 One task running fixed samplingsfrequency
A sempaphore get attached a krnl timer which signal to the semaphore every 10 tick * 1msec
The task do only wait by the semaphore and when the sempahore gets a krnl kick (signal) at regular intervals
task is released form the semaphore
eat 3 msec
loop to top and wait again to next sample time
Can be used for control loops like
void task()
{
int res;
k_set_sem_timer(sem1, 10); // krnl signals every 10 msec
while (1) {
res = k_wait(sem1, 0); // knock knock at sem1. timeout = 0 means forever
ADC(); // measure input
controlAlg();
DAC(); actuate output
}
}
code for k9
You can see that task is running very regular every 10 msec
k10 two task sampling
Debugging on pins has been modified so
DIO3 is high when task is eating CPU time after leaving k_wait
DIO4 is high when task2 is eating CPU time after leaving k_wait
task and task2 has same priority
task is eating 4 msec every 15 msec
task2 is eating 3 msec every 10 msec
code for k10
Debugging on pins has been modified so
DIO3 is high when task is eating CPU time after leaving k_wait
DIO4 is high when task2 is eating CPU time after leaving k_wait
task and task2 has same priority
task is eating 4 msec every 15 msec
task2 is eating 3 msec every 10 msec
So we can observe that due to round robbing and same priority eat time is prolonged from time to time for both tasks.
k11 as k10 except task has higher priority taht task2
Now task has highest prority which means it will always get CPU
code for k11
DIO3 is high when task is eating CPU time after leaving k_wait
DIO4 is high when task2 is eating CPU time after leaving k_wait
task and task2 has same priority
task is eating 4 msec every 15 msec
task2 is eating 3 msec every 10 msec
Observe
that DIO 4 might be high for longer that 3 msec
that DIO 3 is always 4 msec bq task just takes CPU due to priority
See at -13 msec for task2 we have 3 msec eat and the same at -8 msec.
Might be that -13msec is delayed bq task is running from -17msec to -13msec
I guess task2 would like to had CPU at -17msec but task takes it
So we have jitter on task2
CONCLUSION
Multitasking is very difficult to understand, estimate and debug
k01 to k11 image first next link to code
a/k01/k01.ino
a/k02/k02.ino
a/k03/k03.ino
a/k04/k04.ino
a/k05/k05.ino
a/k06/k06.ino
a/k07/k07.ino
a/k08/k08.ino
a/k09/k09.ino
a/k10/k10.ino
a/k11/k11.ino
|