Searching \ for '[EE] RTOS like this?' 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/index.htm?key=rtos+like
Search entire site for: 'RTOS like this?'.

Exact match. Not showing close matches.
PICList Thread
'[EE] RTOS like this?'
2009\05\20@011957 by solarwind

picon face
Let's say I have two tasks like this:

void task1() {
   while(true) {
       do stuff;
       if(case)
           yield();
   }
}

void task2() {
   while(true) {
       do other stuff;
       if(case)
           yield();
   }
}

Is it possible to switch the tasks every x milliseconds (for example,
50 ms) in a way that the context is saved? Is this how RTOS works? Is
this how Salvo works? Note that neither of these tasks return, but if
a certain case exists (like no data in the RX buffer, for example),
the task will yield and let the other task do its thing (is this how
it's supposed to work)?

-- [ solarwind ] -- http://solar-blogg.blogspot.com/

2009\05\20@014422 by Marcel Birthelmer

picon face
On Tue, May 19, 2009 at 10:19 PM, solarwind <spam_OUTx.solarwind.xTakeThisOuTspamgmail.com> wrote:

{Quote hidden}

Yes, that's a basic  task switcher. Pre-emptive, at that (since you're
forcing tasks to switch out at a fixed interval).

If you rely on the tasks to yield, you have cooperative multitasking, which
is even easier to implement.

A good book on the pre-emptive stuff (I found) is
http://oreilly.com/catalog/9781565923546/ - O'Reilly, Programming Embedded
Systems in C and C++. It's practical enough that it's not too dry, like a
pure OS theory book might be.

Anyway, if you take the concept of task switching, add a few primitives like
timers, inter-process communications (mutex, semaphore, queue, etc.) you
have a basic operating system. If you add a standard format for loading
executables, memory protection, and resource management, you're half-way to
a decent desktop operating system.

- Marcel

2009\05\20@015600 by Marcel Birthelmer

picon face
On Tue, May 19, 2009 at 10:19 PM, solarwind <.....x.solarwind.xKILLspamspam@spam@gmail.com> wrote:

{Quote hidden}

Yes, that's a basic  task switcher. Pre-emptive, at that (since you're
forcing tasks to switch out at a fixed interval).

If you rely on the tasks to yield, you have cooperative multitasking, which
is even easier to implement.

A good book on the pre-emptive stuff (I found) is
http://oreilly.com/catalog/9781565923546/ - O'Reilly, Programming Embedded
Systems in C and C++. It's practical enough that it's not too dry, like a
pure OS theory book might be.

Anyway, if you take the concept of task switching, add a few primitives like
timers, inter-process communications (mutex, semaphore, queue, etc.) you
have a basic operating system. If you add a standard format for loading
executables, memory protection, and resource management, you're half-way to
a decent desktop operating system.

- Marcel

2009\05\20@031927 by Vitaliy

flavicon
face
Marcel Birthelmer wrote:
> Anyway, if you take the concept of task switching, add a few primitives
> like
> timers, inter-process communications (mutex, semaphore, queue, etc.) you
> have a basic operating system. If you add a standard format for loading
> executables, memory protection, and resource management, you're half-way
> to
> a decent desktop operating system.

I don't get it. What is it with people's fascination with reinventing the
wheel? :)


2009\05\20@032635 by Vitaliy

flavicon
face
solarwind wrote:
{Quote hidden}

Take a look at the FreeRTOS docs:

http://www.freertos.org/

They describe step-by-step, with plenty of figures and diagrams, how a
preemptive RTOS works.

IMO, you have to have a very good reason to run an RTOS on a low-end micro.
A simple loop works just fine for most applications.

Vitaliy

2009\05\20@073222 by Isaac Marino Bavaresco

flavicon
face
solarwind escreveu:
> Let's say I have two tasks like this:
>
> void task1() {
>     while(true) {
>         do stuff;
>         if(case)
>             yield();
>     }
> }
>
> void task2() {
>     while(true) {
>         do other stuff;
>         if(case)
>             yield();
>     }
> }
>
> Is it possible to switch the tasks every x milliseconds (for example,
>  
Yes, with a preemptive RTOS (not possible for base-line or mid-range
PICs ) it will happen automatically. With a cooperative RTOS (the case
for said PICs) the task must test a timer and call Yield at the
appropriated time.

> 50 ms) in a way that the context is saved? Is this how RTOS works? Is
>  
Yes.
> this how Salvo works? Note that neither of these tasks return, but if
>  
Don't know, I don't use it, but most probably.

