Discussion forum for the BasicX family of microcontroller chips.
Re: Re: BX task switching, shared variables and atomic access - Jepsen Acoustics & Electronics Ltd - Apr 7 18:54:37 2006
I have not used tasking in the past because I have not understood it
properly nor been able to use it reliably. In an effecot to get some
more understanding I decided to start from scratch and task a simple
peice of code flashing the 2 leds.
For example, the following code runs when both subs are called as subs
not tasks.
dim stackled1(1 to 50) as byte
dim stackled2 (1 to 50) as byte
sub main()
do
call taskled1 'run as subs not as tasks
call taskled2
loop
end sub
'**************
sub led1task()
sleep(100)
call putpin(25,0)
sleep(100)
call putpin(25,1)
end sub
'****************
sub led2task()
sleep(100)
call putpin(26,0)
sleep(100)
call putpin(26,1)
end sub
'****************
But if I replace the main calls with:
sub main()
do
calltask "taskled1", stackled1 'run as task
calltask "taskled2", stackled2
loop
end sub
it does not run. Sprinkling sleep(0) 's in both the tasks and the main
or increasing the stacks also is of no help.
Whats going on?
I have been able to get the code running as two tasks if I use a
different method of getting the delays
sub led1task()
sleep(0)
if timer > (J + 0.1) then
call putpin (25,0)
end if
if timer >(J+0.2) then
call putpin(25,1)
J = timer
end if
end sub
sub led2task()
sleep(0)
if timer > (K + 0.1) then
call putpin (25,0)
end if
if timer >(K+0.2) then
call putpin(25,1)
K = timer
end if
end sub
But it is very unreliable and needs a sleep(1) in the main, to run. K &
J are dim'ed as singles and both set to 0.0 before the main. (I realise
this code will fall over after 24 hrs )
It of course runs quite reliably if called as subs not tasks.
On a slightly different note, surely there is a mistake in the docs pg
21 headed "how semaphores are implemented" and "semaphore applications".
What sets the semaphore to true? I don't understand the given example
at all.
neil

(You need to be a member of basicx -- send a blank email to basicx-subscribe@yahoogroups.com )
Re: Re: BX task switching, shared variables and atomic access - Tom Becker - Apr 7 19:15:30 2006
- You must only start a task once; you loop in Main() and crash the
stack fast. If Main() has nothing else to do, it should sleep.
- Also, each task usually endlessly loops; enclose the task in a do loop.
Try:
dim stackled1(50) as byte 'these can be shorter; try BxDism
dim stackled2(50) as byte
sub main()
calltask "led1task", stackled1 'run as task
calltask "led1task", stackled2
do
call sleep(-1)
loop
end sub
'**************
sub led1task()
do
sleep(100)
call putpin(25,0)
sleep(100)
call putpin(25,1)
loop
end sub
'****************
sub led2task()
do
sleep(100)
call putpin(26,0)
sleep(100)
call putpin(26,1)
loop
end sub
'****************
Also, see: http://groups.yahoo.com/group/basicx/message/20730 for
another multitasking demo to play with.
Tom

(You need to be a member of basicx -- send a blank email to basicx-subscribe@yahoogroups.com )
Re: BX task switching, shared variables and atomic access - Tom Becker - Apr 7 19:49:24 2006
On re-reading your code, if your intent is to endlessly re-launch a
task - waiting for completion of each - that can be done, too. Main
would need to test the status of a task before relaunching it.
In my experience, tasks are ordinarily started once and expected to
run forever concurrently with other ongoing tasks. A task can,
however, be written to run to completion, then terminate.
Semaphores are boolean vars that you define, e.g.
public tfCommChannelIsInUse as boolean
Ordinarily, you would use Semaphore(tfCommChannelIsInUse) to test and
set the flag, and
tfCommChannelIsInUse = False
to release it. Be sure to initialize semphores to False, or no
process will ever get control of the resource it protects.
Tom

(You need to be a member of basicx -- send a blank email to basicx-subscribe@yahoogroups.com )
Re: Re: BX task switching, shared variables and atomic access - Tom Becker - Apr 7 20:33:52 2006
Very close to your original code, BTW, the relaunching technique might
be something like this:
dim stackled1(1 to 50) as byte
dim stackled2(1 to 50) as byte
sub main()
calltask "led1task", stackled1 ' launch
calltask "led2task", stackled2
do
if stackled1(1) = bxTaskHalted then
calltask "led1task", stackled1 ' relauch
end if
if stackled2(1) = bxTaskHalted then
calltask "led2task", stackled2
end if
call sleep(0)
loop
end sub
'**************
sub led1task()
sleep(110)
call putpin(25,0)
sleep(110)
call putpin(25,1)
end sub
'****************
sub led2task()
sleep(100)
call putpin(26,0)
sleep(100)
call putpin(26,1)
end sub
'****************
Tom

(You need to be a member of basicx -- send a blank email to basicx-subscribe@yahoogroups.com )
Re: Re: BX task switching, shared variables and atomic access - Jepsen Acoustics & Electronics Ltd - Apr 7 23:58:42 2006
Tom Becker wrote:
> On re-reading your code, if your intent is to endlessly re-launch a
> task -
Thanks Tom and Chris. My aim was to get two tasks running and verify
that chainging the sleep in 1 task didn't alter the oether...which it
doesn't now that I've got it running. The real reason is that i have a
number of radio modems running (several 100 Km from here), which i can
access via the net, but from time to time they miss a command on com3
and I figure its because I simply loop on com3 ( dowhile statuscom)
instead of having the serial coms in a task. I'll fly to site tomorrow
and change the code and put the I/O sub and the coms sub into 2 tasks
and see if that improves things.
neil

(You need to be a member of basicx -- send a blank email to basicx-subscribe@yahoogroups.com )