Searching \ for '[PIC]: Preemptive multitasking on p16 core' in subject line. ()
Make payments with PayPal - it's fast, free and secure! Help us get a faster server
FAQ page: www.piclist.com/techref/microchip/ints.htm?key=multitasking
Search entire site for: 'Preemptive multitasking on p16 core'.

Exact match. Not showing close matches.
PICList Thread
'[PIC]: Preemptive multitasking on p16 core'
2006\01\20@212508 by andrew kelley

picon face
Hello all,

Just browing around the piclist.com site a little.. According to
http://www.sxlist.com/techref/microchip/multitasking.htm pre-emptive
multitasking on a p16 core is not likely possible.

However, I think that it should be able to be done, because, if I were
to setup an interrupt to be every X cycles, and have a state variables
for each task, in the interrupt I would be able to save the state of
status and w, and goto to the next routine. Say the tasks are 1,2,3..
step 0: Begin running routine 1
step 1: Interrupt routine 1, goto routine 2,
step 2: Interrupt routine 2, goto routine 3,
step 3: Interrupt routine 3, goto routine 1,
step 4: Interrupt routine 1, return to routine 3,
step 5: Interrupt routine 3, return to routine 2,
step 6: Interrupt routine 2, return to routine 1,
step 7: repeat from step 1.

Granted, this limits the call depth, but it should work nonetheless.
The routines would receive equal amounts of time per second, but not
the same position in time.. Like this: 123 132 123 132, they are out
of sequence, for lack of a better explanation.

--
andrew

2006\01\20@222528 by Harold Hallikainen

face picon face

{Quote hidden}

As far as I can tell, you can't pop an address of the return stack to a
ram location. Having that capability would make it simple for a task to
continue where it left off. I tried to come up with a clean multitasking
method (using cooperative) but ended up maintaining state variables for
each task so I could remember where to pick up again. Not quite as
elegant. The program counter holds our curent location, so it'd be nice to
just store it and restore it.

Many years ago, I did a similar cooperative multitasking system on a 286.
The tasks were written in Turbo Pascal and the task switcher was written
in assembly. Each task had its own stack area that held the return stack,
function call parameters, and automatic local variables. While a task was
waiting for input, it would be in a tight loop of "NextTask" and check for
input. On finding input, it would act on the input, then go back to
waiting for input.

A task switch was merely loading the stack pointer with the value last
found when that task called NextTask. So, the task switcher kept a copy of
the stack pointer (and stack segment register) for each task.

Each task had a circular buffer fifo on its input. Tasks communicated by
dumping their output to the appropriate input buffer of another task.
Tasks only output complete messages to other tasks so there was no
intermixing of messages sitting in the input buffers for the other tasks.

It seemed to work pretty well. One concern I had was the waste of RAM
since I had to leave room for multiple stacks and leave room for each to
grow as necessary.

So... that's the way I did multitasking, but not on a PIC! On the PIC, I
just have a state variable for each task. Each task always starts with a
jump table to get to where it left off. Not as clean as storing the PC...

Harold
--
FCC Rules Updated Daily at http://www.hallikainen.com

2006\01\20@225712 by Bill & Pookie

picon face
Not sure what you mean by Preemptive but if you are talking about running
three or four simple tasks in a timely manner, there may be a simple way.
What are you trying to do?

Bill

{Original Message removed}

2006\01\20@235949 by andrew kelley

picon face
> Not sure what you mean by Preemptive but if you are talking about running
> three or four simple tasks in a timely manner, there may be a simple way.
> What are you trying to do?

Well, pre-emptive would mean that the code execution and transition to
next code routine would be controlled by some superior process, as
opposed to being cooperative and controlled by each routine.  This
would allow each routine to be alloted some amount of execution time.
(pre-emptive=linux multitasking cooperative=windows 3.1 MT) Likely on
a PIC it would not be of much value because the p16 only has 8 levels
of stack.  I am not trying to do anything except perhaps suggest that
it would be possible to do this on a p16 if anyone needed to use it
for something or other.  Just got bored =P

> Bill

--
andrew

2006\01\21@041519 by Wouter van Ooijen

face picon face
{Quote hidden}

Nice idea, but it still has some problems:
- when in step 1 you 'goto routine 2' in all but the first cycle, how do
you know where in the code you must start?
- how do you deal with routine 2 calling other routines and being
interrupted when such a called routine was executing?

If you go for the easy approach: each routine must run up to a fixed
point (so you know it was not executing a subroutine, and you know where
it was) you have reduced your multitasking to a set of finite-state
machines, which can indeed be done on a 14-bit core. Google 'pic
pumpkin'.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2006\01\21@090408 by olin piclist

face picon face
andrew kelley wrote:
> However, I think that it should be able to be done,

Your method won't work because the PIC 16 has only one hardware call stack
and it can't be read or written from software.  Draw out what is on the
stack at each of your steps and you will see it can't work.