> a certain case exists (like no data in the RX buffer, for example),
> the task will yield and let the other task do its thing (is this how
> it's supposed to work)?
>  
Yes, an interrupt routine may wake a task that is waiting for data, the
task wakes up, do its job and sleeps again.

I suggest you take a look at my RTOS
(<http://www.piclist.com/techref/member/IMB-yahoo-J86/SimpleRTOS.htm>)
for mid-range PICs, you will understand how things work.


Regards,

Isaac

__________________________________________________
Faça ligações para outros computadores com o novo Yahoo! Messenger
http://br.beta.messenger.yahoo.com/

2009\05\20@074713 by olin piclist

face picon face
solarwind wrote:
{Quote hidden}

To switch based on time you need a preemptive system.  That's a lot more
complicated, and in this case unnecessary.  All you need is a cooperative
system where tasks explicitly have to give up the processor.

Did you read my other post about this from yesterday?  I even showed you
source code to implement a simple task scheduler (I wouldn't go so far as
calling it a RTOS).  It will support exactly what you are trying to do in
the example above, except that I called it TASK_YIELD instead of YIELD.

> Note that neither of these tasks return,

Right.  That's why they're tasks.  A task is a single thread of execution.
Since PICs only have one execution unit, each task runs on its own
virtualized processor.  This is done by letting each task run in turn on the
real processor for short periods.

> but if
> a certain case exists (like no data in the RX buffer, for example),
> the task will yield and let the other task do its thing (is this how
> it's supposed to work)?

I discussed this in a post yesterday already.  Go back and read it.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2009\05\20@075031 by olin piclist

face picon face
Vitaliy wrote:
> Marcel Birthelmer wrote:
>> Anyway, if you take the concept of task switching, add a few
>> primitives like
>> timers, inter-process communications (mutex, semaphore, queue, etc.)
>> you have a basic operating system. If you add a standard format for
>> loading executables, memory protection, and resource management,
>> you're half-way to
>> a decent desktop operating system.
>
> I don't get it. What is it with people's fascination with reinventing
> the wheel? :)

Geesh Vitaliy, get off it already.  Marcel wasn't telling him he should do
that, but gave some background to help explain a task scheduler, RTOS, and a
general purpose operating system.  In any case, the point here is education,
so reinventing a wheel can be very illuminating.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2009\05\20@075344 by olin piclist

face picon face
Vitaliy wrote:
> IMO, you have to have a very good reason to run an RTOS on a low-end
> micro. A simple loop works just fine for most applications.

Wow, I actually agree with Vitaliy.

Note that a preemptive task scheduler is impossible on a PIC 16.  Even a
coorperative task scheduler imposes serious restrictions on the code on a
PIC 16.

Solarwind, can you figure out why preemptive tasking is impossible on a PIC
16?


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2009\05\20@083649 by Bob Ammerman

picon face

> Note that a preemptive task scheduler is impossible on a PIC 16.  Even a
> coorperative task scheduler imposes serious restrictions on the code on a
> PIC 16.
>
> Solarwind, can you figure out why preemptive tasking is impossible on a
> PIC
> 16?

Actually, a preemptive scheduler is difficult, and probably not desirable on
a PIC 16, but there is a way to do it. Any guesses how?

--- Bob Ammerman
RAm Systems


2009\05\20@084652 by Tamas Rudnai

face picon face
On Wed, May 20, 2009 at 1:36 PM, Bob Ammerman <rammermanspamKILLspamverizon.net> wrote:

> Actually, a preemptive scheduler is difficult, and probably not desirable
> on
> a PIC 16, but there is a way to do it. Any guesses how?
>

Get an enhanced-midrange?


--
http://www.mcuhobby.com

2009\05\20@092732 by olin piclist

face picon face
Bob Ammerman wrote:
>> Solarwind, can you figure out why preemptive tasking is impossible
>> on a PIC
>> 16?
>
> Actually, a preemptive scheduler is difficult, and probably not
> desirable on a PIC 16, but there is a way to do it. Any guesses how?

I don't want to give away the answer to the original question before
Solarwind has a chance to think about it.  Maybe I should have qualified
that the tasks use the normal instruction set, particularly in the areas of
subroutine entry and exit.  Does that address the situation you had in mind?


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2009\05\20@104435 by Bob Ammerman

picon face
On Wed, May 20, 2009 at 1:36 PM, Bob Ammerman <.....rammermanKILLspamspam.....verizon.net> wrote:
>
>> Actually, a preemptive scheduler is difficult, and probably not desirable
>> on
>> a PIC 16, but there is a way to do it. Any guesses how?
>>
>
> Get an enhanced-midrange?

Good answer, but I am talking about regular old PIC16s

-- Bob Ammerman
RAm Systems

2009\05\20@104616 by Bob Ammerman

picon face
Bob Ammerman wrote:
>> Actually, a preemptive scheduler is difficult, and probably not
>> desirable on a PIC 16, but there is a way to do it. Any guesses how?

Olin replied:
> I don't want to give away the answer to the original question before
> Solarwind has a chance to think about it.  Maybe I should have qualified
> that the tasks use the normal instruction set, particularly in the areas
> of
> subroutine entry and exit.  Does that address the situation you had in
> mind?

Ah, Olin, don't give it away too soon :-)

-- Bob Ammerman
RAm Systems


2009\05\20@105752 by solarwind

picon face
On Wed, May 20, 2009 at 8:36 AM, Bob Ammerman <EraseMErammermanspam_OUTspamTakeThisOuTverizon.net> wrote:
> Actually, a preemptive scheduler is difficult, and probably not desirable on
> a PIC 16, but there is a way to do it. Any guesses how?

Here's a guess. I timer calls in ISR that manages ROM pointers and
context saving codes. Every time the ISR is called, the next ROM
pointer is loaded and jumped to. The old ROM pointer is saved. So it
IS possible, but hard and inefficient due to a lack of a hardware
stack for context saving.

2009\05\20@110835 by Tamas Rudnai

face picon face
On Wed, May 20, 2009 at 3:44 PM, Bob Ammerman <rammermanspamspam_OUTverizon.net> wrote:

> Good answer, but I am talking about regular old PIC16s
>

Unless you can tweak the stack and/or the stack pointer you may have two
kind of dodgy options:

1. You mark a reentry point on each tasks where the scheduler can restart an
interrupted task. You may have even more so the task needs to update it
every time passes a certain point... And in the meantime you can use
critical sections to make sure the task will not be interrupted by half (the
critical section marker could be even the interrupt enable so you disable
timer interrupt for example while during an uninterruptable process like
when you are updating that reentry point or other time or architect critical
section is on).

2. You may can keep an interrupt flag always on and as we know after RETFIE
the PIC will execute one instruction before getting back to the ISR you can
count where is the task's PC... This is kind of very very dodgy though...

Tamas
--
http://www.mcuhobby.com

2009\05\20@113153 by Alan B. Pearce

face picon face
> Good answer, but I am talking about regular old PIC16s

I have a feeling Olin has produced the necessary in his published code
environment ...

It just takes the necessary knowledge to recognise it for what it is ...

2009\05\20@124239 by Vitaliy

flavicon
face
Olin Lathrop wrote:
> Wow, I actually agree with Vitaliy.

AMAZING! :-))))

OTOH, I find myself agreeing with you all the time.

Vitaliy

2009\05\20@131714 by olin piclist

face picon face
Alan B. Pearce wrote:
>> Good answer, but I am talking about regular old PIC16s
>
> I have a feeling Olin has produced the necessary in his published code
> environment ...
>
> It just takes the necessary knowledge to recognise it for what it is
> ...

I've got a example of a pseudo-thread in the CMD module, but that's as far
as I've ever taken it on a PIC 16.  I have yet to get a project where
preemptive multitasking would make sense.  I have used cooperative
multitasking on PIC 18 and PIC 32 a few time, and the code for that is on
the web site.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2009\05\20@132148 by Vitaliy

flavicon
face
Bob Ammerman wrote:
> Bob Ammerman wrote:
>>> Actually, a preemptive scheduler is difficult, and probably not
>>> desirable on a PIC 16, but there is a way to do it. Any guesses how?
>
> Olin replied:
>> I don't want to give away the answer to the original question before
>> Solarwind has a chance to think about it.  Maybe I should have qualified
>> that the tasks use the normal instruction set, particularly in the areas
>> of
>> subroutine entry and exit.  Does that address the situation you had in
>> mind?
>
> Ah, Olin, don't give it away too soon :-)

The suspense is killing me! :-)

It sounds to me like you'd obviously need to use a timer interrupt, that
calls the individual tasks which never return. The interrupt itself would
probably run its own infinite loop, and manually reenable interrupts
(instead of using RETFI).

The hard part is saving and restoring context. How would you restore the PC,
so you're back at the same place inside each task, where you were at the
time the task got preempted?

Vitaliy

2009\05\20@132326 by Marcel Birthelmer

picon face
On Wed, May 20, 2009 at 7:57 AM, solarwind <@spam@x.solarwind.xKILLspamspamgmail.com> wrote:

> On Wed, May 20, 2009 at 8:36 AM, Bob Ammerman <KILLspamrammermanKILLspamspamverizon.net>
> wrote:
> > Actually, a preemptive scheduler is difficult, and probably not desirable
> on
> > a PIC 16, but there is a way to do it. Any guesses how?
>
> Here's a guess. I timer calls in ISR that manages ROM pointers and
> context saving codes. Every time the ISR is called, the next ROM
> pointer is loaded and jumped to. The old ROM pointer is saved. So it
> IS possible, but hard and inefficient due to a lack of a hardware
> stack for context saving.
>

More importantly, there is no way to clean up the stack in the ISR, so each
task will have the same stack as the others, leading to corruption when one
task tries to "return" but ends up in the calling function of another
thread.

2009\05\20@132356 by Vitaliy

flavicon
face
solarwind wrote:
>> Actually, a preemptive scheduler is difficult, and probably not desirable
>> on
>> a PIC 16, but there is a way to do it. Any guesses how?
>
> Here's a guess. I timer calls in ISR that manages ROM pointers and
> context saving codes. Every time the ISR is called, the next ROM
> pointer is loaded and jumped to. The old ROM pointer is saved. So it
> IS possible, but hard and inefficient due to a lack of a hardware
> stack for context saving.

This solution would preempt the task at any point, but would only allow you
to restart each task from the beginning. I hope this is not what Bob had in
mind. :)

Vitaliy

2009\05\20@135023 by olin piclist

face picon face
solarwind wrote:
> Here's a guess. I timer calls in ISR that manages ROM pointers and
> context saving codes. Every time the ISR is called, the next ROM
> pointer is loaded and jumped to. The old ROM pointer is saved. So it
> IS possible, but hard and inefficient due to a lack of a hardware
> stack for context saving.

