Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
20 years ago

Message boxes in eCos

Hi all,

cyg_mbox_peek (), is always returning the count 1 less than the actual number of messages in the message box. When the message box is empty, then count is returned as 0. Why this is so?

I am attaching the code below for reference.

With regards,

Sanjay

/* **** Include standard header files **** */# include <cyg/kernel/kapi.h># include <cyg/infra/diag.h>

/* **** Constants **** */# define TRUE 1

/* Size of a task&#39;s stack */# define STACKSIZE (CYGNUM_HAL_STACK_SIZE_TYPICAL + 4096)# define NTHREADS 2 /* No. of threads */

/* **** User-defined data types **** */

typedef char stack_t; /* Each stack entry is 8-bit wide */

/* **** Function prototypes **** */

void task_a (cyg_addrword_t);

void task_b (cyg_addrword_t);

/* **** Gobal variables **** */

cyg_thread task_housekeeping_info[NTHREADS];

stack_t task_stack[NTHREADS+1][STACKSIZE];

cyg_handle_t mbox_handle;

cyg_mbox mbox;

int msg1=12, msg2=24;

/* Startup function */

void cyg_user_start ()

{

cyg_handle_t task_handle[NTHREADS];

cyg_mbox_create (&mbox_handle, &mbox);

cyg_thread_create (0, task_a, (cyg_addrword_t) 0, "task_a",

(void *) task_stack[0], STACKSIZE, &task_handle[0],

&task_housekeeping_info[0]);

cyg_thread_create (0, task_b, (cyg_addrword_t) 1, "task_b",

(void *) task_stack[1], STACKSIZE, &task_handle[1],

&task_housekeeping_info[1]);

cyg_thread_resume (task_handle[0]);

cyg_thread_resume (task_handle[1]);

cyg_scheduler_start ();

}

void task_a (cyg_addrword_t data)

{

cyg_bool_t stat;

long count;

// Run this thread forever.

while (TRUE)

{

// Delay for 1000 ticks.

cyg_thread_delay (1000);

count = cyg_mbox_peek (mbox_handle);

diag_printf ("Count = %ld\n", count);

// Send a message to Thread B.

cyg_mbox_put (mbox_handle, &msg1);

cyg_mbox_put (mbox_handle, &msg1);

count = cyg_mbox_peek (mbox_handle);

diag_printf ("Count = %ld\n", count);

}

}

void task_b (cyg_addrword_t data)

{

void *message;

// Run this thread forever.

while (TRUE)

{

// Wait for the message.

message = cyg_mbox_get (mbox_handle);

// Make sure we received the message before attempting to process it.

if (message != NULL)

{

// Process the message.

diag_printf ("Message: %d\n", *((int*)message));

}

}

}

