Yahoo Groups archive

AVR-Chat

Index last updated: 2026-04-28 22:41 UTC

Thread

Teenagers should write code.

Teenagers should write code.

2004-09-06 by Dave VanHorn

I just had one of those moments... :)

I came to the realization that the cooperative multitasking model that I've used as the core of my applications for years, is nothing more than how a teenager behaves.

When any chore is due: (system call to transmit a byte)
 First, find any possible reason NOT to do the chore. (Uart busy, Handshake asserted?)
 Second, see if it REALLY needs doing (anything to send?)
 If it absolutely can't be avoided, then do it. (start transmitting a byte, mark uart busy)

As a result, my systems spend most of their time spinning in a loop, doing nothing.
But, here is where they exhibit their most non-teenager behavior!
They are always looking for something to do.

But, that's only because they don't know anything else.

Re: Teenagers should write code.

2004-09-07 by Kathy Andrea Quinlan

--- In AVR-Chat@yahoogroups.com, Dave VanHorn <dvanhorn@d...> wrote:
> At 11:27 PM 9/6/2004, stevech wrote:

> I was just surprised that I hadn't made the connection before.

Dave, you just needed to realise that you had teenagers first ;)

Kat.

RE: [AVR-Chat] Teenagers should write code.

2004-09-07 by stevech

Adding events to unsuspend a task (process) in a cooperative multitasking
system can eliminate such polling.
Event triggers can come from an an interrupt or another task.
An example of such is OPEX for the AVR, in the AVRfreaks.net academy file
archives.
Show quoted textHide quoted text
-----Original Message-----
From: Dave VanHorn [mailto:dvanhorn@dvanhorn.org]
Sent: Monday, September 06, 2004 11:11 AM
To: Microcontroller discussion list - Public.
Cc: avR-Chat@yahoogroups.com
Subject: [AVR-Chat] Teenagers should write code.



I just had one of those moments... :)

I came to the realization that the cooperative multitasking model that I've
used as the core of my applications for years, is nothing more than how a
teenager behaves.

When any chore is due: (system call to transmit a byte)
 First, find any possible reason NOT to do the chore. (Uart busy, Handshake
asserted?)
 Second, see if it REALLY needs doing (anything to send?)
 If it absolutely can't be avoided, then do it. (start transmitting a byte,
mark uart busy)

As a result, my systems spend most of their time spinning in a loop, doing
nothing.
But, here is where they exhibit their most non-teenager behavior!
They are always looking for something to do.

But, that's only because they don't know anything else.





Yahoo! Groups Links

RE: [AVR-Chat] Teenagers should write code.

2004-09-07 by Dave VanHorn

At 11:27 PM 9/6/2004, stevech wrote:

>Adding events to unsuspend a task (process) in a cooperative multitasking
>system can eliminate such polling.

Well, you still have to poll the events somehow or other. 

>Event triggers can come from an an interrupt or another task.
>An example of such is OPEX for the AVR, in the AVRfreaks.net academy file
>archives.

I was just surprised that I hadn't made the connection before.

Re: Teenagers should write code.

2004-09-07 by Graham Davies

--- In AVR-Chat@yahoogroups.com, Dave VanHorn <dvanhorn@d...> wrote:

> At 11:27 PM 9/6/2004, stevech wrote:
> 
> > Adding events to unsuspend a
> > task (process) in a cooperative
> > multitasking system can
> > eliminate such polling.
> 
> Well, you still have to poll the
> events somehow or other. 