It sounds like you're sortof on the right track, although I'm not sure what
you think these ROM pointers are.  The nasty bit about the PIC 16 is that it
has a fixed hardware call stack that can't be read, written, or directly
manipulated by your code.  So what happens when the preempted thread is two
layers down in the call tree at the time of the interrupt, and the thread to
restart is elsewhere in its call tree?


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2009\05\20@135457 by olin piclist

face picon face
Olin Lathrop wrote:
> I have used
> cooperative multitasking on PIC 18 and PIC 32 a few time, and the
> code for that is on the web site.

Oops, I meant to say PIC 30, not 32.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2009\05\20@151028 by Bob Ammerman

picon face
> solarwind wrote:
>>> Actually, a preemptive scheduler is difficult, and probably not
>>> desirable
>>> on
>>> a PIC 16, but there is a way to do it. Any guesses how?
>>
>> Here's a guess. I timer calls in ISR that manages ROM pointers and
>> context saving codes. Every time the ISR is called, the next ROM
>> pointer is loaded and jumped to. The old ROM pointer is saved. So it
>> IS possible, but hard and inefficient due to a lack of a hardware
>> stack for context saving.
>
> This solution would preempt the task at any point, but would only allow
> you
> to restart each task from the beginning. I hope this is not what Bob had
> in
> mind. :)
>
> Vitaliy

Certainly not!

-- Bob Ammerman
RAm Systems

2009\05\20@155121 by Tamas Rudnai

face picon face
On Wed, May 20, 2009 at 8:10 PM, Bob Ammerman <RemoveMErammermanTakeThisOuTspamverizon.net> wrote:

> Certainly not!
>

Do you have an implementation as a preemptive RTOS for PIC16 or just teasing
us with an impossible question to see if someone has a cool idea :-)

Tamas
--
http://www.mcuhobby.com

2009\05\20@155702 by M. Adam Davis

face picon face
On Wed, May 20, 2009 at 3:18 AM, Vitaliy <spamBeGonespamspamBeGonespammaksimov.org> wrote:
> I don't get it. What is it with people's fascination with reinventing the
> wheel? :)

You've been on a list with 2,000 engineers for N years... if you don't
understand it yet then you were simply not meant to know...

;-P

-Adam

2009\05\20@161652 by Vitaliy

flavicon
face
M. Adam Davis wrote:
>> I don't get it. What is it with people's fascination with reinventing the
>> wheel? :)
>
> You've been on a list with 2,000 engineers for N years... if you don't
> understand it yet then you were simply not meant to know...
>
> ;-P

Yeah, I know, it's an engineer thing.. if you had to explain, I wouldn't
understand.. ;-)

I'm sure there is some truth to the theory that the best engineers have to
have a measure of autism.

Vitaliy

2009\05\20@161923 by Wouter van Ooijen

face picon face
Bob Ammerman wrote:
> Does that address the situation you had in
> mind?
>
> Ah, Olin, don't give it away too soon :-)

I still don't see how you could create a preemptive switcher. I know a
cooperative switcher would be no big deal with some compiler support or
assembler macro magic.

--

Wouter van Ooijen

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

2009\05\20@162646 by Bob Ammerman

picon face
> Do you have an implementation as a preemptive RTOS for PIC16 or just
> teasing
> us with an impossible question to see if someone has a cool idea :-)
>
> Tamas

I do not have an implementation, but I do know how to do it.

Fair warning: when I reveal the answer people are going to feel that I
'cheated'.

-- Bob Ammerman
RAm Systems

2009\05\20@170240 by solarwind

picon face
On Wed, May 20, 2009 at 1:51 PM, Olin Lathrop <TakeThisOuTolin_piclistEraseMEspamspam_OUTembedinc.com> wrote:
> It sounds like you're sortof on the right track, although I'm not sure what
> you think these ROM pointers are.  The nasty bit about the PIC 16 is that it
> has a fixed hardware call stack that can't be read, written, or directly
> manipulated by your code.  So what happens when the preempted thread is two
> layers down in the call tree at the time of the interrupt, and the thread to
> restart is elsewhere in its call tree?

Maybe I'm thinking of the 8086 way where it's easy to jump to any
random bits of code and continue execution. I didn't know  it was so
hard to do that on PIC16.

2009\05\20@175215 by Tamas Rudnai

face picon face
On Wed, May 20, 2009 at 10:02 PM, solarwind <RemoveMEx.solarwind.xspamTakeThisOuTgmail.com> wrote:

> Maybe I'm thinking of the 8086 way where it's easy to jump to any
> random bits of code and continue execution. I didn't know  it was so
> hard to do that on PIC16.
>

It is very easy to jump to random places in PIC, what is not possible is to
manipulating the stack.

A preemptive scheduler interrupts the code execution from time to time and
if a task switching is needed then it saves the context of the current task
including the return address from the stack, then restores the next tasks
contexts - including the its return address pushing it onto the stack, so
then when a RETFIE occurs the task switch had been done. It is a very
simplistic description as there are much more things to do, just wanted to
describe why a stack manipulation is very important in this subject. If you
cannot access to the stack you are not able to determine where the scheduler
interrupt has occured therefore you cannot switch tasks -- you cannot
continue the execution of the tasks from the very same point.

With a cooperative RTOS everything is much simpler, the task periodically
calls the scheduler saying "ok, now you can make a task switch if you like".
In this case as Wouter mentioned with a macro magic or hll tricks the task
can save the returning point before calling the scheduler therefore the
scheduler can save / restore that with the rest of the context.

That simple is that -- but we are waiting for Bob's 'cheating' so maybe he
will show us how is it possible otherwise :-) Bob? I think everyne has
surrended already... :-)

Tamas
--
http://www.mcuhobby.com

2009\05\20@175707 by olin piclist

face picon face
solarwind wrote:
>> It sounds like you're sortof on the right track, although I'm not
>> sure what you think these ROM pointers are. The nasty bit about the
>> PIC 16 is that it has a fixed hardware call stack that can't be
>> read, written, or directly manipulated by your code. So what happens
>> when the preempted thread is two layers down in the call tree at the
>> time of the interrupt, and the thread to restart is elsewhere in its
>> call tree?
>
> Maybe I'm thinking of the 8086 way where it's easy to jump to any
> random bits of code and continue execution. I didn't know  it was so
> hard to do that on PIC16.

Yes, you can jump to a runtime-determined address, but that's not the
problem.  Even if you can restart a task right where it left off, how do you
set up the call stack so that the next RETURN goes where it's supposed to,
assuming the task was in a subroutine when it was interrupted?  On a PIC 16
the call stack is in special purpose hardware and you can't read or write
it.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2009\05\20@175854 by M.L.

flavicon
face
On Wed, May 20, 2009 at 3:18 AM, Vitaliy <spamEraseMEspam.....maksimov.org> wrote:

> Marcel Birthelmer wrote:
> > Anyway, if you take the concept of task switching, add a few primitives
> > like
> > timers, inter-process communications (mutex, semaphore, queue, etc.) you
> > have a basic operating system. If you add a standard format for loading
> > executables, memory protection, and resource management, you're half-way
> > to
> > a decent desktop operating system.
>
> I don't get it. What is it with people's fascination with reinventing the
> wheel? :)
>

Because the "wheel" is usually a full blown engine with transmission that
weighs 2500 pounds and you're trying to fit it in a 1cm^3 box. There's
nothing wrong with writing your own code. If nobody reinvented the wheel
we'd all be technicians soldering black boxes together.
--
Martin

2009\05\20@180147 by olin piclist

face picon face
Tamas Rudnai wrote:
> That simple is that -- but we are waiting for Bob's 'cheating' so
> maybe he will show us how is it possible otherwise :-) Bob? I think
> everyne has surrended already... :-)