> step 0: Begin running routine 1
> step 1: Interrupt routine 1, goto routine 2,
> step 2: Interrupt routine 2, goto routine 3,

So now the total nested call state of routines 1, 2, and 3 are on the stack.

> step 3: Interrupt routine 3, goto routine 1,

Go where exactly?  See how this doesn't work?


******************************************************************
Embed Inc, Littleton Massachusetts, (978) 742-9014.  #1 PIC
consultant in 2004 program year.  http://www.embedinc.com/products

2006\01\21@092128 by olin piclist

face picon face
Harold Hallikainen wrote:
> So... that's the way I did multitasking, but not on a PIC! On the
> PIC, I just have a state variable for each task. Each task always
> starts with a jump table to get to where it left off. Not as clean as
> storing the PC...

You can implement restricted cooperative multitasking on a PIC 16, with the
restriction being that TASK_YIELD be a macro that may only be invoked from
top level code (not in any subroutines), and that the data stack be empty at
the time.  See the CMD module of the HOS project at
http://www.embedinc.com/pic for an example.


******************************************************************
Embed Inc, Littleton Massachusetts, (978) 742-9014.  #1 PIC
consultant in 2004 program year.  http://www.embedinc.com/products

2006\01\21@092616 by olin piclist

face picon face
Bill & Pookie wrote:
> Not sure what you mean by Preemptive

Preemptive means that the task manager switches tasks when it decides,
regardless of what the task might be doing at the time.  In a cooperative
system each task explicitly yields the processor so that other tasks can
run.  Preemptive multitasking is no possible on a PIC 16.  It is
theoretically possible on a PIC 18 and 30, but that doesn't make it a good
idea.  I have yet to come accross a microcontroller project suitable for a
PIC where cooperative multitasking wasn't good enough, assuming multitasking
was needed at all.  For the PIC 16 a main event loop architecture has worked
well over many projects.


******************************************************************
Embed Inc, Littleton Massachusetts, (978) 742-9014.  #1 PIC
consultant in 2004 program year.  http://www.embedinc.com/products

2006\01\21@092755 by olin piclist

face picon face
andrew kelley wrote:
> I am not trying to do anything except perhaps suggest that
> it would be possible to do this on a p16

I believe it can't be.  Your examples so far have not proven otherwise.

******************************************************************
Embed Inc, Littleton Massachusetts, (978) 742-9014.  #1 PIC
consultant in 2004 program year.  http://www.embedinc.com/products

2006\01\21@105443 by andrew kelley

picon face
Yeah, I just remembered that it would have to pick up where it left off..

hrm.. well I'll keep pondering about it anyway..

--
andrew

On 1/21/06, Olin Lathrop <spam_OUTolin_piclistTakeThisOuTspamembedinc.com> wrote:
> andrew kelley wrote:
> > I am not trying to do anything except perhaps suggest that
> > it would be possible to do this on a p16
>
> I believe it can't be.  Your examples so far have not proven otherwise.

>

2006\01\21@111919 by Neil Baylis

picon face
Olin wrote:

>  Preemptive multitasking is no possible on a PIC 16.  It is
> theoretically possible on a PIC 18 and 30

I seem to remember a discussion somewhere (maybe on the Microchip
forum) about whether any of the PICs had an atomic test and set
capability.  The consensus seemed to be that this was not possible.

Olin, do you know if this is correct? I think it's possible, e.g. on
an 18F, if you use only high priority interrupts, but I'm not sure
whether this covers every situation, such as low power or brownout
conditions.

Neil

http://www.pixpopuli.com

2006\01\21@115339 by Wouter van Ooijen

face picon face
> I seem to remember a discussion somewhere (maybe on the Microchip
> forum) about whether any of the PICs had an atomic test and set
> capability.  The consensus seemed to be that this was not possible.
>
> Olin, do you know if this is correct? I think it's possible, e.g. on
> an 18F, if you use only high priority interrupts, but I'm not sure
> whether this covers every situation, such as low power or brownout
> conditions.

I don't see the use of a test-and-set on 12 and 14 bit cores:
test-and-set is used to implement a semaphore, which is usefull only in
the context of pre-emption.

But if you want the effect of a test-and-set I think there is a
two-instruction sequence that could be used within reasonable
limitations (like: not too many running processes - and you can't have
more than 2 or 3 anyway - main + 1 or 2 interrupts). I leave it as an
excercise to the reader to find such a sequence :)

Side note: for embedded systems the attractiveness of preemption is not
timeslicing but responding to events (most important: timeouts).

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2006\01\21@125559 by David VanHorn

picon face
I'm following with interest..

I know of pre-emptive multitasking, but I've never really had to use it.
I see that it's significantly more difficult than cooperative, at least in
these sorts of machines.

What I almost always end up doing, is a cooperative multitasker, essentially
a top level list of tasks to run. Each task looks for every reason not to
run, and bails out if it can.  (The lazy teenager model! :)  If it must run,
then it runs to completion, which is never all that long.

The only non-cooperative part of this system is the interrupts, and of
course they happen when they happen.