No, this is not true. My cooperative multi-tasking operating system, 
ECROS (see http://ecros.ecrostech.com), includes an event mechanism. 
There is no polling. When an event is sent to a task, the task is 
queued for execution if that event causes its ready condition to be 
satisfied. I suppose you could say that the queues are polled, but I 
think this would be stretching the definition of polling a bit far.

Graham.

Re: [AVR-Chat] Re: Teenagers should write code.

2004-09-07 by Dave VanHorn

>
>No, this is not true. My cooperative multi-tasking operating system, 
>ECROS (see http://ecros.ecrostech.com), includes an event mechanism. 
>There is no polling. When an event is sent to a task, the task is 
>queued for execution if that event causes its ready condition to be 
>satisfied. I suppose you could say that the queues are polled, but I 
>think this would be stretching the definition of polling a bit far.

Ok, so there is then a list of tasks that are ready to be executed, which you drop through. Eventually, you hit the end, and start over, or just sit in a loop waiting for more tasks to do?

How exactly do you "send" an event to a task?

In terms I'm familiar with (I'm an assembler kind of guy), I might be sending data to a UART.  

First, I'd check wether handshake allows anything to be sent.
sbis PORTA,HSIN
ret


Second, I'd check wether the UART is actively sending something.
SBIC Ser_Flags,SER_TX_Busy
ret


Third, I'd check wether there's anything in the serial out buffer, to send.
Point at buffer, call circ_get, returns carry set if nothing in the buffer, 
otherwise returns carry clear, and the next byte to send.
brcs to label with return

If all these tests pass, then I put the byte to send in a single SRAM location, set the baud rate timer (software UART) to a minimum interval to trigger a timer int, and exit.

The int then causes the start bit, data bits, and stop bit to be sent, then the uart is marked as "not busy".

RE: [AVR-Chat] Re: Teenagers should write code.

2004-09-07 by Larry Barello

AvrX (my RTOS) works similarly: there is no polling.  An event (implemented
as a call to the RTOS) causes some queues to shift and (potentially) a
different task is running upon exit.  Polling a bunch of bits in the depths
of a kernel is one way to do things, but not the only way.  Events are just
software interrupts and can be generated via either an interrupt handler or
another task.

In AvrX the interrupt handler usually just tickles an event and that wakes
up the task that does what it is suppose to do.  With serial I/O things are
a tad more complicated since you have to do something to make the interrupt
source go away (read or write the UDR).

In your example, below, things that don't generate interrupts need to be
polled.  There is no way to get around that.  In AvrX the way to handle that
is  to put a little code into the timer interrupt handler that generates the
"handshake" event when state changes and then have the task wait on the
handshake event.

Cheers!
----
Larry Barello
http://www.barello.net
Show quoted textHide quoted text
-----Original Message-----
From: Dave VanHorn

>
>No, this is not true. My cooperative multi-tasking operating system,
>ECROS (see http://ecros.ecrostech.com), includes an event mechanism.
>There is no polling. When an event is sent to a task, the task is
>queued for execution if that event causes its ready condition to be
>satisfied. I suppose you could say that the queues are polled, but I
>think this would be stretching the definition of polling a bit far.

Ok, so there is then a list of tasks that are ready to be executed, which
you drop through. Eventually, you hit the end, and start over, or just sit
in a loop waiting for more tasks to do?

How exactly do you "send" an event to a task?

In terms I'm familiar with (I'm an assembler kind of guy), I might be
sending data to a UART.

First, I'd check wether handshake allows anything to be sent.
sbis PORTA,HSIN
ret


Second, I'd check wether the UART is actively sending something.
SBIC Ser_Flags,SER_TX_Busy
ret


Third, I'd check wether there's anything in the serial out buffer, to send.
Point at buffer, call circ_get, returns carry set if nothing in the buffer,
otherwise returns carry clear, and the next byte to send.
brcs to label with return

If all these tests pass, then I put the byte to send in a single SRAM
location, set the baud rate timer (software UART) to a minimum interval to
trigger a timer int, and exit.

The int then causes the start bit, data bits, and stop bit to be sent, then
the uart is marked as "not busy".






Yahoo! Groups Links

Re: Teenagers should write code.

2004-09-07 by Graham Davies

--- In AVR-Chat@yahoogroups.com, Dave VanHorn <dvanhorn@d...> wrote:

> ... so there is then a list of tasks
> that are ready to be executed, which
> you drop through. Eventually, you hit
> the end, and start over, or just sit
> in a loop waiting for more tasks to do?

In ECROS, multiple lists (queues), one for each priority. You 
never "hit the end" because the idle task is always ready on the 
lowest priority queue.

> How exactly do you "send" an event to a task?

There is an ECROS function to do this.

> In terms I'm familiar with (I'm an
> assembler kind of guy), I might be
> sending data to a UART ...