Speak for yourself.  I think I know what Bob has in mind, and tried to give
just enough evidence without spilling the beans.  I may be wrong, of course.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2009\05\20@180621 by Harold Hallikainen

face
flavicon
face

>
> Yes, you can jump to a runtime-determined address, but that's not the
> problem.  Even if you can restart a task right where it left off, how do
> you
> set up the call stack so that the next RETURN goes where it's supposed to,
> assuming the task was in a subroutine when it was interrupted?  On a PIC
> 16
> the call stack is in special purpose hardware and you can't read or write
> it.


Because of the limited access to the stack, it does indeed seem difficult
to do multitasking on a 16 except for the use of state machines. On the
18, I wrote a cooperative multitasking system using the stack quite a
while back. It's at
http://www.piclist.com/techref/microchip/language/c/MultiTask.c.htm .

Harold

--
FCC Rules Updated Daily at http://www.hallikainen.com - Advertising
opportunities available!

2009\05\20@182754 by Isaac Marino Bavaresco

flavicon
face
Tamas Rudnai escreveu:
{Quote hidden}

Perhaps something like this:

   movlw    low ReturnPoint_xxx
   movwf    TaskPC+0
   movlw    high ReturnPoint_xxx
   movwf   TaskPC+1
   bsf         PIR1,TMR1IE
ReturnPoint_xxx:
   bcf         PIR1,TMR1IE

Then spread this sequence all over your code (better if the compiler is
aware of the RTOS and generate this automatically, like the CC5X does).
Of course, don´t repeat the 'xxx' part.

It is clear that preemption must happen only after the return point is
saved, thus the bsf/bcf sequence. If the preemption doesn't happen in
the window between bsf/bcf, then it must be disabled until the next
saving of the return point.

It is not possible to use call/return for normal functions also. Some
other mechanism must be used.

Regards,

Isaac

__________________________________________________
Faça ligações para outros computadores com o novo Yahoo! Messenger
http://br.beta.messenger.yahoo.com/

2009\05\21@025033 by Wouter van Ooijen

face picon face
> Perhaps something like this:
>
>     movlw    low ReturnPoint_xxx
>     movwf    TaskPC+0
>     movlw    high ReturnPoint_xxx
>     movwf   TaskPC+1
>     bsf         PIR1,TMR1IE
> ReturnPoint_xxx:
>     bcf         PIR1,TMR1IE
>
> Then spread this sequence all over your code (better if the compiler is
> aware of the RTOS and generate this automatically, like the CC5X does).
> Of course, don´t repeat the 'xxx' part.

If you spread this yourself this is cooperative multitasking: you
explicitly allow switching at selected points.

If the compiler does this for you, and inserts such a sequence after
each instruction you get preemptive multitasking, but at horrible costs.
I would not call this executing PIC code. An interpreter would probably
be more effective.

> It is not possible to use call/return for normal functions also. Some
> other mechanism must be used.

That's no problem. You can explicitly save the return address in a
stack-like memory area. IIRC there are even some compilers that extend
the 8-level stack in this way.

--

Wouter van Ooijen

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

2009\05\21@033050 by Tamas Rudnai

face picon face
On Thu, May 21, 2009 at 7:49 AM, Wouter van Ooijen <RemoveMEwouterEraseMEspamEraseMEvoti.nl> wrote:

> > Perhaps something like this:
> >
> >     movlw    low ReturnPoint_xxx
> >     movwf    TaskPC+0
> >     movlw    high ReturnPoint_xxx
> >     movwf   TaskPC+1
> >     bsf         PIR1,TMR1IE
> > ReturnPoint_xxx:
> >     bcf         PIR1,TMR1IE
> >
> > Then spread this sequence all over your code (better if the compiler is
> > aware of the RTOS and generate this automatically, like the CC5X does).
> > Of course, don´t repeat the 'xxx' part.
>
> If you spread this yourself this is cooperative multitasking: you
> explicitly allow switching at selected points.


I would say it is somewhere in between.

For example you have this task in pseudo code:

void task ( )
{
   ...
   ...
   saveReentry();
   while ( 1 )
   {
       ...
       ...
       ...
       ...
   }

}

Inside the while there is no trade off, you can make a tight loop or
whatever you want. If the scheduler suspends the task in the middle of the
loop then it can only continue from the while(1). But sometimes it is ok. If
you have something that should not be interrupted then you can still use the
good old crtitical section tricks, like:

void task ( )
{
   ...
   ...
   saveReentry();
   while ( 1 )
   {
       ...
       ...
       ...
       enterCriticalSection();
       ...
       ...
       ...
       leaveCriticalSection();
       ...
       ...
   }

}

So the scheduler can suspend only on the first 3 lines or the last 2. In a
way you can even think it as an event driven rtos where the task was started
at certain periods and running for a limited time frame only, however, take
a look at a bit more complex example:

void task ( )
{
   ...
   ...
   saveReentry();
   while ( 1 )
   {
       ...
       ...
       ...
       ...
   }

   saveReentry();
   switch (...)
   {
   case 0:
       ....
   case 1:
       saveReentry();
       while ( 1 )
       {
           ...
           ...
           ...
       }
       break;
   case 2:
       ....
   }

}


So the task has more than one reentry point which created at different state
of the task. It is looks like a cooperative, however, to save the reentry
point takes less time than calling the scheduler and also inside the loop
there is no need to do that so the code runs at native speed.

I would not say that this is efficient or nice, however it could be better
some cases than the simply cooperative mode where you might need to call the
scheduler from inside the loop degrading its performance.

Tamas
--
http://www.mcuhobby.com

2009\05\21@043253 by Alan B. Pearce

face picon face
> I don't get it. What is it with people's fascination with
> reinventing the wheel? :)

Sometimes it is a case of understanding what goes on behind the scenes, so
you can do that special project, or make something dance through hoops when
other people cannot make it happen.


2009\05\21@050759 by Michael Rigby-Jones

flavicon
face


> -----Original Message-----
> From: RemoveMEpiclist-bouncesspam_OUTspamKILLspammit.edu [RemoveMEpiclist-bouncesTakeThisOuTspamspammit.edu] On
Behalf
> Of Tamas Rudnai
> Sent: 21 May 2009 08:31
> To: Microcontroller discussion list - Public.
> Subject: Re: [EE] RTOS like this?
>
>
> I would not say that this is efficient or nice, however it could be
better
> some cases than the simply cooperative mode where you might need to
call
> the
> scheduler from inside the loop degrading its performance.#

Also you wouldn't be able to have any function calls within the "task",
since if a context switch occurred whilst calling a function, the
address would remain on the stack, so the very next return instruction
(which could be in a function called by a different task) would jump
back to the original function.

I have seen a neat task switcher implemented on the 14 bit cores by
simply pre-loading the stack with function addresses.  A return
instruction then switches to the next address in the stack, which works
indefinitely since the stack is a circular buffer.  However, interrupts
screw this up by pushing another address onto the stack.

Having racked my brains I don't see any way the stack could be useful
for a preemptive system, so all function calls would have to be done via
calculated addresses.  This implies you need some way of storing the
address within each task as the task executes.  If you had a completely
linear "task", i.e. no flow control you could possibly use a timer
running at instruction rate to determine progress through a task, but I
can see difficulties with interrupt latency and this would be
restrictive to the point of uselessness for the majority of
applications.

The only potentially useful way I could see a preemptive-like system
working on a PIC is when running a virtual machine with a bytecode
language where tests for any context switched could be performed after
each 'instruction' has been executed, much like the way the Basic Stamps
handle interrupts.

Regards

Mike