2006\01\21@142424 by olin piclist

face picon face
Neil Baylis wrote:
> I seem to remember a discussion somewhere (maybe on the Microchip
> forum) about whether any of the PICs had an atomic test and set
> capability.  The consensus seemed to be that this was not possible.

Why is it not possible at the very least by temporarily disabling
interrupts?  Also the 30F do have a bit test and set instruction.


******************************************************************
Embed Inc, Littleton Massachusetts, (978) 742-9014.  #1 PIC
consultant in 2004 program year.  http://www.embedinc.com/products

2006\01\21@150455 by D. Jay Newman

flavicon
face
> > I seem to remember a discussion somewhere (maybe on the Microchip
> > forum) about whether any of the PICs had an atomic test and set
> > capability.  The consensus seemed to be that this was not possible.
>
> Why is it not possible at the very least by temporarily disabling
> interrupts?  Also the 30F do have a bit test and set instruction.

It is *possible* to do preemptive multitasking. I just can't see
any reason to actually use it.

When I use a PIC, I want real-time performance. So I use interrupts
for anything external and a loop in the main program that checks to
see if any of my interrupt routines need more processing. I only
use that if my interrupt routine is going to take too long and then
it just does the minimal amount of processing necessary and sets
a flag for the main loop.
--
D. Jay Newman           ! Author of:
.....jayKILLspamspam@spam@sprucegrove.com     ! _Linux Robotics: Building Smarter Robots_
http://enerd.ws/robots/ ! (Now I can get back to building robots.)

2006\01\21@152337 by David VanHorn

picon face
>
> When I use a PIC, I want real-time performance.


Must resist AVR jab.. MUST resist!..

So I use interrupts
> for anything external and a loop in the main program that checks to
> see if any of my interrupt routines need more processing. I only
> use that if my interrupt routine is going to take too long and then
> it just does the minimal amount of processing necessary and sets
> a flag for the main loop.


Agreed. ISRs should only do what they NEED to do.  I've seen cases of huge
ISRs that caused problems that way.
Huge of course in time to execute. Sometimes writing them big is the best
way to write them fast.

In the AVR, I reserve a couple of "w" register equivalents specifically for
the ints, and I reserve a register to hold the SREG contents, so I avoid two
or three push/pops that way.  I've never been so pushed for register space
that I couldn't afford an ITEMP, ITEMP2, and an STEMP.

2006\01\21@154036 by Gerhard Fiedler

picon face
Wouter van Ooijen wrote:

> If you go for the easy approach: each routine must run up to a fixed
> point (so you know it was not executing a subroutine, and you know where
> it was) you have reduced your multitasking to a set of finite-state
> machines, which can indeed be done on a 14-bit core. Google 'pic
> pumpkin'.

This sounds pretty much like the cooperative multitasking Olin (and others)
were talking about.

Gerhard

2006\01\21@155202 by olin piclist

face picon face
D. Jay Newman wrote:
>>> I seem to remember a discussion somewhere (maybe on the Microchip
>>> forum) about whether any of the PICs had an atomic test and set
>>> capability.  The consensus seemed to be that this was not possible.
>>
>> Why is it not possible at the very least by temporarily disabling
>> interrupts?  Also the 30F do have a bit test and set instruction.
>
> It is *possible* to do preemptive multitasking. I just can't see
> any reason to actually use it.

But the question wasn't about preemptive multitasking.  It was about atomic
test and set capability.


******************************************************************
Embed Inc, Littleton Massachusetts, (978) 742-9014.  #1 PIC
consultant in 2004 program year.  http://www.embedinc.com/products

2006\01\21@155347 by Gerhard Fiedler

picon face
Olin Lathrop wrote:

> Harold Hallikainen wrote:
>> So... that's the way I did multitasking, but not on a PIC! On the
>> PIC, I just have a state variable for each task. Each task always
>> starts with a jump table to get to where it left off. Not as clean as
>> storing the PC...
>
> You can implement restricted cooperative multitasking on a PIC 16, with the
> restriction being that TASK_YIELD be a macro that may only be invoked from
> top level code (not in any subroutines), and that the data stack be empty at
> the time.  See the CMD module of the HOS project at
> http://www.embedinc.com/pic for an example.

The way I do it usually is to make every task (or better, the more complex
tasks) a state machine, with yields (i.e. returns to the main loop) where
appropriate, and call them all in a fixed sequence from the top level main
loop (round robin). Since that "round robin" is very fast (all individual
tasks run at max short activities between their yields) this becomes almost
preemptive -- if you allow the maximum main loop time as latency. And if
you keep that low, a cooperative model is not really that different from a
"real" preemptive one.

One important advantage of a real preemptive system is that you isolate the
tasks from each other, and have the means to tame a rogue task. This is
important in a multi-user system like Unix, where different tasks are
controlled by different users. But in an embedded system where the designer
is the only one controlling all tasks, a rogue task (that is, a task that
takes too long between cooperative yields) is just a bug that needs to be
fixed. After that, you're back to your pseudo-preemptive model again.

