• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Development Guidelines<a name="EN-US_TOPIC_0000001078588414"></a>
2
3-   [Available APIs](#section158501652121514)
4-   [How to Develop](#section783435801510)
5-   [Development Example](#section1426719434114)
6    -   [Example Description](#section896412438910)
7    -   [Sample Code](#section149077554912)
8    -   [Verification](#section2059413981311)
9
10
11## Available APIs<a name="section158501652121514"></a>
12
13**Table  1**  APIs of the mutex module
14
15<a name="table37108292611"></a>
16<table><thead align="left"><tr id="row8711112919610"><th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.1"><p id="p3711102912617"><a name="p3711102912617"></a><a name="p3711102912617"></a>Category</p>
17</th>
18<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.2"><p id="p1671110293610"><a name="p1671110293610"></a><a name="p1671110293610"></a>API</p>
19</th>
20<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.3"><p id="p87114292617"><a name="p87114292617"></a><a name="p87114292617"></a>Description</p>
21</th>
22</tr>
23</thead>
24<tbody><tr id="row37115291166"><td class="cellrowborder" rowspan="2" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p1795312108911"><a name="p1795312108911"></a><a name="p1795312108911"></a>Creating or deleting a mutex</p>
25</td>
26<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p1671120293611"><a name="p1671120293611"></a><a name="p1671120293611"></a>LOS_MuxCreate</p>
27</td>
28<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p171112291967"><a name="p171112291967"></a><a name="p171112291967"></a>Creates a mutex.</p>
29</td>
30</tr>
31<tr id="row17711329268"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p071114291864"><a name="p071114291864"></a><a name="p071114291864"></a>LOS_MuxDelete</p>
32</td>
33<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p137111129965"><a name="p137111129965"></a><a name="p137111129965"></a>Deletes the specified mutex.</p>
34</td>
35</tr>
36<tr id="row5711192912616"><td class="cellrowborder" rowspan="2" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p86087143910"><a name="p86087143910"></a><a name="p86087143910"></a>Requesting or releasing a mutex</p>
37</td>
38<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p1171112295614"><a name="p1171112295614"></a><a name="p1171112295614"></a>LOS_MuxPend</p>
39</td>
40<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p1271110291969"><a name="p1271110291969"></a><a name="p1271110291969"></a>Requests the specified mutex.</p>
41</td>
42</tr>
43<tr id="row1571162918615"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p57111229967"><a name="p57111229967"></a><a name="p57111229967"></a>LOS_MuxPost</p>
44</td>
45<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p107118291660"><a name="p107118291660"></a><a name="p107118291660"></a>Releases the specified mutex.</p>
46</td>
47</tr>
48</tbody>
49</table>
50
51## How to Develop<a name="section783435801510"></a>
52
53The typical mutex development process is as follows:
54
551.  Call  **LOS\_MuxCreate**  to create a mutex.
562.  Call  **LOS\_MuxPend**  to request a mutex.
57
58    The following modes are available:
59
60    -   Non-block mode: A task acquires the mutex if the requested mutex is not held by any task or the task holding the mutex is the same as the task requesting the mutex.
61    -   Permanent block mode: A task acquires the mutex if the requested mutex is not occupied. If the mutex is occupied, the task will be blocked and the task with the highest priority in the ready queue will be executed. The blocked task can be unlocked and executed only when the mutex is released.
62    -   Scheduled block mode: A task acquires the mutex if the requested mutex is not occupied. If the mutex is occupied, the task will be blocked and the task with the highest priority in the ready queue will be executed. The blocked task can be executed only when the mutex is released within the specified timeout period or when the specified timeout period expires.
63
643.  Call  **LOS\_MuxPost**  to release a mutex.
65    -   If tasks are blocked by the specified mutex, the task with a higher priority will be unblocked when the mutex is released. The unblocked task changes to the Ready state and is scheduled.
66    -   If no task is blocked by the specified mutex, the mutex is released successfully.
67
684.  Call  **LOS\_MuxDelete**  to delete a mutex.
69
70>![](../public_sys-resources/icon-note.gif) **NOTE:**
71>-   Two tasks cannot lock the same mutex. If a task attempts to lock a mutex held by another task, the task will be blocked until the mutex is unclocked.
72>-   Mutexes cannot be used in the interrupt service program.
73>-   When using the LiteOS-M kernel, OpenHarmony must ensure real-time task scheduling and avoid long-time task blocking. Therefore, a mutex must be released as soon as possible after use.
74>-   When a mutex is held by a task, the task priority cannot be changed by using APIs such as  **LOS\_TaskPriSet**.
75
76## Development Example<a name="section1426719434114"></a>
77
78### Example Description<a name="section896412438910"></a>
79
80This example implements the following:
81
821.  Create the  **Example\_TaskEntry**  task. In this task, create a mutex, lock task scheduling, create two tasks  **Example\_MutexTask1**  \(with a lower priority\) and  **Example\_MutexTask2**  \(with a higher priority\), and unlock task scheduling.
832.  When being scheduled,  **Example\_MutexTask2**  requests a mutex in permanent block mode. After acquiring the mutex,  **Example\_MutexTask2**  enters the sleep mode for 100 ticks.  **Example\_MutexTask2**  is suspended, and  **Example\_MutexTask1**  is woken up.
843.  **Example\_MutexTask1**  requests a mutex in scheduled block mode, and waits for 10 ticks. Because the mutex is still held by  **Example\_MutexTask2**,  **Example\_MutexTask1**  is suspended. After 10 ticks,  **Example\_MutexTask1**  is woken up and attempts to request a mutex in permanent block mode.  **Example\_MutexTask1**  is suspended because the mutex is still held by  **Example\_MutexTask2**.
854.  After 100 ticks,  **Example\_MutexTask2**  is woken up and releases the mutex, and then  **Example\_MutexTask1**  is woken up.  **Example\_MutexTask1**  acquires the mutex and then releases the mutex. At last, the mutex is deleted.
86
87### Sample Code<a name="section149077554912"></a>
88
89The sample code is as follows:
90
91```
92#include <string.h>
93#include "los_mux.h"
94
95/* Mutex handler ID*/
96UINT32 g_testMux;
97/* Task ID*/
98UINT32 g_testTaskId01;
99UINT32 g_testTaskId02;
100
101VOID Example_MutexTask1(VOID)
102{
103    UINT32 ret;
104
105    printf("task1 try to get  mutex, wait 10 ticks.\n");
106    /* Request a mutex.*/
107    ret = LOS_MuxPend(g_testMux, 10);
108
109    if (ret == LOS_OK) {
110        printf("task1 get mutex g_testMux.\n");
111         /*Release the mutex.*/
112        LOS_MuxPost(g_testMux);
113        return;
114    }
115    if (ret == LOS_ERRNO_MUX_TIMEOUT ) {
116            printf("task1 timeout and try to get mutex, wait forever.\n");
117            /* Request a mutex.*/
118            ret = LOS_MuxPend(g_testMux, LOS_WAIT_FOREVER);
119            if (ret == LOS_OK) {
120                printf("task1 wait forever, get mutex g_testMux.\n");
121                /*Release the mutex.*/
122                LOS_MuxPost(g_testMux);
123                /* Delete the mutex. */
124                LOS_MuxDelete(g_testMux);
125                printf("task1 post and delete mutex g_testMux.\n");
126                return;
127            }
128    }
129    return;
130}
131
132VOID Example_MutexTask2(VOID)
133{
134    printf("task2 try to get  mutex, wait forever.\n");
135    /* Request a mutex.*/
136    (VOID)LOS_MuxPend(g_testMux, LOS_WAIT_FOREVER);
137
138    printf("task2 get mutex g_testMux and suspend 100 ticks.\n");
139
140     /* Enable the task to enter sleep mode for 100 ticks.*/
141    LOS_TaskDelay(100);
142
143    printf("task2 resumed and post the g_testMux\n");
144    /* Release the mutex.*/
145    LOS_MuxPost(g_testMux);
146    return;
147}
148
149UINT32 Example_TaskEntry(VOID)
150{
151    UINT32 ret;
152    TSK_INIT_PARAM_S task1;
153    TSK_INIT_PARAM_S task2;
154
155    /* Create a mutex.*/
156    LOS_MuxCreate(&g_testMux);
157
158    /* Lock task scheduling.*/
159    LOS_TaskLock();
160
161    /* Create task 1.*/
162    memset(&task1, 0, sizeof(TSK_INIT_PARAM_S));
163    task1.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_MutexTask1;
164    task1.pcName       = "MutexTsk1";
165    task1.uwStackSize  = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
166    task1.usTaskPrio   = 5;
167    ret = LOS_TaskCreate(&g_testTaskId01, &task1);
168    if (ret != LOS_OK) {
169        printf("task1 create failed.\n");
170        return LOS_NOK;
171    }
172
173    /* Create task 2.*/
174    memset(&task2, 0, sizeof(TSK_INIT_PARAM_S));
175    task2.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_MutexTask2;
176    task2.pcName       = "MutexTsk2";
177    task2.uwStackSize  = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
178    task2.usTaskPrio   = 4;
179    ret = LOS_TaskCreate(&g_testTaskId02, &task2);
180    if (ret != LOS_OK) {
181        printf("task2 create failed.\n");
182        return LOS_NOK;
183    }
184
185    /* Unlock task scheduling.*/
186    LOS_TaskUnlock();
187
188    return LOS_OK;
189}
190```
191
192### Verification<a name="section2059413981311"></a>
193
194The development is successful if the return result is as follows:
195
196```
197task2 try to get  mutex, wait forever.
198task2 get mutex g_testMux and suspend 100 ticks.
199task1 try to get  mutex, wait 10 ticks.
200task1 timeout and try to get mutex, wait forever.
201task2 resumed and post the g_testMux
202task1 wait forever, get mutex g_testMux.
203task1 post and delete mutex g_testMux.
204```
205
206