=======================================================================
This e-mail is intended for the person it is addressed to only. The
information contained in it may be confidential and/or protected by
law. If you are not the intended recipient of this message, you must
not make any use of this information, or copy or show it to any
person. Please contact us immediately to tell us that you have
received this e-mail, and return the original to us. Any use,
forwarding, printing or copying of this message is strictly prohibited.
No part of this message can be considered a request for goods or
services.
=======================================================================

2009\05\21@055546 by Tony Smith

flavicon
face
> > I don't get it. What is it with people's fascination with
> > reinventing the wheel? :)
>
> Sometimes it is a case of understanding what goes on behind the scenes, so
> you can do that special project, or make something dance through hoops
when
> other people cannot make it happen.


Or the "NIH Foundation" is lacking funds in their search for a cure.  Give
generously!

Tony

(Of course there is now the 'NIH Foundation', 'The NIH Institute', the
'Royal Society of the Prevention of NIH' etc etc.  They all do excellent
work.)

2009\05\21@065501 by Tamas Rudnai

face picon face
On Thu, May 21, 2009 at 10:07 AM, Michael Rigby-Jones <
EraseMEMichael.Rigby-JonesspamspamspamBeGoneoclaro.com> wrote:

> Also you wouldn't be able to have any function calls within the "task",
> since if a context switch occurred whilst calling a function, the
> address would remain on the stack, so the very next return instruction
> (which could be in a function called by a different task) would jump
> back to the original function.
>

True. What about that you have a special macro (if the compiler cannot help
on it) to enter to critical section before and leave when it's done? You
need that macro anyway as you cannot use the standard CALL/RETURN as you
have to use a soft-stack to be able to save it.

Tamas
--
http://www.mcuhobby.com

2009\05\21@074232 by Isaac Marino Bavaresco

flavicon
face
Wouter van Ooijen escreveu:
>> Perhaps something like this:
>>
>>     movlw    low ReturnPoint_xxx
>>     movwf    TaskPC+0
>>     movlw    high ReturnPoint_xxx
>>     movwf   TaskPC+1
>>     bsf         PIR1,TMR1IE
>> ReturnPoint_xxx:
>>     bcf         PIR1,TMR1IE
>>
>> Then spread this sequence all over your code (better if the compiler is
>> aware of the RTOS and generate this automatically, like the CC5X does).
>> Of course, don´t repeat the 'xxx' part.
>>    
>
> If you spread this yourself this is cooperative multitasking: you
> explicitly allow switching at selected points.
>  

I see it more like a preemptive one with most of the code inside
critical sections.
In a non-preemptive scheduler, each time you execute "Yield", the
context will be switched. In this one, the switch will only happen if
the slice has already finished.

> If the compiler does this for you, and inserts such a sequence after
> each instruction you get preemptive multitasking, but at horrible costs.
> I would not call this executing PIC code. An interpreter would probably
> be more effective.
>
>  

Not for every instruction, but a trade-off between latency and
efficiency. Say, each 200 instructions or so at 5MIPS will give a 40
microsecond jitter and an overhead of 3%.
Remember, this is just a theoretical discussion :)

>> It is not possible to use call/return for normal functions also. Some
>> other mechanism must be used.
>>    
>
> That's no problem. You can explicitly save the return address in a
> stack-like memory area. IIRC there are even some compilers that extend
> the 8-level stack in this way.
>  

Yes, I know. I wrote this just for others not saying "Hey, you forgot...".


Regards,

Isaac

__________________________________________________
Faça ligações para outros computadores com o novo Yahoo! Messenger
http://br.beta.messenger.yahoo.com/

2009\05\21@124311 by peter green

flavicon
face

> Not for every instruction, but a trade-off between latency and
> efficiency. Say, each 200 instructions or so at 5MIPS will give a 40
> microsecond jitter and an overhead of 3%.
> Remember, this is just a theoretical discussion :)
The real complication would be loops, the compiler would have to
calculate the maximum runtime of every loop, take that into account in
it's insertion placements and if nessacery make insertions in the loops
themselves.

2009\05\21@133455 by Gerhard Fiedler

picon face
Bob Ammerman wrote:

> Bob Ammerman wrote:
>>> Actually, a preemptive scheduler is difficult, and probably not
>>> desirable on a PIC 16, but there is a way to do it. Any guesses
>>> how?
>
> Olin replied:
>> I don't want to give away the answer to the original question before
>> Solarwind has a chance to think about it.  Maybe I should have
>> qualified that the tasks use the normal instruction set,
>> particularly in the areas of subroutine entry and exit.  Does that
>> address the situation you had in mind?
>
> Ah, Olin, don't give it away too soon :-)

Since the main problem is the fact that the hardware stack isn't
accessible, maybe addressing this is the ticket? :)

Gerhard

2009\05\21@175419 by Isaac Marino Bavaresco

flavicon
face
peter green escreveu:
>> Not for every instruction, but a trade-off between latency and
>> efficiency. Say, each 200 instructions or so at 5MIPS will give a 40
>> microsecond jitter and an overhead of 3%.
>> Remember, this is just a theoretical discussion :)
>>    
> The real complication would be loops, the compiler would have to
> calculate the maximum runtime of every loop, take that into account in
> it's insertion placements and if nessacery make insertions in the loops
> themselves.
>  


At least one insertion in each loop, more if the loop is too long .
Remember that the preemption doesn't happen every time the sequence is
executed.


Regards,

Isaac
__________________________________________________
Faça ligações para outros computadores com o novo Yahoo! Messenger
http://br.beta.messenger.yahoo.com/

2009\05\21@190035 by Vitaliy

flavicon
face
M.L. wrote:
>> > Anyway, if you take the concept of task switching, add a few primitives
>> > like
>> > timers, inter-process communications (mutex, semaphore, queue, etc.)
>> > you
>> > have a basic operating system. If you add a standard format for loading
>> > executables, memory protection, and resource management, you're
>> > half-way
>> > to
>> > a decent desktop operating system.
>>
>> I don't get it. What is it with people's fascination with reinventing the
>> wheel? :)
>>
>
> Because the "wheel" is usually a full blown engine with transmission that
> weighs 2500 pounds and you're trying to fit it in a 1cm^3 box. There's
> nothing wrong with writing your own code. If nobody reinvented the wheel
> we'd all be technicians soldering black boxes together.

Martin, the problem with your guys' responses is that they make a lot of
sense in a vacuum, but not in the situation we're discussing.

Is SW trying to build a home automation system, or is he trying to learn how
to design custom token-based protocols and write PIC-based desktop operating
systems?

Using someone else's code does not preclude you from writing your own code.

Vitaliy

2009\05\21@191330 by Vitaliy

flavicon
face
Olin Lathrop wrote:
>> That simple is that -- but we are waiting for Bob's 'cheating' so
>> maybe he will show us how is it possible otherwise :-) Bob? I think
>> everyne has surrended already... :-)
>
> Speak for yourself.  I think I know what Bob has in mind, and tried to
> give
> just enough evidence without spilling the beans.  I may be wrong, of
> course.

If Bob holds out any longer, he should not be surprised if he sees a crowd
outside his window with torches and pitchforks.. or whatever implements an
angry engineering mob takes to a lynching.

Vitaliy

2009\05\21@192133 by Tamas Rudnai

face picon face
On Fri, May 22, 2009 at 12:12 AM, Vitaliy <RemoveMEspamKILLspamspammaksimov.org> wrote:

> If Bob holds out any longer, he should not be surprised if he sees a crowd
> outside his window with torches and pitchforks.. or whatever implements an
> angry engineering mob takes to a lynching.
>

LOL! I am already there... Still quiet for the moment giving the last chance
to make a confess like : "Sorry, sorry guys, I meant 18F" :-)