The other advantage is that once you have all the infrastructure of task
scheduling and inter-task communication up, some things (related to timing)
become quite comfortable to program. But then, we're talking PICs here...
once you're looking for that level of comfort, it's probably time to look
at ARMs or similar :)  OTOH, by the same margin that it becomes more
comfortable, it becomes more unpredictable. Testing a complex real-time
system with a preemptive scheduler and various levels of task priorities
for odd failure modes is not easy.

Gerhard

2006\01\21@160554 by D. Jay Newman

flavicon
face
> D. Jay Newman wrote:
> >> Why is it not possible at the very least by temporarily disabling
> >> interrupts?  Also the 30F do have a bit test and set instruction.
> >
> > It is *possible* to do preemptive multitasking. I just can't see
> > any reason to actually use it.
>
> But the question wasn't about preemptive multitasking.  It was about atomic
> test and set capability.

I'm sorry; I forgot that I was responding to one of *your* posts.

You are correct, interrupts can be disabled to do an atomic test/set on
pretty much any microcontroller. This, of course, is highly useful to
creating a preemptive operating system.
--
D. Jay Newman           ! Author of:
jayspamKILLspamsprucegrove.com     ! _Linux Robotics: Building Smarter Robots_
http://enerd.ws/robots/ ! (Now I can get back to building robots.)

2006\01\21@160959 by D. Jay Newman

flavicon
face
> > When I use a PIC, I want real-time performance.

> Must resist AVR jab.. MUST resist!..

I've used both PICs and AVRs and have no problem with using either.

> Agreed. ISRs should only do what they NEED to do.  I've seen cases of huge
> ISRs that caused problems that way.
> Huge of course in time to execute. Sometimes writing them big is the best
> way to write them fast.

Yes. However, depending on the amount of interrupts expected, I like to
keep the execution time as low as necessary. For example, if the only
interrupt I have will be the UART interrupt when using 9600 baud, my
interrupt routines can be fairly large. :)
--
D. Jay Newman           ! Author of:
.....jayKILLspamspam.....sprucegrove.com     ! _Linux Robotics: Building Smarter Robots_
http://enerd.ws/robots/ ! (Now I can get back to building robots.)

2006\01\21@162454 by Wouter van Ooijen

face picon face
> > If you go for the easy approach: each routine must run up to a fixed
> > point (so you know it was not executing a subroutine, and
> you know where
> > it was) you have reduced your multitasking to a set of finite-state
> > machines, which can indeed be done on a 14-bit core. Google 'pic
> > pumpkin'.
>
> This sounds pretty much like the cooperative multitasking
> Olin (and others) were talking about.

Yes, of course. Did I give another impression? What I meant to say is
when you apply a lot of restrictions on your program structure you sort
of can do multitastking, but it is realy just a glorified bunch of state
machines. I would not even call it cooperative multitasking, because you
can't call schedule-next-task from within a called subroutine.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2006\01\21@162456 by Wouter van Ooijen

face picon face
> It is *possible* to do preemptive multitasking. I just can't see
> any reason to actually use it.

I can see plenty of reasons, but often they will not outweight the added
CPU and memory use.

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2006\01\21@165555 by William Chops Westfield

face picon face
On Jan 21, 2006, at 6:26 AM, Olin Lathrop wrote:

> I have yet to come accross a microcontroller project suitable for
> a PIC where cooperative multitasking wasn't good enough

Cooperative multitasking is good enough for a lot of things,
even on processors much larger than a PIC.  Cisco's IOS is
still largely cooperative, for instance, despite images that
are 50+ Mbytes long running on 1GHz+ processors.  In my experience,
a lot of the "discipline" needed to do cooperative multitasking
simply moves to data structure locking when you go preemptive.
(which says, preemptive is easier when tasks don't share data
structures...)

BillW

2006\01\21@190407 by D. Jay Newman

flavicon
face
> > It is *possible* to do preemptive multitasking. I just can't see
> > any reason to actually use it.
>
> I can see plenty of reasons, but often they will not outweight the added
> CPU and memory use.

My first system was a 6502 homebrew board in a wooden case. It eventually
had 18k RAM. Some PICs have a greater capacity. Theoretically I could
write a multitasking system similar to the one I wrote of the 6502.

However, I just don't think it would be worthwhile. I seem to remember
that somebody has already written a multitasking kernel for the PIC
but I've never had any occasion to look closely at it. I use my PICs
for fairly small things where I can handle pretty much everything I
need to in assembly.
--
D. Jay Newman           ! Author of:
EraseMEjayspam_OUTspamTakeThisOuTsprucegrove.com     ! _Linux Robotics: Building Smarter Robots_
http://enerd.ws/robots/ ! (Now I can get back to building robots.)

2006\01\21@190716 by Bob Axtell

face picon face
David VanHorn wrote:

