• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Queue<a name="EN-US_TOPIC_0000001078912736"></a>
2
3-   [Basic Concepts](#section81171363232)
4-   [Working Principles](#section1074515132316)
5    -   [Queue Control Block](#section194431851201315)
6    -   [Working Principles](#section89875741418)
7
8-   [Development Guidelines](#section827981242419)
9    -   [Available APIs](#section19327151642413)
10    -   [How to Develop](#section1390154210243)
11
12-   [Development Example](#section27132341285)
13    -   [Example Description](#section197311443141017)
14    -   [Sample Code](#section972214490107)
15    -   [Verification](#section19287165416106)
16
17
18## Basic Concepts<a name="section81171363232"></a>
19
20A queue, also called a message queue, is a data structure used for communication between tasks. The queue receives messages of unfixed length from tasks or interrupts, and determines whether to store the transferred messages in the queue based on different APIs.
21
22Tasks can read messages from a queue. When the queue has no messages, the tasks are suspended. When the queue has a new message, the suspended tasks are woken up and process the new message. Tasks can also write messages to the queue. When the queue is full, the write task is suspended. When there is an available message node in the queue, the suspended write task is woken up and writes a message.
23
24You can adjust the timeout period of the read queue and write queue to adjust the block mode of the read and write APIs. If the timeout period is set to  **0**  for the read queue and write queue, tasks will not be suspended and the API directly returns. This is the non-block mode. If the timeout period is greater than  **0**, block mode is used.
25
26An asynchronous processing mechanism is provided to allow messages in a queue not to be processed immediately. In addition, queues can be used to buffer messages and implement asynchronous task communication. Queues have the following features:
27
28-   Messages are queued in first-in-first-out \(FIFO\) mode and can be read and written asynchronously.
29-   Both the read queue and write queue support the timeout mechanism.
30-   Each time a message is read, the message node becomes available.
31-   The types of messages to be sent are determined by the parties involved in communication. Messages of different lengths \(not exceeding the message node size of the queue\) are allowed.
32-   A task can receive messages from and send messages to any message queue.
33-   Multiple tasks can receive messages from and send messages to the same queue.
34-   When a queue is created, the required dynamic memory space is automatically allocated in the queue API.
35
36## Working Principles<a name="section1074515132316"></a>
37
38### Queue Control Block<a name="section194431851201315"></a>
39
40```
41/**
42 * Data structure of the queue control block
43  */
44typedef struct {
45    UINT8 *queueHandle; /**< Pointer to a queue handle */
46    UINT16 queueState;  /**< Queue state */
47    UINT16 queueLen;    /**< Queue length */
48    UINT16 queueSize;   /**< Node size */
49    UINT32 queueID;     /**< queueID */
50    UINT16 queueHead;   /**< Node head */
51    UINT16 queueTail;   /**< Node tail */
52    UINT16 readWriteableCnt[OS_QUEUE_N_RW];   /**< Count of readable or writable resources, 0:readable, 1:writable */
53    LOS_DL_LIST readWriteList[OS_QUEUE_N_RW]; /**< the linked list to be read or written, 0:readlist, 1:writelist */
54    LOS_DL_LIST memList;                      /**< Pointer to the memory linked list */
55} LosQueueCB;
56```
57
58Each queue control block contains information about the queue status.
59
60-   **OS\_QUEUE\_UNUSED**: The queue is not in use.
61-   **OS\_QUEUE\_INUSED**: The queue is in use.
62
63### Working Principles<a name="section89875741418"></a>
64
65-   The queue ID is returned if a queue is created successfully.
66-   The queue control block contains  **Head**  and  **Tail**, which indicate the storage status of messages in a queue.  **Head**  indicates the start position of occupied message nodes in the queue.  **Tail**  indicates the end position of the occupied message nodes and the start position of idle message nodes. When a queue is created,  **Head**  and  **Tail**  point to the start position of the queue.
67-   When data is to be written to a queue,  **readWriteableCnt\[1\]**  is used to determine whether data can be written to the queue. If  **readWriteableCnt\[1\]**  is  **0**, the queue is full and data cannot be written to it. Data can be written to the head node or tail node of a queue. To write data to the tail node, locate the start idle message node based on  **Tail**  and write data to it. If  **Tail**  is pointing to the tail of the queue, the rewind mode is used. To write data to the head node, locate previous node based on  **Head**  and write data to it. If  **Head**  is pointing to the start position of the queue, the rewind mode is used.
68-   When a queue is to be read,  **readWriteableCnt\[0\]**  is used to determine whether the queue has messages to read. Reading an idle queue \(**readWriteableCnt\[0\]**  is** 0**\) will cause task suspension. If the queue has messages to read, the system locates the first node to which data is written based on  **Head**  and read the message from the node. If  **Head**  is pointing to the tail of the queue, the rewind mode is used.
69-   When a queue is to be deleted, the system locates the queue based on the queue ID, sets the queue status to  **OS\_QUEUE\_UNUSED**, sets the queue control block to the initial state, and releases the memory occupied by the queue.
70
71**Figure  1**  Reading and writing data in a queue<a name="fig139854471119"></a>
72![](figure/reading-and-writing-data-in-a-queue.png "reading-and-writing-data-in-a-queue")
73
74The preceding figure illustrates how to write data to the tail node only. Writing data to the head node is similar.
75
76## Development Guidelines<a name="section827981242419"></a>
77
78### Available APIs<a name="section19327151642413"></a>
79
80<a name="table10903105695114"></a>
81<table><thead align="left"><tr id="row1293645645110"><th class="cellrowborder" valign="top" width="23.56%" id="mcps1.1.4.1.1"><p id="p59361562512"><a name="p59361562512"></a><a name="p59361562512"></a>Category</p>
82</th>
83<th class="cellrowborder" valign="top" width="24.29%" id="mcps1.1.4.1.2"><p id="p1393665645118"><a name="p1393665645118"></a><a name="p1393665645118"></a>API</p>
84</th>
85<th class="cellrowborder" valign="top" width="52.15%" id="mcps1.1.4.1.3"><p id="p119363564516"><a name="p119363564516"></a><a name="p119363564516"></a>Description</p>
86</th>
87</tr>
88</thead>
89<tbody><tr id="row1693665613516"><td class="cellrowborder" rowspan="2" valign="top" width="23.56%" headers="mcps1.1.4.1.1 "><p id="p193675615514"><a name="p193675615514"></a><a name="p193675615514"></a>Creating or deleting a message queue</p>
90</td>
91<td class="cellrowborder" valign="top" width="24.29%" headers="mcps1.1.4.1.2 "><p id="p11936115612514"><a name="p11936115612514"></a><a name="p11936115612514"></a>LOS_QueueCreate</p>
92</td>
93<td class="cellrowborder" valign="top" width="52.15%" headers="mcps1.1.4.1.3 "><p id="p1593620562517"><a name="p1593620562517"></a><a name="p1593620562517"></a>Creates a message queue. The system dynamically allocates the queue space.</p>
94</td>
95</tr>
96<tr id="row79361156175113"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p893615567517"><a name="p893615567517"></a><a name="p893615567517"></a>LOS_QueueDelete</p>
97</td>
98<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p4936155695111"><a name="p4936155695111"></a><a name="p4936155695111"></a>Deletes the specified queue based on the queue ID. </p>
99</td>
100</tr>
101<tr id="row093614566519"><td class="cellrowborder" rowspan="3" valign="top" width="23.56%" headers="mcps1.1.4.1.1 "><p id="p1593685614513"><a name="p1593685614513"></a><a name="p1593685614513"></a>Reading or writing data in a queue (without the content contained in the address)</p>
102</td>
103<td class="cellrowborder" valign="top" width="24.29%" headers="mcps1.1.4.1.2 "><p id="p6936556155118"><a name="p6936556155118"></a><a name="p6936556155118"></a>LOS_QueueRead</p>
104</td>
105<td class="cellrowborder" valign="top" width="52.15%" headers="mcps1.1.4.1.3 "><p id="p11936556155118"><a name="p11936556155118"></a><a name="p11936556155118"></a>Reads data in the head node of the specified queue. The data in the queue node is an address.</p>
106</td>
107</tr>
108<tr id="row199369565518"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p393655620513"><a name="p393655620513"></a><a name="p393655620513"></a>LOS_QueueWrite</p>
109</td>
110<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p12936256175120"><a name="p12936256175120"></a><a name="p12936256175120"></a>Writes the value of the input parameter <strong id="b9518118105313"><a name="b9518118105313"></a><a name="b9518118105313"></a>bufferAddr</strong> (buffer address) to the tail node of the specified queue.</p>
111</td>
112</tr>
113<tr id="row1293615635114"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p893625665119"><a name="p893625665119"></a><a name="p893625665119"></a>LOS_QueueWriteHead</p>
114</td>
115<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p193620566515"><a name="p193620566515"></a><a name="p193620566515"></a>Writes the value of the input parameter <strong id="b16808172214534"><a name="b16808172214534"></a><a name="b16808172214534"></a>bufferAddr</strong> (buffer address) to the head node of the specified queue.</p>
116</td>
117</tr>
118<tr id="row593675635117"><td class="cellrowborder" rowspan="3" valign="top" width="23.56%" headers="mcps1.1.4.1.1 "><p id="p293675615111"><a name="p293675615111"></a><a name="p293675615111"></a>Reading or writing in a queue (with the content contained in the address)</p>
119</td>
120<td class="cellrowborder" valign="top" width="24.29%" headers="mcps1.1.4.1.2 "><p id="p14936356155113"><a name="p14936356155113"></a><a name="p14936356155113"></a>LOS_QueueReadCopy</p>
121</td>
122<td class="cellrowborder" valign="top" width="52.15%" headers="mcps1.1.4.1.3 "><p id="p11936155616510"><a name="p11936155616510"></a><a name="p11936155616510"></a>Reads data from the head node of the specified queue.</p>
123</td>
124</tr>
125<tr id="row093619569510"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p179361256175117"><a name="p179361256175117"></a><a name="p179361256175117"></a>LOS_QueueWriteCopy</p>
126</td>
127<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p6936155616515"><a name="p6936155616515"></a><a name="p6936155616515"></a>Writes the data saved in the input parameter <strong id="b14415194615537"><a name="b14415194615537"></a><a name="b14415194615537"></a>bufferAddr</strong> to the tail node of the specified queue.</p>
128</td>
129</tr>
130<tr id="row16936856185111"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p49361156195113"><a name="p49361156195113"></a><a name="p49361156195113"></a>LOS_QueueWriteHeadCopy</p>
131</td>
132<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p1193625675116"><a name="p1193625675116"></a><a name="p1193625675116"></a>Writes the data saved in the input parameter <strong id="b1030118493534"><a name="b1030118493534"></a><a name="b1030118493534"></a>bufferAddr</strong> to the head node of the specified queue.</p>
133</td>
134</tr>
135<tr id="row1936756155114"><td class="cellrowborder" valign="top" width="23.56%" headers="mcps1.1.4.1.1 "><p id="p149371956105114"><a name="p149371956105114"></a><a name="p149371956105114"></a>Obtaining queue information</p>
136</td>
137<td class="cellrowborder" valign="top" width="24.29%" headers="mcps1.1.4.1.2 "><p id="p7937145613516"><a name="p7937145613516"></a><a name="p7937145613516"></a>LOS_QueueInfoGet</p>
138</td>
139<td class="cellrowborder" valign="top" width="52.15%" headers="mcps1.1.4.1.3 "><p id="p19371356175110"><a name="p19371356175110"></a><a name="p19371356175110"></a>Obtains information about the specified queue, including the queue ID, queue length, message node size, head node, tail node, number of readable nodes, number of writable nodes, tasks waiting for read operations, and tasks waiting for write operations.</p>
140</td>
141</tr>
142</tbody>
143</table>
144
145### How to Develop<a name="section1390154210243"></a>
146
1471.  Call  **LOS\_QueueCreate**  to create a queue. The queue ID is returned when the queue is created.
1482.  Call  **LOS\_QueueWrite**  or  **LOS\_QueueWriteCopy**  to write messages to the queue.
1493.  Call  **LOS\_QueueRead**  or  **LOS\_QueueReadCopy**  to read messages from the queue.
1504.  Call  **LOS\_QueueInfoGet**  to obtain queue information.
1515.  Call  **LOS\_QueueDelete**  to delete a queue.
152
153>![](../public_sys-resources/icon-note.gif) **NOTE:**
154>-   The maximum number of queues supported by the system is the total number of queue resources of the system, not the number of queue resources available to users. For example, if the system software timer occupies one more queue resource, the number of queue resources available to users decreases by one.
155>-   The input parameters queue name and flags passed when a queue is created are reserved for future use.
156>-   The input parameter  **timeOut**  in the queue interface function is relative time.
157>-   **LOS\_QueueReadCopy**,  **LOS\_QueueWriteCopy**, and  **LOS\_QueueWriteHeadCopy**  are a group of APIs that must be used together.  **LOS\_QueueRead**,  **LOS\_QueueWrite**, and  **LOS\_QueueWriteHead**  are a group of APIs that must be used together.
158>-   As  **LOS\_QueueWrite**,  **LOS\_QueueWriteHead**, and  **LOS\_QueueRead**  are used to manage data addresses, you must ensure that the memory directed by the pointer obtained by calling  **LOS\_QueueRead**  is not modified or released abnormally when the queue is being read. Otherwise, unpredictable results may occur.
159>-   **LOS\_QueueWrite**,  **LOS\_QueueWriteHead**, and  **LOS\_QueueRead**  are called to manage data addresses, which means that the actual data read or written is pointer data. Therefore, before using these APIs, ensure that the message node size is the pointer length during queue creation, to avoid waste and read failures.
160
161## Development Example<a name="section27132341285"></a>
162
163### Example Description<a name="section197311443141017"></a>
164
165Create a queue and two tasks. Enable task 1 to call the queue write API to send messages, and enable task 2 to receive messages by calling the queue read API.
166
1671.  Create task 1 and task 2 by calling  **LOS\_TaskCreate**.
1682.  Create a message queue by calling  **LOS\_QueueCreate**.
1693.  Enable messages to be sent in task 1 by calling  **SendEntry**.
1704.  Enable messages to be received in task 2 by calling  **RecvEntry**.
1715.  Call  **LOS\_QueueDelete**  to delete a queue.
172
173### Sample Code<a name="section972214490107"></a>
174
175The sample code is as follows:
176
177```
178#include "los_task.h"
179#include "los_queue.h"
180static UINT32 g_queue;
181#define BUFFER_LEN 50
182
183VOID SendEntry(VOID)
184{
185    UINT32 ret = 0;
186    CHAR abuf[] = "test message";
187    UINT32 len = sizeof(abuf);
188
189    ret = LOS_QueueWriteCopy(g_queue, abuf, len, 0);
190    if(ret != LOS_OK) {
191        printf("send message failure, error: %x\n", ret);
192    }
193}
194
195VOID RecvEntry(VOID)
196{
197    UINT32 ret = 0;
198    CHAR readBuf[BUFFER_LEN] = {0};
199    UINT32 readLen = BUFFER_LEN;
200
201   // Sleep for 1s.
202    usleep(1000000);
203    ret = LOS_QueueReadCopy(g_queue, readBuf, &readLen, 0);
204    if(ret != LOS_OK) {
205        printf("recv message failure, error: %x\n", ret);
206    }
207
208    printf("recv message: %s\n", readBuf);
209
210    ret = LOS_QueueDelete(g_queue);
211    if(ret != LOS_OK) {
212        printf("delete the queue failure, error: %x\n", ret);
213    }
214
215    printf("delete the queue success!\n");
216}
217
218UINT32 ExampleQueue(VOID)
219{
220    printf("start queue example\n");
221    UINT32 ret = 0;
222    UINT32 task1, task2;
223    TSK_INIT_PARAM_S initParam = {0};
224
225    initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)SendEntry;
226    initParam.usTaskPrio = 9;
227    initParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
228    initParam.pcName = "SendQueue";
229
230    LOS_TaskLock();
231    ret = LOS_TaskCreate(&task1, &initParam);
232    if(ret != LOS_OK) {
233        printf("create task1 failed, error: %x\n", ret);
234        return ret;
235    }
236
237    initParam.pcName = "RecvQueue";
238    initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)RecvEntry;
239    ret = LOS_TaskCreate(&task2, &initParam);
240    if(ret != LOS_OK) {
241        printf("create task2 failed, error: %x\n", ret);
242        return ret;
243    }
244
245    ret = LOS_QueueCreate("queue", 5, &g_queue, 0, 50);
246    if(ret != LOS_OK) {
247        printf("create queue failure, error: %x\n", ret);
248    }
249
250    printf("create the queue success!\n");
251    LOS_TaskUnlock();
252    return ret;
253}
254```
255
256### Verification<a name="section19287165416106"></a>
257
258The development is successful if the return result is as follows:
259
260```
261start test example
262create the queue success!
263recv message: test message
264delete the queue success!
265```
266
267