Help with small kernel..

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
Hi, I'm writing a little "kernel" for a small microprocessor.
Right now it just implements tasks, and does scheduling.
That is , I have a timer fire every ms in which the interrupt
handler sets up the kernel stack and pc, and the "kernel"
merly checks if the current task has reached its timeslice.
Now I want to do some abstractios over events.For now interrupts,
but have no idea what that takes. One of the interrupts signals
the press of a button, I want tasks to wait on such an event.
Whats the basis of doing that ? I'd like the interrupt handlers
as small as possible.
One solution I can think of is to let the interrupt handler append
events to a queue, and on each kernel tick check the event queue
and if there are any task waiting.. but that seems odd. And
rather high latency since little happens until my 1 ms tick.
Basically, how to make tasks wait for events, and how to let
interrupt handlers signal that an event happened.


Re: Help with small kernel..
Message que seems like one possible answer, I know that
things like this are oftenly done (waiting for a event) in a way that
your function (for example wait_button()) returns 0 if button wasn't
pressed and returns 1 if button was pressed. And in your task you would
have something like:

function task_keypad()
{
  if (wait_button())
  {
      ...
      do_button_routine
      ...
  }
}

I have seen this kind of event handling in Dynamic C (for Rabbit
processors).

Mickey



Re: Help with small kernel..
Quoted text here. Click to load it
This is no problem. The problem is what does the wait_button() do.
How and when should my "kernel" handle the(for this example) button event,
what should the interrupt handler for the button do.


Re: Help with small kernel..

Quoted text here. Click to load it

wait_button() sees if there's an unhandled button event that needs
processed.  If there is, the code proceeds without delay.  If not, it
suspends (moves them to the waiting queue) the current task and appends
itself onto the list of tasks waiting for a button event.

The interrupt handler for the button handles the hardware and flags the OS
that a button event has occured.

The OS scheduler, when it gets a button event, sees if there are any
processes that are suspended waiting for a button event.  If there are,
those processes are moved to the ready queue.

Almost any college OS text in the last 20 years covers this in detail.

Kelly



Re: Help with small kernel..
snipped-for-privacy@frisurf.no  wrote in message
Quoted text here. Click to load it

When faced with the task of making a very simple kernel for a
nonetheless significant project, I chose to abandon the system tick as
a basis for task context switch. Instead, the "wait for event queue
non-empty" primitive was used as the primary task synchronization
feature. The interrupt service routines do indeed insert events in
queues as your post suggests.

This is now part of the ABCD Proto-Kernel(tm) at
http://www.connotech.com/abcd_proto_kernel/abcd_proto_kernel_intro.htm


- Thierry Moreau

CONNOTECH Experts-conseils inc.
9130 Place de Montgolfier
Montreal, Qc
H2M 2A1

Tel.: (514)385-5691
Fax:  (514)385-5900

e-mail: snipped-for-privacy@connotech.com

Re: Help with small kernel..
Quoted text here. Click to load it
Thanks, I'll take a look at it.

Re: Help with small kernel..
snipped-for-privacy@connotech.com (Thierry Moreau) writes:

Quoted text here. Click to load it

I haven't a wide experience with embedded systems, but the system tick
concept always seemed a bit odd to me.  One OS we dealt with was
slightly annoying since the system tick functionality stole a very
useful timer.

Basic semaphores, of the type that have been around for many decades,
solve the problem.  A task waits on a semaphore and is suspended, and
the interrupt signals the semaphore which may cause it to wake up.
The implementation isn't hard.  Each semaphore has a list or array of
tasks waiting on it, and when it's signaled one of the tasks becomes
runnable again.  At the end of the interrupt the task with the highest
priority is resumed, which may not necessarily be the task that was
interrupted.

All other synchronization or IPC mechanisms can be built on top of a
semaphore primitive, such as message queues.

--
Darin Johnson
    "Floyd here now!"

Re: Help with small kernel..
Quoted text here. Click to load it
Thanks for all the great info folks.
Are there any good online material on this ? I'd rather
take pointers from folks who have been there instead
of googling myself to death ;)


Re: Help with small kernel..
Quoted text here. Click to load it
Take a look at http://sourceforge.net/projects/xmk/.  It has a preemptive
priority based scheduler.  It should give you some ideas on how to 'wake-up'
threads from an interrupt services without having to check state of every
thread on every interrupt.

Re: Help with small kernel..
Quoted text here. Click to load it

The classic mechanism is a semaphore.  A task does a "P" (pend)
operation on a semaphore.  If the semaphore count is zero, the task is
suspended.  One implementation is for the semaphore to point to a queue
of tasks waiting on the semaphore.  Waiting tasks should be queued in
priority order.

An interrupt routine can activate a task by performing a "V" operation
on a semaphore.  If any tasks are waiting on it, the OS then makes the
highest priority task ready to run.  If the newly ready task has a
higher priority than the task which was running when the interrupt
occurred, the active task indicator is changed.  

In order to accomplish this with multiple interrupt nesting allowed,
usually the interrupt handler increments the interrupt nesting level.
When exiting the interrupt, the OS decrements the nesting level.  If it
is non-zero, the normal return is made.  If zero, the check is made for
task switch.  If none, a normal exit is done.  If switching occurred,
magic happens: it saves the state of the old task in its TCB and then
performs a return from interrupt which resumes the newly active task.

The activation can be done without semaphores by having the interrupt
routine directly activate a given task.

All this must be done with careful consideration of what code can be
interrupted and what must be protected.  If interrupts are disabled for
too long, interrupt latency suffers.  

Thad

Re: Help with small kernel..
Quoted text here. Click to load it

IMHO, with a multi-threaded system available, there is very little
real need for nested interrupts. An equivalent mechanism can be
built with high-priority threads doing the lengthy parts of
the interrupt service. In an interrupt handler, the only really
necessary things to take care of are: acknowledging the hardware
so that it drops the interupt request, and signaling the handler
thread. One example of this kind of handling is the 'bottom half'
of a Linux driver interrupt handling.

The nested interrupts very often create more problems than
solutions. The necessary overhead can easily waste more
processing power than the advantages of the nesting.

Been there - made it (since 1973).

Tauno Voipio
tauno voipio @ iki fi





Re: Help with small kernel..

Quoted text here. Click to load it

    This problem has been thoroughly thought out and solved with a simple
round-robin multitasker in Forth.  Free with most/many variants.  Whenever
a 'pause' is encoutered the cooperative multitasker relinquishes control
to the next task.  If that task is sleeping then the cost is a simple jump
instruction to the next task.

    Any task can put any other task to sleep, wake another task, or add a
task.  Pre-emptive multitaskers usually have a lot of overhead to consider.

 
-- Regards, Albert
----------------------------------------------------------------------
AM Research, Inc.                  The Embedded Systems Experts
http://www.amresearch.com 916.780.7623
----------------------------------------------------------------------


Re: Help with small kernel..
Quoted text here. Click to load it

Ever notice that virtually all programming
issues, especially embedded ones, were solved
years ago in Forth (:


Re: Help with small kernel..

Quoted text here. Click to load it

In this case, perhaps it is because multitasking has been
commonly available in Forth environments for a very long
time. Most commercial Forth cross compilers have always
supplied multitaskers as part of the standard package,
whereas even now this is not standard practice with C
compiler vendors.

Stephen
--
Stephen Pelc, snipped-for-privacy@INVALID.mpeltd.demon.co.uk
MicroProcessor Engineering Ltd - More Real, Less Time
We've slightly trimmed the long signature. Click to see the full one.

Site Timeline