>>When I use a PIC, I want real-time performance.
>>    
>>
>
>
>Must resist AVR jab.. MUST resist!..
>
>So I use interrupts
>  
>
>>for anything external and a loop in the main program that checks to
>>see if any of my interrupt routines need more processing. I only
>>use that if my interrupt routine is going to take too long and then
>>it just does the minimal amount of processing necessary and sets
>>a flag for the main loop.
>>    
>>
>
>  
>
Agreed. The interrupt has always been used by me to set flags, which are
then served in
a prioritized manner by a main loop. The ONLY exception is in the case
of a serial characters
just received. I even service the serial outbound port in a main loop.

Almost everybody uses a "tick" timer, such as tmr0, to set flags at a
precise interval. If possible, make
the tick interval as large as possible to reduce interrupt overhead.

Don't waste a good interrupt on non-essential tasks. For example, the
MSSP port rarely
needs to use its interrupt, nor should ADC tasks, nor should many others.
.
To test for the possibility of overrun (missing a "tick" due to heavy
interrupt processing),
set a port pin when you enter the interrupt and clear it when leaving,
then examine it
with an oscilloscope while running. If your pin mormally stays true more
than 25% of the
time, you may have a problem when very infrequent items occur.

The most common interrupt error made is making too many changes in the
same interrupt.
For example, most people have a task that occurs when counterA counts
down to 0, and
another when counterB counts down to zero, etc.  But if they are chained
together, there
will be a situation where all the tasks will happen in the same
interrupt.  The best way to
solve this is to stagger the tasks by jump tables so that they CAN'T
occur at the same time.

This is as multitasking as one can get with PIC16. But it works well.

--Bob

--
Note: To protect our network,
attachments must be sent to
attachspamspam_OUTengineer.cotse.net .
1-520-850-1673 USA/Canada
http://beam.to/azengineer

2006\01\22@085330 by Xiaofan Chen

face picon face
On 1/22/06, Olin Lathrop <@spam@olin_piclistKILLspamspamembedinc.com> wrote:
> Neil Baylis wrote:
> > I seem to remember a discussion somewhere (maybe on the Microchip
> > forum) about whether any of the PICs had an atomic test and set
> > capability.  The consensus seemed to be that this was not possible.
>
> Why is it not possible at the very least by temporarily disabling
> interrupts?  Also the 30F do have a bit test and set instruction.
>

There are ports of uC/OS-II to PIC18F and dsPICs.

According to the website
www.ucos-ii.com/products/rtos/kernel/rtos.html
"µC/OS-II, The Real-Time Kernel is a highly portable, ROMable, very
scalable, preemptive real-time, multitasking kernel (RTOS) for
microprocessors and microcontrollers."

PIC18 port and the dsPIC ports of uC-OS II can be downloaded here:
http://www.ucos-ii.com/microchip/index.html

I have not tried them though and I am not so sure whether it is useful
or not.


Regards,
Xiaofan

2006\01\22@094512 by olin piclist

face picon face
Bob Axtell wrote:
> For example, most people have a task that occurs when counterA counts
> down to 0, and
> another when counterB counts down to zero, etc.  But if they are
> chained together, there
> will be a situation where all the tasks will happen in the same
> interrupt.  The best way to
> solve this is to stagger the tasks by jump tables so that they CAN'T
> occur at the same time.

Or each counter is decremented in the interrupt routine and a flag is set
when it expires.  The flags are then handled by the foreground code.


******************************************************************
Embed Inc, Littleton Massachusetts, (978) 742-9014.  #1 PIC
consultant in 2004 program year.  http://www.embedinc.com/products

2006\01\22@103203 by David VanHorn

picon face
> Or each counter is decremented in the interrupt routine and a flag is set
> when it expires.  The flags are then handled by the foreground code.


I usually use dec-to-zero counters for this.
Whenever the foreground notices that they've zeroed, then they get acted on.

2006\01\22@104718 by Scott Dattalo

face
flavicon
face
On Sat, 2006-01-21 at 08:19 -0800, Neil Baylis wrote:
> Olin wrote:
>
> >  Preemptive multitasking is no possible on a PIC 16.  It is
> > theoretically possible on a PIC 18 and 30
>
> I seem to remember a discussion somewhere (maybe on the Microchip
> forum) about whether any of the PICs had an atomic test and set
> capability.  The consensus seemed to be that this was not possible.

Hi Neil,

The 14bit cores do not have an explicit atomic test and set instruction,
however it's possible to conjure one up.

Suppose two asynchronous processes want to capture the semaphore 'Sem1'.
Further suppose that the semaphore is declared available if it is equal to
1. Then this (unoptimized) macro will block until a semaphore is obtained.



mGrabSemaphore_Blocking  macro _Sem1
 local LFailedToGrab, LTryAndGrab
   goto   LTryAndGrab
FailedToGrab:
   incr   _Sem1,F
LTryAndGrab:
   decfsz _Sem1,F
    goto  FailedToGrab
endm


Here's another non-blocking variation:


