1e41f4b71Sopenharmony_ci# Queue 2e41f4b71Sopenharmony_ci 3e41f4b71Sopenharmony_ci 4e41f4b71Sopenharmony_ci## Basic Concepts 5e41f4b71Sopenharmony_ci 6e41f4b71Sopenharmony_ciA 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. 7e41f4b71Sopenharmony_ci 8e41f4b71Sopenharmony_ciTasks 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. 9e41f4b71Sopenharmony_ci 10e41f4b71Sopenharmony_ciYou 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. 11e41f4b71Sopenharmony_ci 12e41f4b71Sopenharmony_ciAn 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: 13e41f4b71Sopenharmony_ci 14e41f4b71Sopenharmony_ci- Messages are queued in first-in-first-out (FIFO) mode and can be read and written asynchronously. 15e41f4b71Sopenharmony_ci 16e41f4b71Sopenharmony_ci- Both the read queue and write queue support the timeout mechanism. 17e41f4b71Sopenharmony_ci 18e41f4b71Sopenharmony_ci- Each time a message is read, the message node becomes available. 19e41f4b71Sopenharmony_ci 20e41f4b71Sopenharmony_ci- 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. 21e41f4b71Sopenharmony_ci 22e41f4b71Sopenharmony_ci- A task can receive messages from and send messages to any message queue. 23e41f4b71Sopenharmony_ci 24e41f4b71Sopenharmony_ci- Multiple tasks can receive messages from and send messages to the same queue. 25e41f4b71Sopenharmony_ci 26e41f4b71Sopenharmony_ci- When a queue is created, the required dynamic memory space is automatically allocated in the queue API. 27e41f4b71Sopenharmony_ci 28e41f4b71Sopenharmony_ci 29e41f4b71Sopenharmony_ci## Working Principles 30e41f4b71Sopenharmony_ci 31e41f4b71Sopenharmony_ci 32e41f4b71Sopenharmony_ci### Queue Control Block 33e41f4b71Sopenharmony_ci 34e41f4b71Sopenharmony_ci 35e41f4b71Sopenharmony_ci``` 36e41f4b71Sopenharmony_ci/** 37e41f4b71Sopenharmony_ci * Data structure of the queue control block 38e41f4b71Sopenharmony_ci */ 39e41f4b71Sopenharmony_citypedef struct { 40e41f4b71Sopenharmony_ci UINT8 *queueHandle; /**< Pointer to a queue handle */ 41e41f4b71Sopenharmony_ci UINT16 queueState; /**< Queue state */ 42e41f4b71Sopenharmony_ci UINT16 queueLen; /**< Queue length */ 43e41f4b71Sopenharmony_ci UINT16 queueSize; /**< Node size */ 44e41f4b71Sopenharmony_ci UINT32 queueID; /**< queueID */ 45e41f4b71Sopenharmony_ci UINT16 queueHead; /**< Node head */ 46e41f4b71Sopenharmony_ci UINT16 queueTail; /**< Node tail */ 47e41f4b71Sopenharmony_ci UINT16 readWriteableCnt[OS_QUEUE_N_RW]; /**< Count of readable or writable resources, 0:readable, 1:writable */ 48e41f4b71Sopenharmony_ci LOS_DL_LIST readWriteList[OS_QUEUE_N_RW]; /**< the linked list to be read or written, 0:readlist, 1:writelist */ 49e41f4b71Sopenharmony_ci LOS_DL_LIST memList; /**< Pointer to the memory linked list */ 50e41f4b71Sopenharmony_ci} LosQueueCB; 51e41f4b71Sopenharmony_ci``` 52e41f4b71Sopenharmony_ci 53e41f4b71Sopenharmony_ciEach queue control block contains information about the queue status. 54e41f4b71Sopenharmony_ci 55e41f4b71Sopenharmony_ci- **OS_QUEUE_UNUSED**: The queue is not in use. 56e41f4b71Sopenharmony_ci 57e41f4b71Sopenharmony_ci- **OS_QUEUE_INUSED**: The queue is in use. 58e41f4b71Sopenharmony_ci 59e41f4b71Sopenharmony_ci 60e41f4b71Sopenharmony_ci### Working Principles 61e41f4b71Sopenharmony_ci 62e41f4b71Sopenharmony_ci- The queue ID is returned when a queue is created successfully. 63e41f4b71Sopenharmony_ci 64e41f4b71Sopenharmony_ci- 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. 65e41f4b71Sopenharmony_ci 66e41f4b71Sopenharmony_ci- 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. 67e41f4b71Sopenharmony_ci 68e41f4b71Sopenharmony_ci- 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. 69e41f4b71Sopenharmony_ci 70e41f4b71Sopenharmony_ci- 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. 71e41f4b71Sopenharmony_ci 72e41f4b71Sopenharmony_ci **Figure 1** Reading and writing data in a queue 73e41f4b71Sopenharmony_ci 74e41f4b71Sopenharmony_ci  75e41f4b71Sopenharmony_ci 76e41f4b71Sopenharmony_ciThe preceding figure illustrates how to write data to the tail node only. Writing data to the head node is similar. 77e41f4b71Sopenharmony_ci 78e41f4b71Sopenharmony_ci 79e41f4b71Sopenharmony_ci## Development Guidelines 80e41f4b71Sopenharmony_ci 81e41f4b71Sopenharmony_ci 82e41f4b71Sopenharmony_ci### Available APIs 83e41f4b71Sopenharmony_ci 84e41f4b71Sopenharmony_ci| Category| API Description | 85e41f4b71Sopenharmony_ci| -------- | -------- | 86e41f4b71Sopenharmony_ci| Creating or deleting a message queue| - **LOS_QueueCreate**: creates a message queue. The system dynamically allocates the queue space.<br>- **LOS_QueueDelete**: deletes a queue.| 87e41f4b71Sopenharmony_ci| Reading or writing data (address without the content) in a queue| - **LOS_QueueRead**: reads data in the head node of the specified queue. The data in the queue node is an address.<br>- **LOS_QueueWrite**: writes the value of **bufferAddr** (buffer address) to the tail node of a queue.<br>- **LOS_QueueWrite**: writes the value of **bufferAddr** (buffer address) to the head node of a queue.| 88e41f4b71Sopenharmony_ci| Reading or writing data (data and address) in a queue| - **LOS_QueueReadCopy**: reads data from the head node of a queue.<br>- **LOS_QueueWriteCopy**: writes the data saved in **bufferAddr** to the tail node of a queue.<br>- **LOS_QueueWriteHeadCopy**: writes the data saved in **bufferAddr** to the head node of a queue.| 89e41f4b71Sopenharmony_ci| Obtaining queue information| **LOS_QueueInfoGet**: obtains queue information, including the queue ID, queue length, message node size, head node, tail node, number of readable/writable nodes, and tasks waiting for read/write operations.| 90e41f4b71Sopenharmony_ci 91e41f4b71Sopenharmony_ci 92e41f4b71Sopenharmony_ci### How to Develop 93e41f4b71Sopenharmony_ci 94e41f4b71Sopenharmony_ci1. Call **LOS_QueueCreate** to create a queue. The queue ID is returned when the queue is created. 95e41f4b71Sopenharmony_ci 96e41f4b71Sopenharmony_ci2. Call **LOS_QueueWrite** or **LOS_QueueWriteCopy** to write data to the queue. 97e41f4b71Sopenharmony_ci 98e41f4b71Sopenharmony_ci3. Call **LOS_QueueRead** or **LOS_QueueReadCopy** to read data from the queue. 99e41f4b71Sopenharmony_ci 100e41f4b71Sopenharmony_ci4. Call **LOS_QueueInfoGet** to obtain queue information. 101e41f4b71Sopenharmony_ci 102e41f4b71Sopenharmony_ci5. Call **LOS_QueueDelete** to delete a queue. 103e41f4b71Sopenharmony_ci 104e41f4b71Sopenharmony_ci> **NOTE**<br> 105e41f4b71Sopenharmony_ci> - 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. 106e41f4b71Sopenharmony_ci> 107e41f4b71Sopenharmony_ci> - The queue name and flags passed in when a queue is created are reserved for future use. 108e41f4b71Sopenharmony_ci> 109e41f4b71Sopenharmony_ci> - The parameter **timeOut** in the queue function is relative time. 110e41f4b71Sopenharmony_ci> 111e41f4b71Sopenharmony_ci> - **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. 112e41f4b71Sopenharmony_ci> 113e41f4b71Sopenharmony_ci> - 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. 114e41f4b71Sopenharmony_ci> 115e41f4b71Sopenharmony_ci> - If the length of the data to read in **LOS_QueueRead** or **LOS_QueueReadCopy** is less than the actual message length, the message will be truncated. 116e41f4b71Sopenharmony_ci> 117e41f4b71Sopenharmony_ci> - **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. 118e41f4b71Sopenharmony_ci 119e41f4b71Sopenharmony_ci 120e41f4b71Sopenharmony_ci## Development Example 121e41f4b71Sopenharmony_ci 122e41f4b71Sopenharmony_ci 123e41f4b71Sopenharmony_ci### Example Description 124e41f4b71Sopenharmony_ci 125e41f4b71Sopenharmony_ciCreate a queue and two tasks. Enable task 1 to write data to the queue, and task 2 to read data from the queue. 126e41f4b71Sopenharmony_ci 127e41f4b71Sopenharmony_ci1. Call **LOS_TaskCreate** to create task 1 and task 2. 128e41f4b71Sopenharmony_ci 129e41f4b71Sopenharmony_ci2. Call **LOS_QueueCreate** to create a message queue. 130e41f4b71Sopenharmony_ci 131e41f4b71Sopenharmony_ci3. Task 1 sends a message in **SendEntry**. 132e41f4b71Sopenharmony_ci 133e41f4b71Sopenharmony_ci4. Task 2 receives message in **RecvEntry**. 134e41f4b71Sopenharmony_ci 135e41f4b71Sopenharmony_ci5. Call **LOS_QueueDelete** to delete the queue. 136e41f4b71Sopenharmony_ci 137e41f4b71Sopenharmony_ci 138e41f4b71Sopenharmony_ci### Sample Code 139e41f4b71Sopenharmony_ci 140e41f4b71Sopenharmony_ciThe sample code can be compiled and verified in **./kernel/liteos_a/testsuites/kernel/src/osTest.c**. The **ExampleQueue** function is called in **TestTaskEntry**. 141e41f4b71Sopenharmony_ci 142e41f4b71Sopenharmony_ciTo avoid excessive printing, call **LOS_Msleep(5000)** to cause a short delay before calling **ExampleQueue**. 143e41f4b71Sopenharmony_ci 144e41f4b71Sopenharmony_ciThe sample code is as follows: 145e41f4b71Sopenharmony_ci 146e41f4b71Sopenharmony_ci``` 147e41f4b71Sopenharmony_ci#include "los_task.h" 148e41f4b71Sopenharmony_ci#include "los_queue.h" 149e41f4b71Sopenharmony_cistatic UINT32 g_queue; 150e41f4b71Sopenharmony_ci#define BUFFER_LEN 50 151e41f4b71Sopenharmony_ci 152e41f4b71Sopenharmony_ciVOID SendEntry(VOID) 153e41f4b71Sopenharmony_ci{ 154e41f4b71Sopenharmony_ci UINT32 ret = 0; 155e41f4b71Sopenharmony_ci CHAR abuf[] = "test message"; 156e41f4b71Sopenharmony_ci UINT32 len = sizeof(abuf); 157e41f4b71Sopenharmony_ci 158e41f4b71Sopenharmony_ci ret = LOS_QueueWriteCopy(g_queue, abuf, len, 0); 159e41f4b71Sopenharmony_ci if(ret != LOS_OK) { 160e41f4b71Sopenharmony_ci dprintf("send message failure, error: %x\n", ret); 161e41f4b71Sopenharmony_ci } 162e41f4b71Sopenharmony_ci} 163e41f4b71Sopenharmony_ci 164e41f4b71Sopenharmony_ciVOID RecvEntry(VOID) 165e41f4b71Sopenharmony_ci{ 166e41f4b71Sopenharmony_ci UINT32 ret = 0; 167e41f4b71Sopenharmony_ci CHAR readBuf[BUFFER_LEN] = {0}; 168e41f4b71Sopenharmony_ci UINT32 readLen = BUFFER_LEN; 169e41f4b71Sopenharmony_ci 170e41f4b71Sopenharmony_ci LOS_Msleep(1000); 171e41f4b71Sopenharmony_ci ret = LOS_QueueReadCopy(g_queue, readBuf, &readLen, 0); 172e41f4b71Sopenharmony_ci if(ret != LOS_OK) { 173e41f4b71Sopenharmony_ci dprintf("recv message failure, error: %x\n", ret); 174e41f4b71Sopenharmony_ci } 175e41f4b71Sopenharmony_ci 176e41f4b71Sopenharmony_ci dprintf("recv message: %s\n", readBuf); 177e41f4b71Sopenharmony_ci 178e41f4b71Sopenharmony_ci ret = LOS_QueueDelete(g_queue); 179e41f4b71Sopenharmony_ci if(ret != LOS_OK) { 180e41f4b71Sopenharmony_ci dprintf("delete the queue failure, error: %x\n", ret); 181e41f4b71Sopenharmony_ci } 182e41f4b71Sopenharmony_ci 183e41f4b71Sopenharmony_ci dprintf("delete the queue success!\n"); 184e41f4b71Sopenharmony_ci} 185e41f4b71Sopenharmony_ci 186e41f4b71Sopenharmony_ciUINT32 ExampleQueue(VOID) 187e41f4b71Sopenharmony_ci{ 188e41f4b71Sopenharmony_ci dprintf("start queue example\n"); 189e41f4b71Sopenharmony_ci UINT32 ret = 0; 190e41f4b71Sopenharmony_ci UINT32 task1, task2; 191e41f4b71Sopenharmony_ci TSK_INIT_PARAM_S initParam = {0}; 192e41f4b71Sopenharmony_ci 193e41f4b71Sopenharmony_ci ret = LOS_QueueCreate("queue", 5, &g_queue, 0, 50); 194e41f4b71Sopenharmony_ci if(ret != LOS_OK) { 195e41f4b71Sopenharmony_ci dprintf("create queue failure, error: %x\n", ret); 196e41f4b71Sopenharmony_ci } 197e41f4b71Sopenharmony_ci 198e41f4b71Sopenharmony_ci dprintf("create the queue success!\n"); 199e41f4b71Sopenharmony_ci 200e41f4b71Sopenharmony_ci initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)SendEntry; 201e41f4b71Sopenharmony_ci initParam.usTaskPrio = 9; 202e41f4b71Sopenharmony_ci initParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE; 203e41f4b71Sopenharmony_ci initParam.pcName = "SendQueue"; 204e41f4b71Sopenharmony_ci 205e41f4b71Sopenharmony_ci LOS_TaskLock(); 206e41f4b71Sopenharmony_ci ret = LOS_TaskCreate(&task1, &initParam); 207e41f4b71Sopenharmony_ci if(ret != LOS_OK) { 208e41f4b71Sopenharmony_ci dprintf("create task1 failed, error: %x\n", ret); 209e41f4b71Sopenharmony_ci LOS_QueueDelete(g_queue); 210e41f4b71Sopenharmony_ci return ret; 211e41f4b71Sopenharmony_ci } 212e41f4b71Sopenharmony_ci 213e41f4b71Sopenharmony_ci initParam.pcName = "RecvQueue"; 214e41f4b71Sopenharmony_ci initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)RecvEntry; 215e41f4b71Sopenharmony_ci ret = LOS_TaskCreate(&task2, &initParam); 216e41f4b71Sopenharmony_ci if(ret != LOS_OK) { 217e41f4b71Sopenharmony_ci dprintf("create task2 failed, error: %x\n", ret); 218e41f4b71Sopenharmony_ci LOS_QueueDelete(g_queue); 219e41f4b71Sopenharmony_ci return ret; 220e41f4b71Sopenharmony_ci } 221e41f4b71Sopenharmony_ci 222e41f4b71Sopenharmony_ci LOS_TaskUnlock(); 223e41f4b71Sopenharmony_ci LOS_Msleep(5000); 224e41f4b71Sopenharmony_ci return ret; 225e41f4b71Sopenharmony_ci} 226e41f4b71Sopenharmony_ci``` 227e41f4b71Sopenharmony_ci 228e41f4b71Sopenharmony_ci 229e41f4b71Sopenharmony_ci### Verification 230e41f4b71Sopenharmony_ci 231e41f4b71Sopenharmony_ciThe development is successful if the return result is as follows: 232e41f4b71Sopenharmony_ci 233e41f4b71Sopenharmony_ci 234e41f4b71Sopenharmony_ci``` 235e41f4b71Sopenharmony_cistart queue example 236e41f4b71Sopenharmony_cicreate the queue success! 237e41f4b71Sopenharmony_cirecv message: test message 238e41f4b71Sopenharmony_cidelete the queue success! 239e41f4b71Sopenharmony_ci``` 240