Re: Do I need a RTOS?
- From: Jonathan Kirwan <jkirwan@xxxxxxxxxxxxxx>
- Date: Wed, 24 Dec 2008 08:09:51 GMT
On Tue, 23 Dec 2008 22:31:13 -0600, "eeboy" <jason@xxxxxxxxxxxxxxxx>
wrote:
That was an excellent example! It makes a lot of sense to me and I can't
see any immediate flaws with my intended application in mind. It also seems
'simple' enough that I can write it without investing a great deal of time.
I think I'll use that as my starting point. I am very much in agreement
with your comment on rolling your own. It's always been much more difficult
for me to inherit code or use others code than it is to make my own (within
reason of course). I'll get the benefit of learning how it works and what
it's positive and negative attributes are.
Daring to assume you are responding to me, see replies below:
Just a few questions about implementation of such a scheme...
1) Are there any stats besides the number of items presently in the queue
that would be helpful to maintain?
A singly-linked list of function addresses and delay times is probably
fine, given that I know nothing much more about your application.
2) I would envision using malloc and memcpy to implement the queue. Are
these appropriate (efficient enough) in the embedded world? I would assume
so but...
My own penchant would be to entirely avoid malloc and its ilk.
Instead, I would make an educated guess about how many slots you will
need and allocate them as an array. More efficient, as compilers can
readily convert some of the references to elements to direct memory
references. And you get compile-time errors instead of run-time
errors you would have no idea what to do with if you got them at that
time.
I'd recommend that your array/list be arranged into three semantic
regions -- the head of one "eating" the tail of the next, in a sense.
Every slot in the list should be in one of three conceptual queues
(although they are all in the same physical array):
(1) the "avail" list of slots that can be used to add a new
function to be called later;
(2) the "sleep" list of functions that are still waiting for
their time to come; and
(3) the "ready" list of functions that have timed out but
have not yet been executed.
The three queue-head pointers are used to reference the first entry in
their particular queue. All linked entries in the chain, following
the one indicated by the queue-head, belong to that queue until the
first entry of the adjacent queue is seen. If two adjacent queue
heads reference the same entry then the "earlier" queue-head owns an
empty queue. I hope that's plain enough. But just to be certain,
examine the following diagram for clarification.
Sleep ---------------------------------> -> [] -> [] -> [] -
/ |
Ready -------------> -> [] -> [] -> [] - |
/ |
Avail ---> [] -> [] - |
|
^ |
|_________________________________________________|
The queue-head pointers can be advanced in only one direction. For
example, it is illegal to move an entry from the sleep-queue to the
avail-queue by backing up the avail-queue's "head." Instead, the
entry must be moved from the sleep-queue to the ready-queue first, by
advancing the sleep-queue "head." The avail-queue "head" is advanced
when a new entry is inserted into the sleep queue. The ready-queue
"head" is advanced when a function that is ready to execute has been,
in fact, executed. The sleep-queue "head" is advanced when an entry
has timed-out and is now ready to be executed.
A queue is empty when its "head" runs up against the following queue's
"head" (as I already mentioned.) So, the avail-queue is empty when
the avail-queue's "head" is equal to the ready-queue's "head". The
ready-queue "follows" the avail-queue. (Kind of like the scissors
paper rock game.)
If you follow this, so far, it's appropriate to examine the possible
"states" of the three queues to point out an important design issue.
Each queue may be either empty or not empty. With three queues, this
leads to eight states. The following table shows the different
combinations and compares the associated "head" pointers for the
queues with each other. I've used a (+) to indicate a non-empty queue
and a (-) to indicate an empty one.
Sleep Ready Avail Pointer conditions Description of condition
--------------------------------------------------------------------
- - - A==R, R==S, S==A Meaningless
+ - - A==R, R==S, S==A All slots are sleeping
- + - A==R, R==S, S==A All slots are ready to run
- - + A==R, R==S, S==A All slots are available
- + + A<>R, R<>S, S==A No slots are sleeping
+ - + A<>R, R==S, S<>A No slots are ready to run
+ + - A==R, R<>S, S<>A No slots available
+ + + A<>R, R<>S, S<>A No empty queues
As you can see, four of the states are indistinguishable from each
other if the only thing you do is compare pointers. This problem can
easily be resolved by insisting that the avail-queue never be allowed
to become empty (a simpler choice than keeping either of the other two
queues non-empty.) With that assertion made, we can conclude that
when the three queue head-pointers are equal to each other, the
avail-queue is full and the other two queues are empty.
I'd use at least three subroutines to manage the three queues: an
insert function which moves entries from the avail-queue to the
sleep-queue by advancing the head-pointer of the avail-queue; an
execute function which moves entries from the ready-queue to the
avail-queue by advancing the head-pointer to the ready-queue, and the
"Timer" function moves entries from the sleep-queue to the ready-queue
by advancing the head-pointer to the sleep-queue. These three
functions have exclusive access to the head-pointer of the their
respective queues and this design decision is crucial to removing the
need for interrupt masking in order to protect the data structures
from concurrency/re-entrancy problems.
Also, any recommended books on this subject matter (keeping in mind that I
have zero experience in this realm)?
Hmm. I first read the term "delta queue" in a book by Douglas Comer
in 1984 called "Operating System Design - The XINU Approach." Look on
this web page, 2nd item down, for it:
http://www.cs.purdue.edu/homes/dec/osbooks.html
There are subsequent books on XINU, but none so clear and easy to read
as the first one.
Jon
.
- Follow-Ups:
- Re: Do I need a RTOS?
- From: eeboy
- Re: Do I need a RTOS?
- From: Jonathan Kirwan
- Re: Do I need a RTOS?
- References:
- Do I need a RTOS?
- From: eeboy
- Re: Do I need a RTOS?
- From: eeboy
- Do I need a RTOS?
- Prev by Date: Re: USART communication in PIC
- Next by Date: Re: Engineering on the fly
- Previous by thread: Re: Do I need a RTOS?
- Next by thread: Re: Do I need a RTOS?
- Index(es):
Relevant Pages
|