Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.

Message boxes in eCos

Altera_Forum
Honored Contributor II
1,408 Views

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)); 

}
0 Kudos
3 Replies
Altera_Forum
Honored Contributor II
714 Views

 

--- 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
0 Kudos
Altera_Forum
Honored Contributor II
714 Views

 

--- 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
0 Kudos
Altera_Forum
Honored Contributor II
714 Views

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
0 Kudos
Reply