11 years, 3 months ago.

rtos Mail query

Hi,

I've been looking at the RTOS Mail example code here:

http://mbed.org/handbook/RTOS

And testing a couple of things out.

If I have only two threads, and I only want to send one message at a time between threads, then is there any problem in me doing the following (note I've borrowed from the example):

#include "mbed.h"
#include "rtos.h"

/* Mail */
typedef struct {
  float    voltage; /* AD result of measured voltage */
  float    current; /* AD result of measured current */
  uint32_t counter; /* A counter value               */
} mail_t;

Mail<mail_t, 1> mail_box;
mail_t *mail;

void send_thread (void const *args) {
    uint32_t i = 0;
    while (true) {
        i++; // fake data update
        //mail_t *mail = mail_box.alloc();
        mail->voltage = (i * 0.1) * 33; 
        mail->current = (i * 0.1) * 11;
        mail->counter = i;
        mail_box.put(mail);
        Thread::wait(1000);
    }
}

int main (void) {
    mail = mail_box.alloc();
    Serial pc(USBTX,USBRX);
    pc.baud(115200);
    Thread thread(send_thread);
    
    while (true) {
        osEvent evt = mail_box.get();
        if (evt.status == osEventMail) {
            //mail_t *mail = (mail_t*)evt.value.p;
            printf("\nVoltage: %.2f V\r\n"   , mail->voltage);
            printf("Current: %.2f A\r\n"     , mail->current);
            printf("Number of cycles: %u\r\n", mail->counter);
            //mail_box.free(mail);
        }
    }
}

If I only have one item in the memory pool, then there isn't any point allocating space for it each time (unless space is exceptionally tight), which is why I've allocated it in main. Since memory is only allocated once, the memory pool address should never change, and consequently I shouldn't have to get it from evt.value.p (nor free it). Is my understanding here correct?

As an aside, I had actually expected that put() would block if the queue was full, but it doesn't, and it doesn't have a timeout. It does however return osErrorResource if the queue is full (btw, it would be good if the docs detailed return values, as I had to look this up in cmsis_os.h).

If I wanted to block forever on put() the most obvious thing to do is "while!=0" on its return value. However, this seems a bit CPU intensive. Is there a better way? How does the RTOS do this in the case of an osWaitForever get()?

Thanks

Ashley

Be the first to answer this question.