mGrabSemaphore_nonBlocking  macro _Sem1, _failed

    decfsz _Sem1,F
     bsf   _failed,0
    btfsc  _failed,0
     incf  _Sem1,F
endm

mReleaseSemaphore  macro _Sem1
    incf   _Sem1,F
endm


Now the thing to notice in both of these macros is that the decfsz
instruction is used as an atomic test and set. If the semaphore is
successfully grabbed, then that means the decfsz instruction was able to
decrement it from 1 to 0. If some other intervening asynchronous process
owns the semaphore or manages to grab it just prior to our attempt to grab
it then the decfsz will fail (in the sense that the semaphore was not a
'1' when the decfsz executed). If we fail to grab it, then we need to
reverse the decrementing operation. And when we're through with the
semaphore, we release it by increment


You might this macro like so:

   mGrabSemaphore_Blocking Sem1

  ; We got the semaphore

   do stuff

  ; release the semaphore

   mReleaseSemaphore  Sem1


Or:

   clrf tempFlags

   mGrabSemaphore_nonBlocking Sem1, tempFlags

   btfsc tempFlags,0
    goto Label_42

  ; We got the semaphore

   do stuff

  ; release the semaphore

   mReleaseSemaphore  Sem1

Label_42:

Scott

2006\01\22@121806 by Gerhard Fiedler

picon face
Wouter van Ooijen wrote:

>>> If you go for the easy approach: each routine must run up to a fixed
>>> point (so you know it was not executing a subroutine, and you know
>>> where it was) you have reduced your multitasking to a set of
>>> finite-state machines, which can indeed be done on a 14-bit core.
>>> Google 'pic pumpkin'.
>>
>> This sounds pretty much like the cooperative multitasking Olin (and
>> others) were talking about.
>
> Yes, of course. Did I give another impression?

No, you didn't; I just wanted to "hang up" this comment onto the other
discussion by adding the key word :)

> What I meant to say is when you apply a lot of restrictions on your
> program structure you sort of can do multitastking, but it is realy just
> a glorified bunch of state machines.

Yes, an approach I use a lot and I find quite sufficient.

> I would not even call it cooperative multitasking, because you can't call
> schedule-next-task from within a called subroutine.

That's partially correct; it is possible if you extend the state machine
concept into the called subroutine and consider the subroutine state in the
calling main task (like through a "done" flag). In essence, everywhere you
want to be able to yield you have a state machine (even if it's degenerated
into two states).

Gerhard

2006\01\22@124708 by Wouter van Ooijen

face picon face
> > I would not even call it cooperative multitasking, because
> you can't call
> > schedule-next-task from within a called subroutine.
>
> That's partially correct; it is possible if you extend the
> state machine
> concept into the called subroutine and consider the
> subroutine state in the
> calling main task (like through a "done" flag). In essence,
> everywhere you
> want to be able to yield you have a state machine (even if
> it's degenerated
> into two states).

The point is that on 12 and 14 bit core PICs you can't access that part
of the state (the content of the stack). So you are restricted to
"yielding" from the main.

I have no objection to state machine-programming: most of the time I try
to convince my students that they don't need to use interrupts for
everyting (which is very error-prone, especially when they do it!).

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2006\01\22@130255 by Neil Baylis

picon face
On 1/22/06, Scott Dattalo <KILLspamscottKILLspamspamdattalo.com> wrote:
>
> The 14bit cores do not have an explicit atomic test and set instruction,
> however it's possible to conjure one up.
>

--- snip ---

Thanks Scott, a lot of very useful info.

Neil

http://www.pixpopuli.com

2006\01\22@130846 by Neil Baylis

picon face
On 1/22/06, Olin Lathrop <RemoveMEolin_piclistTakeThisOuTspamembedinc.com> wrote:

> Why is it not possible at the very least by temporarily disabling
> interrupts?

Yes, I agree with you. I'll try to find the original discussion to
make the question more coherent.

Neil

2006\01\22@164522 by Marcel van Lieshout

flavicon
face
There are also PIC18 ports of FreeRTOS (preemptive & coorporative):
http://www.freertos.org

Marcel

Xiaofan Chen wrote:
{Quote hidden}

2006\01\22@174008 by Gerhard Fiedler

picon face
Wouter van Ooijen wrote:

>>> I would not even call it cooperative multitasking, because you can't
>>> call schedule-next-task from within a called subroutine.
>>
>> That's partially correct; it is possible if you extend the state
>> machine concept into the called subroutine and consider the subroutine
>> state in the calling main task (like through a "done" flag). In
>> essence, everywhere you want to be able to yield you have a state
>> machine (even if it's degenerated into two states).
>
> The point is that on 12 and 14 bit core PICs you can't access that part
> of the state (the content of the stack). So you are restricted to
> "yielding" from the main.

No. I might not have made myself clear... Maybe like this:

main() {
 while( 1 ) {
   taskA();
   taskB();
   // ...
 }
}

taskA() {
 static state;
 switch( state ) {
   case 1:
     if( sub1() )
       state = 2;
     break;
   case 2:
     // ...
 }
 return;
}

bool sub1() {
 static state;
 bool done = 0;
 switch( state ) {
   case 1:
     // ...
   case 15:
     done = 1;
     state = 1;
     break;
 }
 return done;
}

sub1 can yield through taskA. Of course a few prerequisites must be
fulfilled for that to work, but it's not impossible. (Lurkers: Please don't
pick on the code; it's not complete, it's not meant to be a working
example, and so on... It's just meant to illustrate how /in principle/ a
called subroutine can yield, albeit through the main level task.)