In ECROS, you use a printf-like function specifying the UART stream 
as the destination. This returns "immediately", having stored the 
output text in a buffer. Interrupts move the text out of the buffer 
to the UART while you go about something else. The idea is that you 
don't have to worry about all the stuff you list.

If the point of your message is to take issue with my claim that it 
is not necessary to poll, then I give up. You win. It is possible to 
define polling such that polling is necessary. I don't care how; 
picking at terminology is not interesting to me.

Graham.

RE: [AVR-Chat] Re: Teenagers should write code.

2004-09-07 by Dave VanHorn

>
>In your example, below, things that don't generate interrupts need to be
>polled.  There is no way to get around that.  In AvrX the way to handle that
>is  to put a little code into the timer interrupt handler that generates the
>"handshake" event when state changes and then have the task wait on the
>handshake event.

Ok, so the timer isr would then be doing the polling, effectively, right?

As I understand it, you would do the status bit checking during the timer int, and say "task 6 and task 8 are ready to run", and I would assume, put their addresses on the stack in reverse order? (or something like that)

Cooperative RTOS ( was Re: Teenagers ...)

2004-09-07 by Graham Davies

--- In AVR-Chat@yahoogroups.com, Dave VanHorn <dvanhorn@d...> wrote:

> > > How exactly do you "send" an event to a task?
> > There is an ECROS function to do this.
> That didn't really illuminate much for me. :)

OK, sorry, Dave. In ECROS, every task has its own set of eight events 
it can respond to. When you call the OS function, you specify which 
task you want to target and which events you want to send. The new 
events are combined with any previously existing events and compared 
to an OS-wide condition for task readiness. The default condition is 
that any of four events are set or either of two pairs of the others. 
If the task is ready, it is placed on the queue corresponding to its 
priority. When the scheduler runs the task, the events are passed to 
the task function. The task can also inspect and clear events using 
other OS functions.

ECROS events can be sent directly from an OS function, delayed by a 
timer, repeatedly by a recurring timer, attached to a message and 
from an interrupt.

> > In ECROS, you use a printf-like function ...
> Ok, that's very similar to what I do...
> but of course it's possible to get stuck
> with a 10 char message, and a 9 char buffer.
> ... I don't have an elegant handler for that. 

Neither do I. If your intent is not to block on UART output, you're 
doomed to design the system to accomodate the UART data rate and any 
limit on the buffering you can afford. The best thing to do is never 
try to send more than will fit in the buffer. Once you've done that, 
you can (using ECROS) avoid sending anything else until you get the 
event that means the buffer is empty. This is an order of magnitude 
more complicated for the user than anything else in ECROS (except for 
addressing the same problem with UART reception) so I wouldn't call 
it elegant.

> > If the point of your message is to take issue ...
> Not at all!

OK, sorry. Just making sure.

Graham.

Re: [AVR-Chat] Re: Teenagers should write code.

2004-09-07 by Dave VanHorn

>
>> How exactly do you "send" an event to a task?
>
>There is an ECROS function to do this.

That didn't really illuminate much for me. :)

>In ECROS, you use a printf-like function specifying the UART stream 
>as the destination. This returns "immediately", having stored the 
>output text in a buffer. Interrupts move the text out of the buffer 
>to the UART while you go about something else. The idea is that you 
>don't have to worry about all the stuff you list.

Ok, that's very similar to what I do, I try to decouple the tasks as much as possible.
What happens when the message is larger than the space in the target buffer?
I have a function that returns the chars free in a buffer, but of course it's possible to get stuck with a 10 char message, and a 9 char buffer.  At the moment, I don't have an elegant handler for that. 