Tamas
--
http://www.mcuhobby.com

2009\05\21@211453 by Bob Ammerman

picon face
> If Bob holds out any longer, he should not be surprised if he sees a
crowd
> outside his window with torches and pitchforks.. or whatever implements an
> angry engineering mob takes to a lynching.
>
> Vitaliy

Ok, ok... you can leave the pitchforks at home, although you want feel like
getting them back out when you read my idea. Just remember, I did warn you
that you might think I am 'cheating'.


My idea is simple this: implement Forth, or a similar threaded language. In
this case the executable code is a combination of interpreted address lists
and ordinary machine code. However, instead of using the machine stack,
Forth uses its own internal data and procedural stacks. The pre-emptive
multitasking is done in the "Next" routine of the Forth interpreter. Note
that interrupt level code would likely still be written in assembly, and
that interrupts could remain enabled at all times. The interrupt handlers
would just set flags which the preemptive scheduler would notice when it
next got control.

This idea is, of course, very similar to some which have already been
mentioned on this thread.

-- Bob Ammerman
RAm Systems

2009\05\21@221543 by solarwind

picon face
On Thu, May 21, 2009 at 6:59 PM, Vitaliy <spamSTOPspamspamspam_OUTmaksimov.org> wrote:
> Is SW trying to build a home automation system, or is he trying to learn how
> to design custom token-based protocols and write PIC-based desktop operating
> systems?

Both, really.

> Using someone else's code does not preclude you from writing your own code.

Exactly. Maybe I'm not at the level of writing a reliable RTOS yet.
But I know I can write that token protocol :)

2009\05\21@221620 by solarwind

picon face
On Thu, May 21, 2009 at 9:14 PM, Bob Ammerman <spamBeGonerammermanSTOPspamspamEraseMEverizon.net> wrote:
> My idea is simple this: implement Forth, or a similar threaded language. In
> this case the executable code is a combination of interpreted address lists
> and ordinary machine code. However, instead of using the machine stack,
> Forth uses its own internal data and procedural stacks. The pre-emptive
> multitasking is done in the "Next" routine of the Forth interpreter. Note
> that interrupt level code would likely still be written in assembly, and
> that interrupts could remain enabled at all times. The interrupt handlers
> would just set flags which the preemptive scheduler would notice when it
> next got control.
>
> This idea is, of course, very similar to some which have already been
> mentioned on this thread.

I wanted to get my pitchfork out as soon as you said "Forth".

2009\05\21@224444 by Byron Jeff

flavicon
face
On Thu, May 21, 2009 at 09:14:45PM -0400, Bob Ammerman wrote:
>  > If Bob holds out any longer, he should not be surprised if he sees a
> crowd
> > outside his window with torches and pitchforks.. or whatever implements an
> > angry engineering mob takes to a lynching.
> >
> > Vitaliy
>
> Ok, ok... you can leave the pitchforks at home, although you want feel like
> getting them back out when you read my idea. Just remember, I did warn you
> that you might think I am 'cheating'.

Have at it.

{Quote hidden}

Pitchforks out people!

Implementing a PIC16 FORTH is on one of my back burners. I took quite a bit
of time examining how to implement a workable interpreted FORTH system.
Since PIC program memory cannot be read directly, PIC file registers are
too limited, as is PIC data memory, there are very limited options in
implementing a FORTH system with even moderate performance on the 16F
family. A few workable options:

1) Reading program memory for 16F chips that implement it. Not high
performance because it takes a minimum of a dozen instructions to setup and
read the program memory. Also not all 16F family chips implements this
feature.

2) Token based system using RETLWs for token fetch. This is how I
implemented my NPCI interpreter. While there are some limitations a token
fetch and subroutine jump can be implemented in about 10 instructions or
so.

3) The most efficient method is subroutine threaded code. But guess what?
That uses the hardware stack.

Still it may be doable efficiently enough if instead of tokens or calls
doing threading using GOTOs. After all a call is really nothing more than a
push of the return address on a stack followed by a goto the target. What's
the cost? FSR is the stack pointer

DECF  FSR,F
MOVLW RETHIADDR
MOVWF INDF

DECF  FSR,F
MOVLW RETLOADDR
MOVWF INDF

GOTO  TARGET

Still seems too costly.

BAJ

2009\05\22@011857 by Xiaofan Chen

face picon face
On Fri, May 22, 2009 at 10:43 AM, Byron Jeff <KILLspambyronjeffspamBeGonespamclayton.edu> wrote:
> Implementing a PIC16 FORTH is on one of my back burners. I took quite a bit
> of time examining how to implement a workable interpreted FORTH system.
> Since PIC program memory cannot be read directly, PIC file registers are
> too limited, as is PIC data memory, there are very limited options in
> implementing a FORTH system with even moderate performance on the 16F
> family.

There are Open Source Forth for PIC18. Not sure if this helps.
http://zwizwa.be/archive/pic18-interaction.html (new)
http://pic18forth.sourceforge.net/ (rather dated)


--
Xiaofan http://mcuee.blogspot.com

2009\05\22@014247 by William \Chops\ Westfield

face picon face

On May 21, 2009, at 6:14 PM, Bob Ammerman wrote:

> My idea is simple this: implement Forth, or a similar threaded  
> language.

Any interpreted language would work, for some definition of "work."
(let's add preemptive multitasking to Stamp Basic.  One of the modern  
16F chips ought to have plenty of code memory to add the feature.  
(But I gather Stamp Basic is pretty well protected by one means or  
another.))

BillW

2009\05\22@025925 by Wouter van Ooijen

face picon face
> My idea is simple this: implement Forth, or a similar threaded language.

pitchforks! tar! feathers!

--

Wouter van Ooijen

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

2009\05\22@045533 by Wouter van Ooijen

face picon face
Wouter van Ooijen wrote:
>> My idea is simple this: implement Forth, or a similar threaded language.
>
> pitchforks! tar! feathers!

Now the question remains: was this also the solution Olin had in mind?
In that case I'll order more tar ;)


--

Wouter van Ooijen

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

2009\05\22@050317 by Alan B. Pearce

face picon face
> My idea is simple this: implement Forth, or a similar threaded language.
> In
> this case the executable code is a combination of interpreted address
> lists
> and ordinary machine code. However, instead of using the machine stack,
> Forth uses its own internal data and procedural stacks. The pre-emptive
> multitasking is done in the "Next" routine of the Forth interpreter. Note
> that interrupt level code would likely still be written in assembly, and
> that interrupts could remain enabled at all times. The interrupt handlers
> would just set flags which the preemptive scheduler would notice when it
> next got control.
>
> This idea is, of course, very similar to some which have already been
> mentioned on this thread.

<VBG> It is along similar lines to what I was thinking. RCA came up with a
similar system for the COSMAC microprocessor, and the editor that ran on the
COSMAC development system used it.

On a PIC it would not be a big problem. One could use the whole of the PIC
ROM for the interpreter, and then have an external EEPROM for the
interpreted code. Using a Ramtron device would mean there is no time penalty
when writing to it for upgrades, and with a suitable block cypher, like
XTEA, the code could be protected. When executing, a block of code could be
read into RAM, decrypted, then executed, with only a single decryption time
penalty per block, unless the code is jumping between blocks. Having 3 or 4
blocks in RAM at a time would probably cache enough to get around the worst
of this.

2009\05\22@050809 by Tamas Rudnai

face picon face
On Fri, May 22, 2009 at 9:55 AM, Wouter van Ooijen <EraseMEwouterspamEraseMEvoti.nl> wrote:

