This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Sys/Bios Queue



Hello, everyone.

I am trying to get familiar with Sys/bios. So I read the sys/bios user guide. My aim for now is synchronization modules. Mailbox is easy to understand. But I don`t completely understand, what must be queue  used for. In freeRTOS you usually use them to send a message from one task to another(like mailboxes in Sys/bios). 

As I understand you can do this in sys/bios too, if you use the structures like this

typedef struct MsgObj {
             Queue_Elem elem;             /* first field for Queue */
             unsigned int val;                   /* message value */
} MsgObj, *Msg;

, but what is Queue_Elem elem? Does it have some functionality?

I hope my question is not very chaotic. I want to use all the possibilities Sys/bios gives us.

Best Regards,

Yevhen

  • Hi Yevhen,

    The Mailbox module is copy based. So when Mailbox_post is called, the message is copied into the Mailbox object's internal buffer (number of messages is determined by numMsgs and the size of a message is determined by msgSize in the Mailbox_create). When Mailbox_pend is called, the message is copied into the buffer supplied in the Mailbox_pend call.

    The Queue module is a doubly-linked list module. The first two fields of a Queue_Elem is a next and prev pointer. The Queue_put atomically pushes the buffer onto the tail of the linked list (and adjusts the prev and next pointers accordingly). Note: the buffer must have a Queue_Elem structure at the top. The rest of the buffer is ignored by the Queue module. The Queue_get pops the buffer off the head of the linked-list (and adjusts next and prev pointers accordingly). Note this is done without copying the buffer.

    The Queue module has the typical link-list APIs (Queue_insert to insert into a list, Queue_empty to see if it is empty, Queue_next/prev for traversal, etc.)

    fyi...the Mailbox module uses Queue to maintain both a "free" msg linked list and a "full-data" msg linked list.

    Todd

  • HI, Todd,

    Thank you for your answer. It is very good explanation, but I am still a little bit confused. You said,  "The rest of the buffer is ignored by the Queue module." But, as I understand, Queue_Elem itself doesn`t contain any useful information. So my question would be - in what cases do I need to use queue? How can it help me?

    Thank you,

    Yevhen

  • To put anything onto a Queue, it must have a Queue_Elem in the structure (generally at the top to make it easier). For example, I could have the following structure:

    typedef struct myMsg {
        Queue_Elem elem;
        char buffer[128];
        UInt cmd;
        ...
    } myMsg;

    myMsg msg;

    I could put the message on the a Queue now (assuming myQueue is queue that has been created):

        Queue_put(myQue, &msg);

    The Queue module will only act on the prev and next in the Queue_Elem fields. It does not touch, or even know about the other fields (i.e. buffer, cmd, ...).

    So to answer your question, yes, a Queue_Elem does not contain any useful "application" fields, but you can use it inside your structure, which does contain useful application fields. There are lots of use cases for linked list module. If you want to have a driver queue up received data for a Task, you can use a Queue. The driver puts items on the Queue and then posts a semaphore that the Task is pending on. The Task then calls Queue_get to get the pointer. The linked list allows the driver to link up multiple buffers for the Task to consume.

    Todd

  • Thank you, Todd

    Now it`s clear enough.