>If the point of your message is to take issue with my claim that it 
>is not necessary to poll, then I give up. You win. It is possible to 
>define polling such that polling is necessary. I don't care how; 
>picking at terminology is not interesting to me.

Not at all!  
I'm just not used to the terminology that you're using, and trying to compare it to what I do know.

Re: [AVR-Chat] Re: Teenagers should write code.

2004-09-07 by Dave VanHorn

>
>If the point of your message is to take issue with my claim that it 
>is not necessary to poll, then I give up. You win. It is possible to 
>define polling such that polling is necessary. I don't care how; 
>picking at terminology is not interesting to me.

If I'm understanding it right, in your case, a timer schedules your re-evaluation of which tasks should be running/queued.  During that timer int, you do what I do, in that you examine semaphores to see what's ready, what's done, what's empty, etc..
(pre-emptive multitasking?)

In my case, I run a task to completion, with an eye to completing it as soon as possible.
When any task ends, then in the case of a round-robin, the next task tries to run.
If it can't proceed for whatever reason, then I pass to the next task, and so on. 
Interrupts, in my case, are either a system timer (clock-ish timekeeping) or physical events.
(cooperative multitasking)

I arrange the order of my tasks in the round-robin system such that the low level functions happen first, then the higher levels, because the higher levels depend on events that happen in the lower levels.

Alternately, I can re-start from the beginning in which case high priority tasks (those that sit early in the idle loop) can prevent lower priority tasks from running by chewing up all the time.

ECROS (was Re: Teenagers ...)

2004-09-07 by Graham Davies

--- In AVR-Chat@yahoogroups.com, Dave VanHorn <dvanhorn@d...> wrote:

> ... in your case [ECROS], a timer schedules
> your re-evaluation of which tasks should be
> running/queued.  During that timer int, you
> do what I do, in that you examine semaphores
> to see what's ready, what's done, what's empty,
> etc.. (pre-emptive multitasking?)

I hope I'm not getting this thread mixed up. Assuming you were still 
replying to me, Dave, the answer is no, the ECROS kernel is 
cooperative, like yours. So, the OS adds tasks to queues only when 
events make them ready and once added they make their way to the head 
until they are removed and run.

> In my case, I run a task to completion, with
> an eye to completing it as soon as possible.

Same with ECROS.  A task has a function associated with it and it 
yields the CPU by returning from that function. The function bound to 
the task can be changed at run time, which makes for very neat state 
machines.

> When any task ends, then in the case of a
> round-robin, the next task tries to run.
> If it can't proceed for whatever reason,
> then I pass to the next task, and so on.

The ECROS scheduler just goes back to examining the queues. It will 
never meet a task that is not ready to run as such a task will not be 
in a queue. I have no strict round-robin, but first-come-first-served 
queuing within a priority level has a similar effect.

> Interrupts, in my case, are either a system
> timer (clock-ish timekeeping) or physical events.

Same with ECROS.

> I arrange the order of my tasks in the
> round-robin system such that the low
> level functions happen first, then the
> higher levels, because the higher levels
> depend on events that happen in the lower
> levels.

ECROS supports multiple task priorities with any number of tasks at 
any given priority so the ordering of execution is fully dynamic.

> Alternately, I can re-start from the
> beginning in which case high priority
> tasks (those that sit early in the idle
> loop) can prevent lower priority tasks
> from running by chewing up all the time.

In ECROS it is also possible for high priority tasks to lock out the 
low priority ones. I don't know that this needs fixing in the OS. If 
this happens, it's probably the application that's at fault. If a 
task hogs the CPU for too long in a single stretch, ECROS resets the 
system using the watchdog timer.

Graham.

Move to quarantaine

This moves the raw source file on disk only. The archive index is not changed automatically, so you still need to run a manual refresh afterward.