> >> My idea is simple this: implement Forth, or a similar threaded language.
> >
> > pitchforks! tar! feathers!
>
> Now the question remains: was this also the solution Olin had in mind?
> In that case I'll order more tar ;)
>

LOL!

--
http://www.mcuhobby.com

2009\05\22@095136 by olin piclist

face picon face
Bob Ammerman wrote:
> My idea is simple this: implement Forth, or a similar threaded
> language. In this case the executable code is a combination of
> interpreted address lists and ordinary machine code. However, instead
> of using the machine stack, Forth uses its own internal data and
> procedural stacks. The pre-emptive multitasking is done in the "Next"
> routine of the Forth interpreter. Note that interrupt level code would
> likely still be written in assembly, and that interrupts could remain
> enabled at all times. The interrupt handlers would just set flags which
> the preemptive scheduler would notice when it next got control.

I thought you were going to use a software call/return stack.  This could be
done with macros for subroutine call and return.  This is less of a cheat
since most of the code executes normally and uses the native instruction
set.  Only call and return are hacked.

Note that I'm not actually advocating this.  Preemptive multitasking is
mostly silly on small resource-constrained systems.  Even cooperative
multitasking is less common than a basic main event loop architecture.

The one place where having a separate thread seems particularly useful is in
dealing with a input stream where the meaning of each byte is dependent on
previous bytes (each byte is not idempotent), such as a protocol where there
are opcodes followed by data dependent on the opcode.  Being able to do
things like a computed GOTO on the opcode is very useful and makes the code
a lot cleaner.  This is essentially using a state machine but using the PC
as the state variable.  However, in that scheme the code needs to appear to
get the next input byte when in reality input bytes come in when they come
in.  This is where a task is useful.  It can check for a new input byte and
yield in a loop until one is available.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2009\05\22@103316 by Bob Ammerman

picon face
> Bob Ammerman wrote:
>> My idea is simply this: implement Forth, or a similar threaded
>> language.

> I thought you were going to use a software call/return stack.  This could
> be
> done with macros for subroutine call and return.  This is less of a cheat
> since most of the code executes normally and uses the native instruction
> set.  Only call and return are hacked.

One can look at a Forth (runtime only without editor) implementation as very
much a mixed environment in which Call/Return are simulated but the rest of
the code is executed natively. It is just that the Call/Return stuff is
interpreted by the Forth kernel which then branches into native code for the
lowest level operations.

> Note that I'm not actually advocating this.  Preemptive multitasking is
> mostly silly on small resource-constrained systems.  Even cooperative
> multitasking is less common than a basic main event loop architecture.

Amen, and Amen.

{Quote hidden}

I do this with some macro magic. The "get next byte" routine saves a resume
PC and then returns from the function that processes the input. When the
next character comes in I call a stub that branches to the saved PC. This of
course breaks horribly if and "GetNextByte" calls are in a subroutine.

-- Bob Ammerman
RAm Systems


2009\05\22@132629 by M.L.

flavicon
face
On Thu, May 21, 2009 at 6:59 PM, Vitaliy <@spam@spam@spam@spamspam_OUTmaksimov.org> wrote:

{Quote hidden}

Vitaliy,
Your criticism to my 3 sentence response to your 2 sentence dig hardly
qualifies as a "discussion" that we are having. I don't know what the o.p.
is trying to do and it doesn't really matter. I was responding to your
nearly baseless blanket statement that people are fascinated by reinventing
the wheel.


> Using someone else's code does not preclude you from writing your own code.
>

Did I say it does?


>
> Vitaliy
>


Martin

2009\05\22@142726 by olin piclist

face picon face
Bob Ammerman wrote:
> I do this with some macro magic. The "get next byte" routine saves a
> resume PC and then returns from the function that processes the input.
> When the next character comes in I call a stub that branches to the
> saved PC. This of course breaks horribly if and "GetNextByte" calls are
> in a subroutine.

This is what I call pseudo-threads on a PIC 16.  I do the same thing, with
GetNextByte called GETBYTE.  The main event loop jumps to CMD_BYTE when it
detects a new input byte available.  The code is available in template
module QQQ_CMD.ASPIC, which is included in the PIC development tools release
that can be downloaded from http://www.embedinc.com/pic/dload.htm.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2009\05\22@200324 by Isaac Marino Bavaresco

flavicon
face
part 0 44 bytes
his is a multi-part message in MIME format.
part 1 1297 bytes content-type:text/plain; charset=ISO-8859-1 (decoded 7bit)

Isaac Marino Bavaresco escreveu:
{Quote hidden}

This is my proof of concept for a preemptive scheduler for PIC16 MCUs.
Not quite working, but shows the concept (in MPLB-SIM).

Sometimes one task gets "lost",  but the others keep taking rounds. I
think I will need to rewrite the scheduler (interrupt routine) in
assembly for it to work correctly.

The context is not saved/restored correctly yet (STATUS, FSR, etc.),
only the PC.

Regards,

Isaac



part 2 1718 bytes content-type:application/x-zip-compressed; (decode)

part 3 35 bytes content-type:text/plain; charset="us-ascii"
(decoded 7bit)

2009\05\22@215128 by Vitaliy

flavicon
face
M.L. wrote:
{Quote hidden}

Notice that I said "your guys'", not "your".


> I don't know what the o.p.
> is trying to do and it doesn't really matter. I was responding to your
> nearly baseless blanket statement that people are fascinated by
> reinventing
> the wheel.

Well that's the problem. It does matter. You have to understand the context
to make sense of what I said.


>> Using someone else's code does not preclude you from writing your own
>> code.
>>
>
> Did I say it does?

You said, "There's nothing wrong with writing your own code."  Of course
there isn't. My point is, you can be more productive if you can use code
that has already been written, and instead of reinventing wheels, create
something new.

What you and others have said, has merit. Whether it applies in this
situation, depends on the goal of SW's project ("automating a home" or "the
joy of pure learning").

Vitaliy

2009\05\23@093929 by olin piclist

face picon face
Vitaliy wrote:
> My point is, you can be more productive if you
> can use code that has already been written,

This is usually not true in my experience.  Most other code is crap, or
wouldn't fit into my system nicely without more work then to write it the
way I want from scratch.  Code re-use sounds nice in principle, but in
practise I find it way overrated.


********************************************************************
Embed Inc, Littleton Massachusetts, http://www.embedinc.com/products
(978) 742-9014.  Gold level PIC consultants since 2000.

2009\05\23@133542 by Isaac Marino Bavaresco

flavicon
face
Olin Lathrop escreveu:
> Vitaliy wrote:
>  
>> My point is, you can be more productive if you
>> can use code that has already been written,
>>    
>
> This is usually not true in my experience.  Most other code is crap, or
>  

It appears that 99.9% of the programmers think this way (me included),
because of coding style or other subtle details. I try to get over such
prejudices so I can use others code.
There is a lot of bad code around, but there is a lot of good code also.
If you get a nice piece of code, use it, or at least use it as a base to
write your own.
I save much time this way.

> wouldn't fit into my system nicely without more work then to write it the
> way I want from scratch.  Code re-use sounds nice in principle, but in
> practise I find it way overrated.
>  
Perhaps overrated, but useful.
I rarely start a project from scratch, usually I start with an older
project skeleton, trim off the parts that won´t fit at all, adapt what
may be reused and write what is missing.

Regards,

Isaac


__________________________________________________
Faça ligações para outros computadores com o novo Yahoo! Messenger
http://br.beta.messenger.yahoo.com/

2009\05\25@145415 by Herbert Graf

picon face
On Sat, 2009-05-23 at 09:40 -0400, Olin Lathrop wrote:
> Vitaliy wrote:
> > My point is, you can be more productive if you
> > can use code that has already been written,
>
> This is usually not true in my experience.  Most other code is crap, or
> wouldn't fit into my system nicely without more work then to write it the
> way I want from scratch.  Code re-use sounds nice in principle, but in
> practise I find it way overrated.

