To LUGNET HomepageTo LUGNET News HomepageTo LUGNET Guide Homepage
 Help on Searching
 
Post new message to lugnet.robotics.rcx.legosOpen lugnet.robotics.rcx.legos in your NNTP NewsreaderTo LUGNET News Traffic PageSign In (Members)
 Robotics / RCX / legOS / 1762
1761  |  1763
Subject: 
Kernel proposal - message passing and signals
Newsgroups: 
lugnet.robotics.rcx.legos
Date: 
Tue, 13 Mar 2001 13:47:28 GMT
Viewed: 
1451 times
  
Hi,

    I have been poking around in the legOS kernel and it appears that there
is no formal way to pass messages between tasks - only shared protected
resources through semaphores. I intend to modify the kernel to add the
features descried below. Note that none of this has been tested yet,
and I have probably got some of the wakeup stuff wrong...

- each pdata_t will have three additional fields: waitbits, sigbits
  and lockedbits. waitbits contains the "signal bits" the task is
  waiting for, sigbits contains the bits it has been sent and
  lockedbits contains a record of the signals the task has allocated
  (for waiting on messages, signals from other tasks and stuff).

- two functions, alloc_sig() and free_sig() to allocate and free
  signal bits in the task structure. These use lockedbits to see
  which isgnals are free..

- a function send_sig(pid, signum) which sets the signum bit in
  the sigbits field of the specified task.

- a new structure:

struct _message_t {
    struct _message_t *next;
    struct _message_t *prev;

    struct _message_port_t *replyport; // allow for synchronsiation

    int message_id;   // General purpose id, user controlled
}

#typedef struct _message_t message_t

- a new list, msg_ports, of these structures :

struct _message_port_t {
    struct _message_port_t *next;
    struct _message_port_t *prev;

    struct _message_t *messages;

    char *name;

    struct _pdata_t *task;
    byte signum;
}

#typedef struct _message_port_t message_port_t

- two functions alloc_mp() and free_mp() which create new message
  ports, allocate a signal in the parent task and link into the
  kernel mp list.

- a functions find_msg_port(char *) which returns a pointer to the
  message port with the specified name.

- a new wakeup function:

static wakeup_t tm_waitsig_wakeup(wakeup_t data) {
    return cpid -> waitbits & cpid -> sigbits;
}

- and a new sleep:

unsigned int waitsig(byte signals)
{
    cpid -> waitbits = signals;
    cpid -> sigbits  = 0;

    return wait_event(&tm_waitsig_wakeup, 0);
}

(note that you can use the return value from this to work
out which signal(s) woke you up..)

- a put_msg(message_port_t, message_t) function which
  adds the message to the list of messages in the port and
  then uses send_sig() to signal the port owner task.

- a get_msg(message_port_t) which fetches each message
  in turn from the port.

- a reply_msg(message_t) which does the same same thing
  as put_msg() but the message port used is the one in
  message_t -> replyport


How does this work? Well, say that we have two tasks
A and B. They both understand the structure:

struct _exampleData {
    message_t exampleMsg;

    int dataA;
    int dataB;
    int result;
}

#typedef struct _exampleData exampleData

task A does:

     message_port_t myMP = alloc_mp("PORTA");

     if(myMP) {
       while(something isn't true) {
            sigs = waitsig(1 << myMP -> signum);

            if(sigs & (1 << myMP -> signum)) {
                while(myMsg = (exampleData *)get_msg(myMP)) {
                    myMsg -> result = myMsg -> dataA + myMsg -> dataB;
                    reply_msg((message_t)myMsg);
                }
            }
        }
     }

task B can then do something like:

     message_port_t waitMP = alloc_mp("PORTB");

     if(waitMP) {
         if(newMsg = (exampleData *)calloc(1, sizeof(exampleData))) {
             newMsg -> dataA = 10;
             newMsg -> dataB = 20;
             newMsg -> exampleMsg -> replyport = waitMP;

             if(aMP = find_msg_port("PORTA")) {
                 put_msg(aMP, (message_t)newMsg);
                 waitsig(1 << waitMP -> sigbit);

                 lcd_int(newMsg -> result);

            // now clean up...

Any comments, suggestions? Is this of interest to anyone else?



1 Message in This Thread:

Entire Thread on One Page:
Nested:  All | Brief | Compact | Dots
Linear:  All | Brief | Compact
    

Custom Search

©2005 LUGNET. All rights reserved. - hosted by steinbruch.info GbR