Sometimes multiple tasks of a multi-tasking program will desire access to a single resource of the PICAXE; serial, LCD, I2C, PWMOUT, etc. If two or more tasks try to access the same resource simultaneously they can often trample over each other and the outcome will not be as intended.
For example, if we wish to output five '0' from one task and five '1' from another, and run the following program on a real PICAXE chip or in the PE6 simulator -
The output isn't our desirable '00000111110000011111' etc but '0101010101' etc.
It is possible to take sole control of a resource by suspending other tasks which use that resource but that means knowing which tasks use that resource, is a brute force approach if the other tasks are not imminently going to use that resource - that task gets suspended when there is no good reason to suspend it, and there can sometimes be issues where multiple tasks are suspending and resuming each other.
A better approach is to have each task ask for access to the resource only when it wants to use it, and only let that task proceed once it has access to the resource. When finished with a resource the task can then release the resource for other tasks to use.
In this example we create an 'owner' variable which indicates who has taken ownership of the resource and add 'GrabResource' and 'ReleaseResource' routines to control access to it. Note there must be an initial 'Gosub ReleaseResource' in one, and only one, of the tasks -
Task 0 now grabs the resource while it outputs its five '0' and Task 1 grabs the resource while it outputs its five '1'.
We could add additional tasks using the same basic task structure without having to change anything else; no need to go through and add or adjust SUSPEND and RESUME statements, there's no chance we will miss one or introduce other problems.
For example, if we wish to output five '0' from one task and five '1' from another, and run the following program on a real PICAXE chip or in the PE6 simulator -
Code:
#Picaxe 08M2
#Terminal 4800
#SimTask ALL
Start0:
Do
For b0 = 1 To 5
Sertxd( "0" )
Next
Loop
Start1:
Do
For b1 = 1 To 5
Sertxd( "1" )
Next
Loop
It is possible to take sole control of a resource by suspending other tasks which use that resource but that means knowing which tasks use that resource, is a brute force approach if the other tasks are not imminently going to use that resource - that task gets suspended when there is no good reason to suspend it, and there can sometimes be issues where multiple tasks are suspending and resuming each other.
A better approach is to have each task ask for access to the resource only when it wants to use it, and only let that task proceed once it has access to the resource. When finished with a resource the task can then release the resource for other tasks to use.
In this example we create an 'owner' variable which indicates who has taken ownership of the resource and add 'GrabResource' and 'ReleaseResource' routines to control access to it. Note there must be an initial 'Gosub ReleaseResource' in one, and only one, of the tasks -
Rich (BB code):
#Picaxe 08M2
#Terminal 4800
#SimTask ALL
Symbol owner = b27
Start0:
Gosub ReleaseResource
Do
Gosub GrabResource
For b0 = 1 To 5
Sertxd( "0" )
Next
Gosub ReleaseResource
Loop
Start1:
Do
Gosub GrabResource
For b1 = 1 To 5
Sertxd( "1" )
Next
Gosub ReleaseResource
Loop
ReleaseResource:
owner = $FF
Return
GrabResource:
Do
If owner = $FF Then
owner = task
End If
Loop Until owner = task
Return
We could add additional tasks using the same basic task structure without having to change anything else; no need to go through and add or adjust SUSPEND and RESUME statements, there's no chance we will miss one or introduce other problems.
Last edited: