• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# 开发指导<a name="ZH-CN_TOPIC_0000001123948079"></a>
2
3-   [接口说明](#section158501652121514)
4-   [开发流程](#section783435801510)
5-   [编程实例](#section460018317164)
6    -   [结果验证](#section189023104457)
7
8
9任务创建后,内核可以执行锁任务调度,解锁任务调度,挂起,恢复,延时等操作,同时也可以设置任务优先级,获取任务优先级。
10
11## 接口说明<a name="section158501652121514"></a>
12
13OpenHarmony LiteOS-M内核的任务管理模块提供下面几种功能,接口详细信息可以查看API参考。
14
15**表 1**  任务管理模块接口
16
17<a name="table1415203765610"></a>
18<table><thead align="left"><tr id="row134151837125611"><th class="cellrowborder" valign="top" width="12.85128512851285%" id="mcps1.2.4.1.1"><p id="p16415637105612"><a name="p16415637105612"></a><a name="p16415637105612"></a>功能分类</p>
19</th>
20<th class="cellrowborder" valign="top" width="29.8029802980298%" id="mcps1.2.4.1.2"><p id="p11415163718562"><a name="p11415163718562"></a><a name="p11415163718562"></a>接口名</p>
21</th>
22<th class="cellrowborder" valign="top" width="57.34573457345735%" id="mcps1.2.4.1.3"><p id="p1641533755612"><a name="p1641533755612"></a><a name="p1641533755612"></a>描述</p>
23</th>
24</tr>
25</thead>
26<tbody><tr id="row0415737175610"><td class="cellrowborder" rowspan="3" valign="top" width="12.85128512851285%" headers="mcps1.2.4.1.1 "><p id="p88211552111218"><a name="p88211552111218"></a><a name="p88211552111218"></a>创建和删除任务</p>
27</td>
28<td class="cellrowborder" valign="top" width="29.8029802980298%" headers="mcps1.2.4.1.2 "><p id="p6347518151610"><a name="p6347518151610"></a><a name="p6347518151610"></a>LOS_TaskCreateOnly</p>
29</td>
30<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p5347161814167"><a name="p5347161814167"></a><a name="p5347161814167"></a>创建任务,并使该任务进入suspend状态,不对该任务进行调度。如果需要调度,可以调用LOS_TaskResume使该任务进入ready状态。</p>
31</td>
32</tr>
33<tr id="row1841519376561"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p4166128181614"><a name="p4166128181614"></a><a name="p4166128181614"></a>LOS_TaskCreate</p>
34</td>
35<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1516617282165"><a name="p1516617282165"></a><a name="p1516617282165"></a>创建任务,并使该任务进入ready状态,如果就绪队列中没有更高优先级的任务,则运行该任务。</p>
36</td>
37</tr>
38<tr id="row1187514443616"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p9364362169"><a name="p9364362169"></a><a name="p9364362169"></a>LOS_TaskDelete</p>
39</td>
40<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p106058831812"><a name="p106058831812"></a><a name="p106058831812"></a>删除指定的任务。</p>
41</td>
42</tr>
43<tr id="row1141513373562"><td class="cellrowborder" rowspan="5" valign="top" width="12.85128512851285%" headers="mcps1.2.4.1.1 "><p id="p9438545181812"><a name="p9438545181812"></a><a name="p9438545181812"></a>控制任务状态</p>
44</td>
45<td class="cellrowborder" valign="top" width="29.8029802980298%" headers="mcps1.2.4.1.2 "><p id="p2871432206"><a name="p2871432206"></a><a name="p2871432206"></a>LOS_TaskResume</p>
46</td>
47<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p2871632201"><a name="p2871632201"></a><a name="p2871632201"></a>恢复挂起的任务,使该任务进入ready状态。</p>
48</td>
49</tr>
50<tr id="row1541513745611"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p99679299202"><a name="p99679299202"></a><a name="p99679299202"></a>LOS_TaskSuspend</p>
51</td>
52<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p596712910200"><a name="p596712910200"></a><a name="p596712910200"></a>挂起指定的任务,然后切换任务</p>
53</td>
54</tr>
55<tr id="row14167379561"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1596722915207"><a name="p1596722915207"></a><a name="p1596722915207"></a>LOS_TaskDelay</p>
56</td>
57<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1496792972019"><a name="p1496792972019"></a><a name="p1496792972019"></a>任务延时等待,释放CPU,等待时间到期后该任务会重新进入ready状态。传入参数为Tick数目。</p>
58</td>
59</tr>
60<tr id="row1018605142017"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p19186185119201"><a name="p19186185119201"></a><a name="p19186185119201"></a>LOS_Msleep</p>
61</td>
62<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p418612515207"><a name="p418612515207"></a><a name="p418612515207"></a>传入参数为毫秒数,转换为Tick数目,调用LOS_TaskDelay。</p>
63</td>
64</tr>
65<tr id="row2832910132011"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1896722932020"><a name="p1896722932020"></a><a name="p1896722932020"></a>LOS_TaskYield</p>
66</td>
67<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p796702962016"><a name="p796702962016"></a><a name="p796702962016"></a>当前任务时间片设置为0,释放CPU,触发调度运行就绪任务队列中优先级最高的任务。</p>
68</td>
69</tr>
70<tr id="row57041546104720"><td class="cellrowborder" rowspan="3" valign="top" width="12.85128512851285%" headers="mcps1.2.4.1.1 "><p id="p11344426483"><a name="p11344426483"></a><a name="p11344426483"></a>控制任务调度</p>
71</td>
72<td class="cellrowborder" valign="top" width="29.8029802980298%" headers="mcps1.2.4.1.2 "><p id="p83447211482"><a name="p83447211482"></a><a name="p83447211482"></a>LOS_TaskLock</p>
73</td>
74<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p4344721480"><a name="p4344721480"></a><a name="p4344721480"></a>锁任务调度,但任务仍可被中断打断。</p>
75</td>
76</tr>
77<tr id="row8645184724712"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p133441025480"><a name="p133441025480"></a><a name="p133441025480"></a>LOS_TaskUnlock</p>
78</td>
79<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p934418217482"><a name="p934418217482"></a><a name="p934418217482"></a>解锁任务调度。</p>
80</td>
81</tr>
82<tr id="row16401849185317"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p54011249195317"><a name="p54011249195317"></a><a name="p54011249195317"></a>LOS_Schedule</p>
83</td>
84<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p640144919534"><a name="p640144919534"></a><a name="p640144919534"></a>触发任务调度。</p>
85</td>
86</tr>
87<tr id="row955081314485"><td class="cellrowborder" rowspan="3" valign="top" width="12.85128512851285%" headers="mcps1.2.4.1.1 "><p id="p11466102734816"><a name="p11466102734816"></a><a name="p11466102734816"></a>控制任务优先级</p>
88</td>
89<td class="cellrowborder" valign="top" width="29.8029802980298%" headers="mcps1.2.4.1.2 "><p id="p154664278482"><a name="p154664278482"></a><a name="p154664278482"></a>LOS_CurTaskPriSet</p>
90</td>
91<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p1046632764812"><a name="p1046632764812"></a><a name="p1046632764812"></a>设置当前任务的优先级。</p>
92</td>
93</tr>
94<tr id="row13909142489"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p5467927164811"><a name="p5467927164811"></a><a name="p5467927164811"></a>LOS_TaskPriSet</p>
95</td>
96<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p446772704811"><a name="p446772704811"></a><a name="p446772704811"></a>设置指定任务的优先级。</p>
97</td>
98</tr>
99<tr id="row355119149485"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p134671527134811"><a name="p134671527134811"></a><a name="p134671527134811"></a>LOS_TaskPriGet</p>
100</td>
101<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1946782717489"><a name="p1946782717489"></a><a name="p1946782717489"></a>获取指定任务的优先级。</p>
102</td>
103</tr>
104<tr id="row4964232175514"><td class="cellrowborder" rowspan="8" valign="top" width="12.85128512851285%" headers="mcps1.2.4.1.1 "><p id="p1512125013144"><a name="p1512125013144"></a><a name="p1512125013144"></a>获取任务信息</p>
105</td>
106<td class="cellrowborder" valign="top" width="29.8029802980298%" headers="mcps1.2.4.1.2 "><p id="p0142259562"><a name="p0142259562"></a><a name="p0142259562"></a>LOS_CurTaskIDGet</p>
107</td>
108<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p91419257568"><a name="p91419257568"></a><a name="p91419257568"></a>获取当前任务的ID。</p>
109</td>
110</tr>
111<tr id="row81994135812"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1620014131982"><a name="p1620014131982"></a><a name="p1620014131982"></a>LOS_NextTaskIDGet</p>
112</td>
113<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1297616371197"><a name="p1297616371197"></a><a name="p1297616371197"></a>获取任务就绪队列中优先级最高的任务的ID。</p>
114</td>
115</tr>
116<tr id="row1742101318812"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p147422136816"><a name="p147422136816"></a><a name="p147422136816"></a>LOS_NewTaskIDGet</p>
117</td>
118<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p18742101318812"><a name="p18742101318812"></a><a name="p18742101318812"></a>等同LOS_NextTaskIDGet。</p>
119</td>
120</tr>
121<tr id="row135511828165616"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p1235774875616"><a name="p1235774875616"></a><a name="p1235774875616"></a>LOS_CurTaskNameGet</p>
122</td>
123<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p52858313568"><a name="p52858313568"></a><a name="p52858313568"></a>获取当前任务的名称。</p>
124</td>
125</tr>
126<tr id="row1411710407583"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p81176407583"><a name="p81176407583"></a><a name="p81176407583"></a>LOS_TaskNameGet</p>
127</td>
128<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p1635193815613"><a name="p1635193815613"></a><a name="p1635193815613"></a>获取指定任务的名称。</p>
129</td>
130</tr>
131<tr id="row95431743121216"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p95431434127"><a name="p95431434127"></a><a name="p95431434127"></a>LOS_TaskStatusGet</p>
132</td>
133<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p57752481129"><a name="p57752481129"></a><a name="p57752481129"></a>获取指定任务的状态。</p>
134</td>
135</tr>
136<tr id="row5810125105712"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p57171053135711"><a name="p57171053135711"></a><a name="p57171053135711"></a>LOS_TaskInfoGet</p>
137</td>
138<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p77173535571"><a name="p77173535571"></a><a name="p77173535571"></a>获取指定任务的信息,包括任务状态、优先级、任务栈大小、栈顶指针SP、任务入口函数、已使用的任务栈大小等。</p>
139</td>
140</tr>
141<tr id="row3909121616111"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p490917165118"><a name="p490917165118"></a><a name="p490917165118"></a>LOS_TaskIsRunning</p>
142</td>
143<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p790991618113"><a name="p790991618113"></a><a name="p790991618113"></a>获取任务模块是否已经开始调度运行。</p>
144</td>
145</tr>
146<tr id="row248964211159"><td class="cellrowborder" valign="top" width="12.85128512851285%" headers="mcps1.2.4.1.1 "><p id="p194891428158"><a name="p194891428158"></a><a name="p194891428158"></a>任务信息维测</p>
147</td>
148<td class="cellrowborder" valign="top" width="29.8029802980298%" headers="mcps1.2.4.1.2 "><p id="p14891142171519"><a name="p14891142171519"></a><a name="p14891142171519"></a>LOS_TaskSwitchInfoGet</p>
149</td>
150<td class="cellrowborder" valign="top" width="57.34573457345735%" headers="mcps1.2.4.1.3 "><p id="p6490204221518"><a name="p6490204221518"></a><a name="p6490204221518"></a>获取任务切换信息,需要开启宏LOSCFG_BASE_CORE_EXC_TSK_SWITCH。</p>
151</td>
152</tr>
153</tbody>
154</table>
155
156## 开发流程<a name="section783435801510"></a>
157
158本节介绍任务模块的典型场景开发流程:
159
1601.  锁任务调度LOS\_TaskLock,防止高优先级任务调度。
1612.  创建任务LOS\_TaskCreate。
1623.  解锁任务LOS\_TaskUnlock,让任务按照优先级进行调度。
1634.  延时任务LOS\_TaskDelay,任务延时等待。
1645.  挂起指定的任务LOS\_TaskSuspend,任务挂起等待恢复操作。
1656.  恢复挂起的任务LOS\_TaskResume。
166
167>![](../public_sys-resources/icon-note.gif) **说明:**
168>-   执行Idle任务时,会对待回收链表中的任务控制块和任务栈进行回收。
169>-   任务名是指针,并没有分配空间,在设置任务名时,禁止将局部变量的地址赋值给任务名指针。
170>-   任务栈的大小按8字节大小对齐。确定任务栈大小的原则是,够用就行,多了浪费,少了任务栈溢出。
171>-   挂起当前任务时,如果已经锁任务调度,则无法挂起。
172>-   Idle任务及软件定时器任务不能被挂起或者删除。
173>-   在中断处理函数中或者在锁任务的情况下,执行LOS\_TaskDelay会失败。
174>-   锁任务调度,并不关中断,因此任务仍可被中断打断。
175>-   锁任务调度必须和解锁任务调度配合使用。
176>-   设置任务优先级时可能会发生任务调度。
177>-   可配置的系统最大任务数是指:整个系统的任务总个数,而非用户能使用的任务个数。例如:系统软件定时器多占用一个任务资源,那么用户能使用的任务资源就会减少一个。
178>-   LOS\_CurTaskPriSet和LOS\_TaskPriSet接口不能在中断中使用,也不能用于修改软件定时器任务的优先级。
179>-   LOS\_TaskPriGet接口传入的task ID对应的任务未创建或者超过最大任务数,统一返回-1。
180>-   在删除任务时要保证任务申请的资源(如互斥锁、信号量等)已被释放。
181
182## 编程实例<a name="section460018317164"></a>
183
184本实例介绍基本的任务操作方法,包含2个不同优先级任务的创建、任务延时、任务锁与解锁调度、挂起和恢复等操作,阐述任务优先级调度的机制以及各接口的应用。示例代码如下:
185
186```
187UINT32 g_taskHiId;
188UINT32 g_taskLoId;
189#define TSK_PRIOR_HI 4
190#define TSK_PRIOR_LO 5
191
192UINT32 Example_TaskHi(VOID)
193{
194    UINT32 ret;
195
196    printf("Enter TaskHi Handler.\n");
197
198    /* 延时100个Ticks,延时后该任务会挂起,执行剩余任务中最高优先级的任务(TaskLo任务) */
199    ret = LOS_TaskDelay(100);
200    if (ret != LOS_OK) {
201        printf("Delay TaskHi Failed.\n");
202        return LOS_NOK;
203    }
204
205    /* 100个Ticks时间到了后,该任务恢复,继续执行 */
206    printf("TaskHi LOS_TaskDelay Done.\n");
207
208    /* 挂起自身任务 */
209    ret = LOS_TaskSuspend(g_taskHiId);
210    if (ret != LOS_OK) {
211        printf("Suspend TaskHi Failed.\n");
212        return LOS_NOK;
213    }
214    printf("TaskHi LOS_TaskResume Success.\n");
215    return ret;
216}
217
218/* 低优先级任务入口函数 */
219UINT32 Example_TaskLo(VOID)
220{
221    UINT32 ret;
222
223    printf("Enter TaskLo Handler.\n");
224
225    /* 延时100个Ticks,延时后该任务会挂起,执行剩余任务中最高优先级的任务 */
226    ret = LOS_TaskDelay(100);
227    if (ret != LOS_OK) {
228        printf("Delay TaskLo Failed.\n");
229        return LOS_NOK;
230    }
231
232    printf("TaskHi LOS_TaskSuspend Success.\n");
233
234    /* 恢复被挂起的任务g_taskHiId */
235    ret = LOS_TaskResume(g_taskHiId);
236    if (ret != LOS_OK) {
237        printf("Resume TaskHi Failed.\n");
238        return LOS_NOK;
239    }
240    return ret;
241}
242
243/* 任务测试入口函数,创建两个不同优先级的任务 */
244UINT32 Example_TskCaseEntry(VOID)
245{
246    UINT32 ret;
247    TSK_INIT_PARAM_S initParam;
248
249    /* 锁任务调度,防止新创建的任务比本任务高而发生调度 */
250    LOS_TaskLock();
251
252    printf("LOS_TaskLock() Success!\n");
253
254    initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_TaskHi;
255    initParam.usTaskPrio = TSK_PRIOR_HI;
256    initParam.pcName = "TaskHi";
257    initParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
258
259    /* 创建高优先级任务,由于锁任务调度,任务创建成功后不会马上执行 */
260    ret = LOS_TaskCreate(&g_taskHiId, &initParam);
261    if (ret != LOS_OK) {
262        LOS_TaskUnlock();
263
264        printf("Example_TaskHi create Failed!\n");
265        return LOS_NOK;
266    }
267
268    printf("Example_TaskHi create Success!\n");
269
270    initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)Example_TaskLo;
271    initParam.usTaskPrio = TSK_PRIOR_LO;
272    initParam.pcName = "TaskLo";
273    initParam.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
274
275    /* 创建低优先级任务,由于锁任务调度,任务创建成功后不会马上执行 */
276    ret = LOS_TaskCreate(&g_taskLoId, &initParam);
277    if (ret != LOS_OK) {
278        LOS_TaskUnlock();
279        printf("Example_TaskLo create Failed!\n");
280        return LOS_NOK;
281    }
282
283    printf("Example_TaskLo create Success!\n");
284
285    /* 解锁任务调度,此时会发生任务调度,执行就绪队列中最高优先级任务 */
286    LOS_TaskUnlock();
287
288    return LOS_OK;
289}
290```
291
292### 结果验证<a name="section189023104457"></a>
293
294编译运行得到的结果为:
295
296```
297LOS_TaskLock() Success!
298Example_TaskHi create Success!
299Example_TaskLo create Success!
300Enter TaskHi Handler.
301Enter TaskLo Handler.
302TaskHi LOS_TaskDelay Done.
303TaskHi LOS_TaskSuspend Success.
304TaskHi LOS_TaskResume Success.
305```
306
307