Freelance AC 800F Task Priority, interruptible?
Presently, I cannot explain an effect we're noticing with a Freelance system on an AC 800F controller.
We've got two tasks:
- Task 1, 200 ms, priority 59
- Task 2, 400 ms, priority 58
Task 1, amongst other things, sets one of three boolean variables indicating which shift is active (early, late or night shift), depending on system time.
Task 2 acts upon this and stores several current counter values into shift-based values, for example counter "foo1" is -- depending on active shift -- saved to "foo1_early", "foo1_late" or "foo1_night". The same applies to "foo2", "foo3" etc.
Now task 2 also sets a total counter, "foo_sum", which contains the sum of all "fooX" variables. It is calculated after all individual variables. Afterwards, it is also saved to one of three variables ("foot_sum_early", -"_late", -"_night"), depending on the global shift flags.
The symptom we're noticing is that upon shift change, the last saved shift total (e.g. "foo_sum_early") doesn't exactly match the sum of the individual counters (e.g. "foo1_early" + "foo2_early" + ...). IMHO, there are two possibilities this can happen:
1. There is a previously undiscovered, general problem in our program
2. Task 2 may be suspended mid-execution whilst task 1 updates the shift flags. Afterwards, Task 2 is resumed and continues at the suspension point.
As I couldn't find definitive statements regarding this in the documentation, my question is: Is no. 2 possible in principle, i.e. tasks are interruptible, or does the controller OS handle tasks atomically, i.e. the running task always finishes completely?
(By the way, CPU load is 50...60%.)
Thanks and best regards
Voted best answer
I want to elaborate a little on what JuergenV said.
Your Task 1 (which determines the shift) has a higher priority than Task 2 (which calculates the shift's variables) and can therefore interrupt it. With this construct it will happen that the shift is switched while Task 2 was not finished with the previous shift's calculations. Now everything depends on how Task 2 gets notified of the shift switch.
If Task 2 checks the shift on several occasions during its execution and uses the direct variable access (using "Shift" instead of "@Shift") it might switch to the new shift's variables in the middle of its execution, without finishing the previous shift's calculation. In that case the sum of the different variables might differ from adding up the values manually.
To prevent that from happening, Task 2 needs to be informed about the shift switch only after it has finished its calculation. That can easily be achieved by using the process image. The process image is a copy of the variables a task is using which is taken at the beginning of a task execution.
Throughout its execution the task uses this copy only, thus being not influenced by a variable change through another task. Also it's own results are only stored in the copy during the execution. The outputs in the process image are written back to the Global Variables at the end of a Task.
In your case it means, that by using the process image variable @Shift, Task 2 will not notice a shift switch done by Task 1 during its execution and therefore finish its calculation of the old shift's variables and sums.
Btw, when you place a variable in an FBD the selection dialog offers a checkbox which when checked will automatically use the process image from then on. That way you don't need to bother with typing the "@" all the time.
Yes, tasks can be interrupted by tasks with higher priority.
And the behavior is different when working without process image or with process image (@variable).
Using variables via process image within a task will make the operations of the tasks on the variables atomic, as the task will have its own copy of the variables. But on the other hand, changes of higher priority tasks to the same variables can be lost when the lower priority task updates the variables from the process image. This should not be a problem if one task only reads and the other task only writes.
Task 2 should probably use the shift indicators through process image and Task 1 should probably set the variables throgh process image. This assumes that creating the process image for a task is protected against interruptions by other tasks (I need to crosscheck).