• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Task
2
3
4## Basic Concepts
5
6Tasks are the minimum running units that compete for system resources. They can use or wait to use CPUs and use system resources such as memory. They run independently from one another.
7
8In the OpenHarmony kernel, a task represents a thread.
9
10Tasks for the processes of the same priority in the OpenHarmony kernel are scheduled and run in a unified manner.
11
12The tasks in the kernel use the preemptive scheduling mechanism, either round-robin (RR) scheduling or First In First Out (FIFO) scheduling.
13
14Tasks are assigned 32 priorities, ranging from **0** (highest) to **31** (lowest).
15
16In the same process, a higher-priority task can preempt resources of a lower-priority task. The lower-priority task can be scheduled only after the higher-priority task is blocked or terminated.
17
18**Task States**
19
20- Init: The task is being created.
21
22- Ready: The task is in the Ready queue and waits for scheduling by the CPU.
23
24- Running: The task is running.
25
26- Blocked: The task is blocked and suspended. The Blocked states include pending (blocked due to lock, event, or semaphore issues), suspended (active pending), delay (blocked due to delays), and pendtime (blocked by waiting timeout of locks, events, or semaphores).
27
28- Exit: The task is complete and waits for the parent task to reclaim its control block resources.
29
30  **Figure 1** Task state transition
31
32  ![](figures/task-state-transition.png "task-state-transition")
33
34**Task State Transition**
35
36- Init→Ready:
37  When a task is created, the task obtains the control block and enters the Init state (initialization). After the initialization is complete, the task is inserted into the scheduling queue and enters the Ready state.
38
39- Ready→Running:
40  When a task switching is triggered, the task with the highest priority in the Ready queue is executed and enters the Running state. Then, this task is deleted from the Ready queue.
41
42- Running→Blocked:
43  When a running task is blocked (for example, is pended, delayed, or reading semaphores), its state changes from Running to Blocked. Then, a task switching is triggered to run the task with the highest priority in the Ready queue.
44
45- Blocked→Ready:
46  After the blocked task is restored (the task is restored, the delay times out, the semaphore reading times out, or the semaphore is read), the task is added to the Ready queue and will change from the Blocked state to the Ready state.
47
48- Ready→Blocked:
49  When a task in the Ready state is blocked (suspended), the task changes to the Blocked state and is deleted from the Ready queue. The blocked task will not be scheduled until it is recovered.
50
51- Running→Ready:
52  When a task with a higher priority is created or recovered, tasks will be scheduled. The task with the highest priority in the Ready queue changes to the Running state. The originally running task changes to the Ready state and is added to the Ready queue.
53
54- Running→Exit:
55  When a running task is complete, it changes to the Exit state. If the task has a detach attribute (set by **LOS_TASK_STATUS_DETACHED** in **los_task.h**), it will be destroyed directly.
56
57
58## Working Principles
59
60The OpenHarmony task management module provides the following functions: creating, delaying, suspending, and restoring tasks, locking and unlocking task scheduling, and querying task control block information by ID.
61
62When a user creates a task, the system initializes the task stack and presets the context. The system places the task entry function in the corresponding position so that the function can be executed when the task enters the running state for the first time.
63
64
65## Development Guidelines
66
67
68### Available APIs
69
70**Table 1** APIs for creating and deleting a task
71
72| API            | Description                                                    |
73| ------------------ | ------------------------------------------------------------ |
74| LOS_TaskCreate     | Creates a task. If the priority of the created task is higher than that of the task in running and task scheduling is not locked, the task will be scheduled to run. |
75| LOS_TaskCreateOnly | Creates a task and blocks it. The task will not be added to the Ready queue unless it is resumed.            |
76| LOS_TaskDelete     | Deletes a task and reclaims the resources consumed by the task control block and task stack.        |
77
78**Table 2** APIs for controlling task status
79
80| API         | Description                                                    |
81| --------------- | ------------------------------------------------------------ |
82| LOS_TaskResume  | Resumes a suspended task.                                              |
83| LOS_TaskSuspend | Suspends a task. The suspended task will be removed from the Ready queue.                |
84| LOS_TaskJoin    | Blocks the current task until the specified task is complete, and reclaims its resources.              |
85| LOS_TaskDetach  | Changes the task attribute from **joinable** to **detach**. When a task of the **detach** attribute is complete, the task control block resources will be automatically reclaimed.|
86| LOS_TaskDelay   | Delays the current task for the specified time (number of ticks).            |
87| LOS_TaskYield   | Moves the current task from the queue of the tasks with the same priority to the end of the Ready queue.|
88
89**Table 3** APIs for task scheduling
90
91| API              | Description                                                    |
92| -------------------- | ------------------------------------------------------------ |
93| LOS_TaskLock         | Locks task scheduling to prevent task switching.                                  |
94| LOS_TaskUnlock       | Unlocks task scheduling. After that, the task lock count decrements by 1. If a task is locked multiple times, the task can be scheduled only when the number of locks is reduced to 0. |
95| LOS_GetTaskScheduler | Obtains the scheduling policy of a task.                                      |
96| LOS_SetTaskScheduler | Sets the scheduling parameters, including the priority and scheduling policy, for a task.                |
97| LOS_Schedule         | Triggers active task scheduling.                                          |
98
99**Table 4** APIs for obtaining task information
100
101| API                  | Description                |
102| ------------------------ | ------------------------ |
103| LOS_CurTaskIDGet         | Obtains the ID of the current task.        |
104| LOS_TaskInfoGet          | Obtains task information.      |
105| LOS_GetSystemTaskMaximum | Obtains the maximum number of tasks supported by the system.|
106
107**Table 5** APIs for managing task priorities
108
109| API           | Description                      |
110| ----------------- | ------------------------------ |
111| LOS_CurTaskPriSet | Sets a priority for the current task.|
112| LOS_TaskPriSet    | Sets a priority for a task.          |
113| LOS_TaskPriGet    | Obtains the priority of a task.          |
114
115**Table 6** APIs for setting CPU pinning
116
117| API            | Description                                   |
118| ------------------ | ------------------------------------------- |
119| LOS_TaskCpuAffiSet | Binds a task to the specified CPU core. This API is used only in multi-core CPUs.|
120| LOS_TaskCpuAffiGet | Obtains information about the core binding of a task. This API is used only in multi-core CPUs.     |
121
122
123
124### How to Develop
125
126The typical task development process is as follows:
127
1281. Call **LOS_TaskCreate** to create a task.
129   - Specify the execution entry function for the task.
130   - Specifies the task name.
131   - Specify the task stack size.
132   - Specify the priority of the task.
133   - Specify the task attribute, which can be **LOS_TASK_ATTR_JOINABLE** or **LOS_TASK_STATUS_DETACHED**.
134   - Specify the task-core binding attribute for multi-core environment.
135
1362. Run the service code to implement task scheduling.
137
1383. Reclaim resources when the task is complete. If the task attribute is **LOS_TASK_STATUS_DETACHED**, the task resources are automatically reclaimed. If the task attribute is **LOS_TASK_ATTR_JOINABLE**, call **LOS_TaskJoin** to reclaim task resources. The default task attribute is **LOS_TASK_STATUS_DETACHED**.
139
140> **NOTE**
141>
142> - The kernel mode has the highest permission and can operate tasks in any process.
143>
144> - If a task is created after a user-mode process enters the kernel mode by a system call, the task belongs to a KProcess not a user-mode process.
145
146
147### Development Example
148
149The sample code is as follows. You can add the test function of the sample code to **TestTaskEntry** in **kernel/liteos_a/testsuites/kernel/src /osTest.c** for testing
150
151
152```c
153UINT32 g_taskLoID;
154UINT32 g_taskHiID;
155#define TSK_PRIOR_HI 4
156#define TSK_PRIOR_LO 5
157UINT32 ExampleTaskHi(VOID)
158{
159    UINT32 ret;
160    PRINTK("Enter TaskHi Handler.\n");
161    /* Delay the task for 2 ticks. The task is suspended, and the remaining task with the highest priority (g_taskLoID) will be executed. */
162    ret = LOS_TaskDelay(2);
163    if (ret != LOS_OK) {
164        PRINTK("Delay Task Failed.\n");
165        return LOS_NOK;
166    }
167    /* After 2 ticks elapse, the task is resumed and executed. */
168    PRINTK("TaskHi LOS_TaskDelay Done.\n");
169    /* Suspend the task. */
170    ret = LOS_TaskSuspend(g_taskHiID);
171    if (ret != LOS_OK) {
172        PRINTK("Suspend TaskHi Failed.\n");
173        return LOS_NOK;
174    }
175    PRINTK("TaskHi LOS_TaskResume Success.\n");
176    return LOS_OK;
177}
178
179/* Entry function of the low-priority task. */
180UINT32 ExampleTaskLo(VOID)
181{
182    UINT32 ret;
183    PRINTK("Enter TaskLo Handler.\n");
184    /* Delay the task for 2 ticks. The task is suspended, and the remaining task with the highest priority (background task) will be executed. */
185    ret = LOS_TaskDelay(2);
186    if (ret != LOS_OK) {
187        PRINTK("Delay TaskLo Failed.\n");
188        return LOS_NOK;
189    }
190    PRINTK("TaskHi LOS_TaskSuspend Success.\n");
191    /* Resume the suspended task g_taskHiID. */
192    ret = LOS_TaskResume(g_taskHiID);
193    if (ret != LOS_OK) {
194        PRINTK("Resume TaskHi Failed.\n");
195        return LOS_NOK;
196    }
197    PRINTK("TaskHi LOS_TaskDelete Success.\n");
198    return LOS_OK;
199}
200/* Create two tasks with different priorities in the task test entry function. */
201UINT32 ExampleTaskCaseEntry(VOID)
202{
203    UINT32 ret;
204    TSK_INIT_PARAM_S initParam = {0};
205
206    /* Lock task scheduling. */
207    LOS_TaskLock();
208    PRINTK("LOS_TaskLock() Success!\n");
209    /* Parameters used to initialize the high-priority task, the resources of which can be reclaimed by LOS_TaskJoin. */
210    initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleTaskHi;
211    initParam.usTaskPrio = TSK_PRIOR_HI;
212    initParam.pcName = "HIGH_NAME";
213    initParam.uwStackSize = LOS_TASK_MIN_STACK_SIZE;
214    initParam.uwResved   = LOS_TASK_ATTR_JOINABLE;
215
216    /* Create a task with higher priority. The task will not be executed immediately after being created, because task scheduling is locked. */
217    ret = LOS_TaskCreate(&g_taskHiID, &initParam);
218    if (ret != LOS_OK) {
219        LOS_TaskUnlock();
220        PRINTK("ExampleTaskHi create Failed! ret=%d\n", ret);
221        return LOS_NOK;
222    }
223    PRINTK("ExampleTaskHi create Success!\n");
224
225    /* Parameters used to initialize the low-priority task, which will be automatically destroyed after the task is complete. */
226    initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleTaskLo;
227    initParam.usTaskPrio = TSK_PRIOR_LO;
228    initParam.pcName = "LOW_NAME";
229    initParam.uwStackSize = LOS_TASK_MIN_STACK_SIZE;
230    initParam.uwResved   = LOS_TASK_STATUS_DETACHED;
231
232    /* Create a low-priority task. The task will not be executed immediately after being created, because task scheduling is locked. */
233    ret = LOS_TaskCreate(&g_taskLoID, &initParam);
234    if (ret!= LOS_OK) {
235        LOS_TaskUnlock();
236        PRINTK("ExampleTaskLo create Failed!\n");
237        return LOS_NOK;
238    }
239    PRINTK("ExampleTaskLo create Success!\n");
240
241    /* Unlock task scheduling. The task with the highest priority in the Ready queue will be executed. */
242    LOS_TaskUnlock();
243    ret = LOS_TaskJoin(g_taskHiID, NULL);
244    if (ret != LOS_OK) {
245        PRINTK("Join ExampleTaskHi Failed!\n");
246    } else {
247        PRINTK("Join ExampleTaskHi Success!\n");
248    }
249    while(1){};
250    return LOS_OK;
251}
252```
253
254The development is successful if the return result is as follows:
255
256
257```
258LOS_TaskLock() Success!
259ExampleTaskHi create Success!
260ExampleTaskLo create Success!
261Enter TaskHi Handler.
262Enter TaskLo Handler.
263TaskHi LOS_TaskDelay Done.
264TaskHi LOS_TaskSuspend Success.
265TaskHi LOS_TaskResume Success.
266TaskHi LOS_TaskDelete Success.
267Join ExampleTaskHi Success!
268```
269