Of course, if you consider that in this case it's not sub1 that yields but
instead taskA that yields (because instructed to that effect by sub1), then
we are in agreement :)

Gerhard

2006\01\22@194415 by Chen Xiao Fan

face
flavicon
face

> From: TakeThisOuTpiclist-bouncesEraseMEspamspam_OUTmit.edu
> [RemoveMEpiclist-bouncesspamTakeThisOuTmit.edu] On Behalf Of Marcel van Lieshout
>
> There are also PIC18 ports of FreeRTOS (preemptive & coorporative):
> http://www.freertos.org
>

Is FreeRTOS really preemptive?

Regards,
Xiaofan

2006\01\23@015252 by Wouter van Ooijen

face picon face
> Of course, if you consider that in this case it's not sub1
> that yields but
> instead taskA that yields (because instructed to that effect
> by sub1), then we are in agreement :)

It is all arguing about words, we agree what can be done and what can't.
I don't call this multitasking, I'd call it willfully cooperating state
machines. But for the customer it does not matter how it is called :)

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2006\01\23@033418 by Marcel van Lieshout

flavicon
face
yes. It allows any task to be interrupted by a hardware interrupt ot by the
timeslice running out.

Chen Xiao Fan wrote:
{Quote hidden}

2006\01\23@035300 by Chen Xiao Fan

face
flavicon
face
Xiaofan Chen wrote:
>
> There are ports of uC/OS-II to PIC18F and dsPICs.
>
> PIC18 port and the dsPIC ports of uC-OS II can be downloaded here:
> http://www.ucos-ii.com/microchip/index.html

uC/OS-II is not free and it is actually not cheap.

The other commercial RTOS for PIC is Salvo but it seems not
to be an preemptive RTOS.

There are also another free GPLed RTOS for PIC18 called PICOS18.
It is here:
http://www.picos18.com.

According to the author:
"PICos18 is a preemptive real-time kernel for PIC18 based on the
OSEK automotive standard.
The application is running on Windows / MPLAB IDE.
The code is open source and is distributed under GPL license."

According to Marcel van Lieshout, FreeRTOS is also preemptive.
I do not see this mentioned in its website
http://www.freertos.org.


Regards,
Xiaofan

2006\01\23@041026 by Marcel van Lieshout

flavicon
face
It's on the very first webpage in the very first bullet under features:
"Free RTOS kernel - both preemptive and cooperative options."
:-)

Marcel

Chen Xiao Fan wrote:
{Quote hidden}

2006\01\23@054728 by Alan B. Pearce

face picon face
> The 14bit cores do not have an explicit atomic test and set instruction,
> however it's possible to conjure one up.

The nearest to this is probably the dec & skip if zero instruction.

2006\01\23@061529 by Wouter van Ooijen
face picon face
> > The 14bit cores do not have an explicit atomic test and set
> instruction,
> > however it's possible to conjure one up.
>
> The nearest to this is probably the dec & skip if zero instruction.

That is one of the two instructions I had in mind for a two instruction
sequence. Note that a test-and-set should keep the flag in the old
situation if it was already 'occupied', so it would be something like:

  decfsz sempahore, f
  goto no_access

  ; critical region code here

no_access
  incf semaphore, f

The sempahore is decremented, if the result is 0 the code has access to
thye critical region, otherwise it has no access. In that case, and
after the execution of the critical section, the semaphore must be
incremented to restore the old situation.

Now there is a problem (or call it a limitation): in a true pre-emptive
situation this code could be interrupted after the decfsz or after the
goto, but before the incf. This thread was locked out, so it decremented
the semaphore from 0 to 255. If 255 other threads would do the same the
255'th would inadvertently get access to its critical section. So you
can't have more than 254 threads with this semaphore implementation. But
threads are not possible anyway on 12 and 14 bit cores so who cares :)

Wouter van Ooijen

-- -------------------------------------------
Van Ooijen Technische Informatica: http://www.voti.nl
consultancy, development, PICmicro products
docent Hogeschool van Utrecht: http://www.voti.nl/hvu


2006\01\23@075631 by Normando Hall

flavicon
face
part 1 529 bytes content-type:text/plain; (decoded 7bit)