3 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    originally posted by sanjay822@Dec 22 2005, 08:45 AM

    hi all,

    cyg_mbox_peek (), is always returning the count 1 less than the actual number of messages in the message box. when the message box is empty, then count is returned as 0. why this is so?

    i am attaching the code below for reference.

    with regards,

    sanjay

    /* **** include standard header files **** */# include <cyg/kernel/kapi.h># include <cyg/infra/diag.h>

    /* **** constants **** */# define true 1

    /* size of a task&#39;s stack */# define stacksize (cygnum_hal_stack_size_typical + 4096)# define nthreads 2 /* no. of threads */

    /* **** user-defined data types **** */

    typedef char stack_t; /* each stack entry is 8-bit wide */

    /* **** function prototypes **** */

    void task_a (cyg_addrword_t);

    void task_b (cyg_addrword_t);

    /* **** gobal variables **** */

    cyg_thread task_housekeeping_info[nthreads];

    stack_t task_stack[nthreads+1][stacksize];

    cyg_handle_t mbox_handle;

    cyg_mbox mbox;

    int msg1=12, msg2=24;

    /* startup function */

    void cyg_user_start ()

    {

    cyg_handle_t task_handle[nthreads];

    cyg_mbox_create (&mbox_handle, &mbox);

    cyg_thread_create (0, task_a, (cyg_addrword_t) 0, "task_a",

    (void *) task_stack[0], stacksize, &task_handle[0],

    &task_housekeeping_info[0]);

    cyg_thread_create (0, task_b, (cyg_addrword_t) 1, "task_b",

    (void *) task_stack[1], stacksize, &task_handle[1],

    &task_housekeeping_info[1]);

    cyg_thread_resume (task_handle[0]);

    cyg_thread_resume (task_handle[1]);

    cyg_scheduler_start ();

    }

    void task_a (cyg_addrword_t data)

    {

    cyg_bool_t stat;

    long count;

    // run this thread forever.

    while (true)

    {

    // delay for 1000 ticks.

    cyg_thread_delay (1000);

    count = cyg_mbox_peek (mbox_handle);

    diag_printf ("count = %ld\n", count);

    // send a message to thread b.

    cyg_mbox_put (mbox_handle, &msg1);

    cyg_mbox_put (mbox_handle, &msg1);

    count = cyg_mbox_peek (mbox_handle);

    diag_printf ("count = %ld\n", count);

    }

    }

    void task_b (cyg_addrword_t data)

    {

    void *message;

    // run this thread forever.

    while (true)

    {

    // wait for the message.

    message = cyg_mbox_get (mbox_handle);

    // make sure we received the message before attempting to process it.

    if (message != null)

    {

    // process the message.

    diag_printf ("message: %d\n", *((int*)message));

    }

    }

    }

    <div align='right'><{post_snapback}> (index.php?act=findpost&pid=11736)

    --- quote end ---

    --- Quote End ---

    Sanjay,

    have a look on page 75/76 in the "eCos Reference Manual":

    cyg_mbox_get () is a blocking function. The thread is woken up immediately after the 1. call of cyg_mbox_put () and empties the mailbox.

    the 2. cyg_mbox_put () increments the counter again to "1".

    I am using a "timed put " to send and a "try get" to read for not blocking the threads.

    Also an additional acknowledge flag is usful to synchronize the threads.

    Regards,

    Sepp
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    --- Quote Start ---

    Hi,

    Thanks Sepp for your suggestion.

    The program is giving correct results now, using cyg_mbox_tryget () instead of cyg_mbox_get (). But still I have one doubt. The reason that you had specified for cyg_mbox_get () is okay, but then using that concept cyg_mbox_peek () would always had returned the count as 0?

    With regards,

    Sanjay
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hi,

    Thanks Sepp for your suggestion.

    The program is giving correct results now, using cyg_mbox_tryget () instead of cyg_mbox_get (). But still I have one doubt. The reason that you had specified for cyg_mbox_get () is okay, but then using that concept cyg_mbox_peek () would always had returned the count as 0?

    With regards,

    Sanjay

    Sanjay,

    I am not using the function cyg_mbox_peek () so I have no idea.

    What I am doing is something like this and it works fine:

    sending thread:

    while(1)

    {

    ...

    // when a message should be sent:

    if(!cyg_mbox_timed_put(mbox_hdl,(void *)psMsg1,1000))

    {

    psMsg1 = NULL;

    // Do something to resend the message

    }

    else

    {

    // wait for acknowledge

    ret = cyg_flag_wait(&FlgAckMsg,FLG_MBOX_ACK,CYG_FLAG_WAITMODE_AND | CYG_FLAG_WAITMODE_CLR);

    }

    ...

    }

    receiving thread:

    while(1)

    {

    ...

    // allways have a look if there is a new message

    pMsg= cyg_mbox_tryget(mbox_hdl);

    if(pMsg2 != NULL)

    {

    save message:

    // Saving the message data into a local struct

    acknowledge:

    cyg_flag_setbits(&FlgAckMsg,FLG_MBOX_ACK);

    work with received data:

    // Decoding the received message and do some action with it

    }

    ...

    }

    Regards,

    Sepp