Then I'd say that perhaps you're coding style is too inflexible.

I'll agree with the overrated comment, people usually see the word "code
reuse" and assume it means "zero work". This is wrong.

That said, I've benefited tremendously from code reuse. While some of my
reuse has been my own code (porting from one platform to another, or
from one language to another), much has been 3rd party.

Yes, it's pretty much unheard of that using 3rd party code is "drop in"
compatible. There are always little things that need to be fiddled with.
But if you know how to spot good code candidates, and where to look
(which only happens with experience in reusing code), reuse is very
beneficial, and can be quite painless.

Another benefit: I find that by keeping reuse in mind I write much more
modular code (which is usually much easier to maintain).

Case in point: I recently wrote some extensive verilog that included a
register interface over serial/USB. I needed to expand that interface to
include I2C. Due to the way I wrote my code, I was able to download an
I2C slave block (opencores.org), integrate it, write a small "interface
block" and was up and running. Had I designed the system less
generically it, as you say: "wouldn't fit into my system nicely without
more work then to write it the way I want from scratch".

You can't expect 3rd party code to mesh with your code by ignoring
elements of your design that make it difficult to integrate other code.

FWIW, in my latest verilog design there is a block that was originally
written in Basic, ported to Java, then to C/C++ and finally to
VerilogRTL. Done right, code reuse can accomplish amazing time savings.

TTYL

2009\05\26@085259 by Michael Rigby-Jones

flavicon
face


> -----Original Message-----
> From: spamBeGonepiclist-bouncesspamKILLspammit.edu [.....piclist-bouncesspam_OUTspammit.edu] On
Behalf
{Quote hidden}

Sorry to be a bit negative, but this only works as well as it does
because your tasks are so simple.  You are saving the return address at
just one point in your task, yet the scheduler could interrupt it
anywhere.  Even if you added context saving this would never work
correctly with tasks that compiler to more than a couple of
instructions.

Regards

Mike

=======================================================================
This e-mail is intended for the person it is addressed to only. The
information contained in it may be confidential and/or protected by
law. If you are not the intended recipient of this message, you must
not make any use of this information, or copy or show it to any
person. Please contact us immediately to tell us that you have
received this e-mail, and return the original to us. Any use,
forwarding, printing or copying of this message is strictly prohibited.
No part of this message can be considered a request for goods or
services.
=======================================================================

2009\05\26@101513 by Isaac Marino Bavaresco

flavicon
face
Michael Rigby-Jones escreveu:
{Quote hidden}

If you analyze the macro Sw, you will see that the tasks may be
interrupted only at specific points, just after the return address is saved.
The tick interrupt stay disabled most of the time (the INTCON PIE bit =
register 0x0b, bit 6), and is only enabled for one instruction cycle
each time the macro is invoked (bsf 0x0b,6/bcf 0x0b,6).

Some people discussed here if it is preemptive or not (theoretically,
before I wrote the code). I think it is something in-between preemptive
and collaborative.
Preemption may happen just at specific points (when the macro is
called), but only if the tick has elapsed, unlike a "Yield" that forces
a switch every time it is called.

The idea is that the compiler add the code automatically every few
normal program instructions.

This is just a theoretical idea, I don't think it may be useful because
of its low efficiency.

Regards,

Isaac

__________________________________________________
Faça ligações para outros computadores com o novo Yahoo! Messenger
http://br.beta.messenger.yahoo.com/

2009\05\26@104155 by Wouter van Ooijen

face picon face
> The idea is that the compiler add the code automatically every few
> normal program instructions.
>
> This is just a theoretical idea, I don't think it may be useful because
> of its low efficiency.

Do you realise that 12/14 bit core PIC code (whether hand-assembly or
compiler generated) generally uses global variables, and is hence not
re-entrant? To make your idea work you would have to make unique copies
of all code that is shared between threads.

--

Wouter van Ooijen

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

2009\05\26@111102 by Tamas Rudnai

face picon face
On Tue, May 26, 2009 at 3:15 PM, Isaac Marino Bavaresco <
.....isaacbavarescospamRemoveMEyahoo.com.br> wrote:

> Preemption may happen just at specific points (when the macro is
> called), but only if the tick has elapsed, unlike a "Yield" that forces
> a switch every time it is called.
>

Some posts ago I was suggesting something like that and there could be a
small advantage in rare cases where you need to do a loop for example and it
is safe to 'redo' the loop at any point. For example you mark the beginning
of the loop as a safe reentry point and then you do not need to yield the
scheduler at every cycle to make the decision if a task switch is needed --
less overhead for sure.

However, the point is that using an RTOS you are not controlling the
resources directly therefore not polling or wasting the CPU with delay loops
etc. For those you can use the OS provided functions -- if nothing else then
queues or semaphores/mutexes. In that way a cooperative scheduler is just as
fine especially when you have interrupt/event driven routines as well (so
your normal task can still be interrupted by any time by an ISR executing an
event handler and then returning to your task).

As Olin suggested this can be well done by normal programming style using
interrupts and well organised program structure. It may can be another
discussion though whenever in this case you are writing your own scheduler
for yourself without even realizing that it was a scheduler.

Tamas
--
http://www.mcuhobby.com

2009\05\26@115238 by Michael Rigby-Jones

flavicon
face


> -----Original Message-----
> From: RemoveMEpiclist-bouncesspamspamBeGonemit.edu [spamBeGonepiclist-bounces@spam@spamspam_OUTmit.edu] On
Behalf
{Quote hidden}

MCUs.
> >> Not quite working, but shows the concept (in MPLB-SIM).
> >>
> >> Sometimes one task gets "lost",  but the others keep taking rounds.
I
> >> think I will need to rewrite the scheduler (interrupt routine) in
> >> assembly for it to work correctly.
> >>
> >> The context is not saved/restored correctly yet (STATUS, FSR,
etc.),
> >> only the PC.
> >>
> >
> > Sorry to be a bit negative, but this only works as well as it does
> > because your tasks are so simple.  You are saving the return address
at
{Quote hidden}

preemptive
> and collaborative.
> Preemption may happen just at specific points (when the macro is
> called), but only if the tick has elapsed, unlike a "Yield" that
forces
> a switch every time it is called.

I see, I didn't realise that you intended placing multiple calls to the
Sw macro within a task.  If I understand correctly, your scheme forces a
task to run for a minimum amount of time, i.e. the first Sw() that is
encountered AFTER this period will force a context switch?

Seems you could add similar functionality to a purely cooperative system
by checking if enough time had elapsed within the "yield" macro prior to
saving context and jumping to the next task?  

Regards

Mike

=======================================================================
This e-mail is intended for the person it is addressed to only. The
information contained in it may be confidential and/or protected by
law. If you are not the intended recipient of this message, you must
not make any use of this information, or copy or show it to any
person. Please contact us immediately to tell us that you have
received this e-mail, and return the original to us. Any use,
forwarding, printing or copying of this message is strictly prohibited.
No part of this message can be considered a request for goods or
services.
=======================================================================

2009\05\26@231652 by Isaac Marino Bavaresco

flavicon
face
Michael Rigby-Jones escreveu:
{Quote hidden}

Right!

> Seems you could add similar functionality to a purely cooperative system
> by checking if enough time had elapsed within the "yield" macro prior to
> saving context and jumping to the next task?  
>
>  

Right again!

> Regards
>
> Mike
>  

__________________________________________________
Faça ligações para outros computadores com o novo Yahoo! Messenger
http://br.beta.messenger.yahoo.com/

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