----- Original Message -----
From: "Alan B. Pearce" <RemoveMEA.B.PearceEraseMEspamEraseMErl.ac.uk>
To: "Microcontroller discussion list - Public." <RemoveMEpiclistspam_OUTspamKILLspammit.edu>
Sent: Monday, January 23, 2006 7:47 AM
Subject: Re: [PIC]: Preemptive multitasking on p16 core


> > The 14bit cores do not have an explicit atomic test and set instruction,
> > however it's possible to conjure one up.
>
> The nearest to this is probably the dec & skip if zero instruction.
> --

2006\01\23@075645 by Normando Hall

flavicon
face
part 1 529 bytes content-type:text/plain; (decoded 7bit)


----- Original Message -----
From: "Alan B. Pearce" <RemoveMEA.B.PearceTakeThisOuTspamspamrl.ac.uk>
To: "Microcontroller discussion list - Public." <EraseMEpiclistspamspamspamBeGonemit.edu>
Sent: Monday, January 23, 2006 7:47 AM
Subject: Re: [PIC]: Preemptive multitasking on p16 core


> > The 14bit cores do not have an explicit atomic test and set instruction,
> > however it's possible to conjure one up.
>
> The nearest to this is probably the dec & skip if zero instruction.
> --

2006\01\23@075655 by Normando Hall

flavicon
face
part 1 529 bytes content-type:text/plain; (decoded 7bit)


----- Original Message -----
From: "Alan B. Pearce" <RemoveMEA.B.PearceKILLspamspamrl.ac.uk>
To: "Microcontroller discussion list - Public." <piclistSTOPspamspamspam_OUTmit.edu>
Sent: Monday, January 23, 2006 7:47 AM
Subject: Re: [PIC]: Preemptive multitasking on p16 core


> > The 14bit cores do not have an explicit atomic test and set instruction,
> > however it's possible to conjure one up.
>
> The nearest to this is probably the dec & skip if zero instruction.
> --

2006\01\23@080123 by Normando Hall

flavicon
face
www.algonet.se/~staffann/developer/rtbasics.htm


----- Original Message -----
From: "Alan B. Pearce" <spamBeGoneA.B.PearceSTOPspamspamEraseMErl.ac.uk>
To: "Microcontroller discussion list - Public." <KILLspampiclistspamBeGonespammit.edu>
Sent: Monday, January 23, 2006 7:47 AM
Subject: Re: [PIC]: Preemptive multitasking on p16 core


> > The 14bit cores do not have an explicit atomic test and set instruction,
> > however it's possible to conjure one up.
>
> The nearest to this is probably the dec & skip if zero instruction.
> --

2006\01\23@094150 by William Chops Westfield

face picon face
On Jan 23, 2006, at 5:00 AM, Normando Hall wrote:

> http://www.algonet.se/~staffann/developer/rtbasics.htm
>
It would be a good idea, if you are going to post some
links and random-sounding attachments, to include some
"framing text" explaining what they are and why people might
be interested in looking at them.  Otherwise, they seem to be
somewhere between a mistake and a virus :-(

Thanks
Bill W

2006\01\23@125633 by Normando Hall

flavicon
face
Because I don't speak english very good. Try and see what are these
attachments. May be you found a virus...
NH
{Original Message removed}

2006\01\23@164911 by Xiaofan Chen

face picon face
On 1/23/06, Marcel van Lieshout <EraseMEmarcelspamEraseMEhmcs.nl> wrote:
> It's on the very first webpage in the very first bullet under features:
> "Free RTOS kernel - both preemptive and cooperative options."
> :-)
>

Ooops. I did not see this. It must be because of the
"Ads by Goooooogle". ;-)

Regards,
Xiaofan

2006\01\23@213957 by Chen Xiao Fan

face
flavicon
face
> -----Original Message-----
> From: @spam@piclist-bounces@spam@spamspam_OUTmit.edu On Behalf Of Normando Hall
> Sent: Monday, January 23, 2006 8:56 PM
> To: Microcontroller discussion list - Public.
> Subject: Re: [PIC]: Preemptive multitasking on p16 core
>

Regarding the attached file pic_rrr_16F874.zip:

Be warned this one uses non-standard assembly and will
fail to build with MPLAB.

It uses "Phyton PASM-MC" environment which I do not know.
It is not so difficult to correct the errors though.

Regards,
Xiaofan

2006\01\24@131017 by sergio masci

flavicon
face


On Sun, 22 Jan 2006, Scott Dattalo wrote:

{Quote hidden}

Actually decfsz is being used as a set and test instruction.

You should consider that the sequence:

       decf        _Sem1
       btfss        STATUS,Z

is equivalent. This is because the test for zero is performed during the
decf instruction and is then stored in the STATUS register. The btfss
instruction will look at the result of decf regardless of a task context
switch between the decf and the btfss (because the context switch will
save and restore STATUS).

Regards
Sergio Masci

http://www.xcprod.com/titan/XCSB - optimising PIC compiler
FREE for personal non-commercial use

More... (looser matching)
- Last day of these posts
- In 2006 , 2007 only
- Today
- New search...