提交 49a5cdcf 编写于 作者: A Annie_wang

update docs

Signed-off-by: NAnnie_wang <annie.wangli@huawei.com>
上级 3aca0377
# Interrupt and Exception Handling # Interrupt and Exception Handling
## Basic Concepts<a name="section439816296117"></a> ## Basic Concepts
An interrupt is a signal to the processor emitted by hardware or software indicating an event that needs immediate attention. An interrupt alerts the processor of a high-priority condition requiring interruption of the code being executed by the processor. In this way, the CPU does not need to spend a lot of time in waiting and querying the peripheral status, which effectively improves the real-time performance and execution efficiency of the system. An interrupt is a signal to the processor emitted by hardware or software indicating an event that needs immediate attention. An interrupt alerts the processor of a high-priority condition requiring interruption of the code being executed by the processor. In this way, the CPU does not need to spend a lot of time in waiting and querying the peripheral status, which effectively improves the real-time performance and execution efficiency of the system.
Exception handling involves a series of actions taken by the OS to respond to exceptions \(chip hardware faults\) that occurred during the OS running, for example, printing the call stack information of the current function, CPU information, and call stack information of tasks when the virtual memory page is missing. OpenHarmony supports the following interrupt operations:
## Working Principles<a name="section2792838318"></a> + Initializing an interrupt.
+ Creating an interrupt.
+ Enabling or disabling interrupts.
+ Restoring the system status before interrupts are disabled.
+ Deleting an interrupt.
Peripherals can complete certain work without the intervention of the CPU. In some cases, however, the CPU needs to perform certain work for peripherals. With the interrupt mechanism, the CPU responds to the interrupt request from a peripheral only when required, and execute other tasks when the peripherals do not require the CPU. The interrupt controller receives the input of other peripheral interrupt pins and sends interrupt signals to the CPU. You can enable or disable the interrupt source and set the priority and trigger mode of the interrupt source by programming the interrupt controller. Common interrupt controllers include vector interrupt controllers \(VICs\) and general interrupt controllers \(GICs\). The ARM Cortex-A7 uses GICs. After receiving an interrupt signal sent by the interrupt controller, the CPU interrupts the current task to respond to the interrupt request. Exception handling involves a series of actions taken by the OS to respond to exceptions (chip hardware faults) that occurred during the OS running, for example, printing the call stack information of the current function, CPU information, and call stack information of tasks when the virtual memory page is missing.
Exception handling interrupts the normal running process of the CPU to handle exceptions, such as, undefined instructions, an attempt to modify read-only data, and unaligned address access. When an exception occurs, the CPU suspends the current program, handles the exception, and then continues to execute the program interrupted by the exception.
## Working Principles
Peripherals can complete certain work without the intervention of the CPU. In some cases, however, the CPU needs to perform certain work for peripherals. With the interrupt mechanism, the CPU responds to the interrupt request from a peripheral only when required, and execute other tasks when the peripherals do not require the CPU.
The interrupt controller receives the input from the interrupt pins of other peripherals and sends interrupt signals to the CPU. You can enable or disable the interrupt source and set the priority and trigger mode of the interrupt source by programming the interrupt controller. Common interrupt controllers include vector interrupt controllers (VICs) and general interrupt controllers (GICs). The ARM Cortex-A7 uses GICs.
After receiving an interrupt signal sent by the interrupt controller, the CPU interrupts the current task to respond to the interrupt request.
An exception interrupts the normal running process of the CPU to handle exceptions, such as, undefined instructions, an attempt to modify read-only data, and unaligned address access. When an exception occurs, the CPU suspends the current program, handles the exception, and then continues to execute the program interrupted by the exception.
The following uses the ARMv7-a architecture as an example. The interrupt vector table is the entry for interrupt and exception handling. The interrupt vector table contains the entry function for each interrupt and exception handling. The following uses the ARMv7-a architecture as an example. The interrupt vector table is the entry for interrupt and exception handling. The interrupt vector table contains the entry function for each interrupt and exception handling.
**Figure 1** Interrupt vector table<a name="fig1552753243714"></a> **Figure 1** Interrupt vector table
![](figures/interrupt-vector-table.png "interrupt-vector-table") ![](figures/interrupt-vector-table.png "interrupt-vector-table")
## Development Guidelines<a name="section15415165510110"></a>
## Development Guidelines
### Available APIs<a name="section57441612024"></a>
Exception handling is an internal mechanism and does not provide external APIs. The following table describes APIs available for the interrupt module. ### Available APIs
<a name="table11657113333110"></a> Exception handling is an internal mechanism and does not provide external APIs. The following tables describe the APIs available for the interrupt module.
<table><thead align="left"><tr id="row1170612337312"><th class="cellrowborder" valign="top" width="19.900000000000002%" id="mcps1.1.4.1.1"><p id="p4706133373112"><a name="p4706133373112"></a><a name="p4706133373112"></a><strong id="b7792162213202"><a name="b7792162213202"></a><a name="b7792162213202"></a>Function</strong></p>
</th> ##### Creating or Deleting an Interrupt
<th class="cellrowborder" valign="top" width="18.43%" id="mcps1.1.4.1.2"><p id="p1070653343117"><a name="p1070653343117"></a><a name="p1070653343117"></a><strong id="b19958356201"><a name="b19958356201"></a><a name="b19958356201"></a>API</strong></p>
</th> | API | Description |
<th class="cellrowborder" valign="top" width="61.67%" id="mcps1.1.4.1.3"><p id="p370613330311"><a name="p370613330311"></a><a name="p370613330311"></a><strong id="b1551072610204"><a name="b1551072610204"></a><a name="b1551072610204"></a>Description</strong></p> |------------ | ----------------------------------------------------------- |
</th> | LOS_HwiCreate | Creates an interrupt and registers the interrupt ID, triggering mode, priority, and interrupt handler. When the interrupt is triggered, the interrupt handler will be called.|
</tr> | LOS_HwiDelete | Deletes an interrupt based on the interrupt number. |
</thead>
<tbody><tr id="row8706123317311"><td class="cellrowborder" rowspan="2" valign="top" width="19.900000000000002%" headers="mcps1.1.4.1.1 "><p id="p4706193319318"><a name="p4706193319318"></a><a name="p4706193319318"></a>Creating or deleting interrupts</p> ##### Enabling or Disabling Interrupts
</td>
<td class="cellrowborder" valign="top" width="18.43%" headers="mcps1.1.4.1.2 "><p id="p170683310317"><a name="p170683310317"></a><a name="p170683310317"></a>LOS_HwiCreate</p> | API | Description |
</td> | -------------- | ------------------------------------------- |
<td class="cellrowborder" valign="top" width="61.67%" headers="mcps1.1.4.1.3 "><p id="p15706833163110"><a name="p15706833163110"></a><a name="p15706833163110"></a>Creates an interrupt and registers the interrupt ID, interrupt triggering mode, interrupt priority, and interrupt handler. When an interrupt is triggered, the interrupt handler will be called.</p> | LOS_IntUnlock | Enables all interrupts for the current processor. |
</td> | LOS_IntLock | Disables all interrupts for the current processor. |
</tr> | LOS_IntRestore | Restores the status in which the system was before **LOS_IntLock** is called.|
<tr id="row18706153318316"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p1870615332312"><a name="p1870615332312"></a><a name="p1870615332312"></a>LOS_HwiDelete</p>
</td> ##### Obtaining Interrupt Information
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p770616333313"><a name="p770616333313"></a><a name="p770616333313"></a>Deletes an interrupt.</p>
</td> | API | Description |
</tr> | ----------------------- | ------------------------ |
<tr id="row1370633316316"><td class="cellrowborder" rowspan="3" valign="top" width="19.900000000000002%" headers="mcps1.1.4.1.1 "><p id="p970611333318"><a name="p970611333318"></a><a name="p970611333318"></a>Enabling and disabling all interrupts</p> | LOS_GetSystemHwiMaximum | Obtains the maximum number of interrupts supported by the system.|
</td>
<td class="cellrowborder" valign="top" width="18.43%" headers="mcps1.1.4.1.2 "><p id="p147061033103117"><a name="p147061033103117"></a><a name="p147061033103117"></a>LOS_IntUnLock</p>
</td>
<td class="cellrowborder" valign="top" width="61.67%" headers="mcps1.1.4.1.3 "><p id="p93681327171713"><a name="p93681327171713"></a><a name="p93681327171713"></a>Enables all interrupts of the current processor.</p> ### How to Develop
</td>
</tr> 1. Call **LOS_HwiCreate** to create an interrupt.
<tr id="row1270603314312"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p1970623343114"><a name="p1970623343114"></a><a name="p1970623343114"></a>LOS_IntLock</p>
</td> 2. Call **LOS_HwiDelete** to delete the specified interrupt. Use this API based on actual requirements.
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p1161283971712"><a name="p1161283971712"></a><a name="p1161283971712"></a>Disables all interrupts for the current processor.</p>
</td>
</tr> ### Development Example
<tr id="row8706233173113"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p1770620337313"><a name="p1770620337313"></a><a name="p1770620337313"></a>LOS_IntRestore</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p1470643323112"><a name="p1470643323112"></a><a name="p1470643323112"></a>Restores to the status before all interrupts are disabled by using <strong id="b354311504226"><a name="b354311504226"></a><a name="b354311504226"></a>LOS_IntLock</strong>.</p>
</td>
</tr>
<tr id="row870793320317"><td class="cellrowborder" valign="top" width="19.900000000000002%" headers="mcps1.1.4.1.1 "><p id="p1970763318316"><a name="p1970763318316"></a><a name="p1970763318316"></a>Obtaining the maximum number of interrupts supported</p>
</td>
<td class="cellrowborder" valign="top" width="18.43%" headers="mcps1.1.4.1.2 "><p id="p1707333123115"><a name="p1707333123115"></a><a name="p1707333123115"></a>LOS_GetSystemHwiMaximum</p>
</td>
<td class="cellrowborder" valign="top" width="61.67%" headers="mcps1.1.4.1.3 "><p id="p4707173323111"><a name="p4707173323111"></a><a name="p4707173323111"></a>Obtains the maximum number of interrupts supported by the system.</p>
</td>
</tr>
</tbody>
</table>
### How to Develop<a name="section64332181221"></a>
1. Call **LOS\_HwiCreate** to create an interrupt.
2. Call **LOS\_HwiDelete** to delete the specified interrupt. Use this API based on actual requirements.
### Development Example<a name="section204698276478"></a>
This example implements the following: This example implements the following:
1. Create an interrupt.
2. Delete an interrupt.
The following sample code shows how to create and delete an interrupt. When the interrupt **HWI\_NUM\_TEST** is generated, the interrupt handler function will be called. 1. Create an interrupt.
``` 2. Delete an interrupt.
The following sample code demostrates how to create and delete an interrupt, and call the interrupt handler when the specified interrupt **HWI_NUM_TEST** is triggered. You can add the test function of the sample code to **TestTaskEntry** in **kernel/liteos_a/testsuites/kernel/src/osTest.c** for testing.
The sample code is as follows:
```c
#include "los_hwi.h" #include "los_hwi.h"
/* Interrupt handler function*/ /* Interrupt handler function*/
STATIC VOID HwiUsrIrq(VOID) STATIC VOID HwiUsrIrq(VOID)
{ {
printf("in the func HwiUsrIrq \n"); PRINTK("in the func HwiUsrIrq \n");
} }
static UINT32 Example_Interrupt(VOID) static UINT32 Example_Interrupt(VOID)
{ {
UINT32 ret; UINT32 ret;
HWI_HANDLE_T hwiNum = 7; HWI_HANDLE_T hwiNum = 7; // The interrupt number is 7.
HWI_PRIOR_T hwiPrio = 3; HWI_PRIOR_T hwiPrio = 3; // The interrupt priority is 3.
HWI_MODE_T mode = 0; HWI_MODE_T mode = 0;
HWI_ARG_T arg = 0; HWI_ARG_T arg = 0;
/* Create an interrupt.*/ /* Create an interrupt. */
ret = LOS_HwiCreate(hwiNum, hwiPrio, mode, (HWI_PROC_FUNC)HwiUsrIrq, (HwiIrqParam *)arg); ret = LOS_HwiCreate(hwiNum, hwiPrio, mode, (HWI_PROC_FUNC)HwiUsrIrq, (HwiIrqParam *)arg);
if(ret == LOS_OK){ if (ret == LOS_OK) {
printf("Hwi create success!\n"); PRINTK("Hwi create success!\n");
} else { } else {
printf("Hwi create failed!\n"); PRINTK("Hwi create failed!\n");
return LOS_NOK; return LOS_NOK;
} }
/* Delay 50 ticks. When a hardware interrupt occurs, call the HwiUsrIrq function.*/ /* Delay 50 ticks. Call HwiUsrIrq when a hardware interrupt occurs. */
LOS_TaskDelay(50); LOS_TaskDelay(50);
/* Delete an interrupt./ /* Delete the interrupt. */
ret = LOS_HwiDelete(hwiNum, (HwiIrqParam *)arg); ret = LOS_HwiDelete(hwiNum, (HwiIrqParam *)arg);
if(ret == LOS_OK){ if (ret == LOS_OK) {
printf("Hwi delete success!\n"); PRINTK("Hwi delete success!\n");
} else { } else {
printf("Hwi delete failed!\n"); PRINTK("Hwi delete failed!\n");
return LOS_NOK; return LOS_NOK;
} }
return LOS_OK; return LOS_OK;
} }
``` ```
### Verification<a name="section1466144215476"></a>
### Verification
The development is successful if the return result is as follows: The development is successful if the return result is as follows:
...@@ -134,4 +133,3 @@ The development is successful if the return result is as follows: ...@@ -134,4 +133,3 @@ The development is successful if the return result is as follows:
Hwi create success! Hwi create success!
Hwi delete success! Hwi delete success!
``` ```
# Process # Process
## Basic Concepts<a name="section89346055119"></a> ## Basic Concepts
A process is the minimum unit for system resource management. The process module provided by the OpenHarmony LiteOS-A kernel is used to isolate user-mode processes. The kernel mode is considered as a process space and does not have other processes except KIdle, which is an idle process provided by the system and shares the same process space with KProcess. A process is the minimum unit for system resource management. The process module provided by the OpenHarmony LiteOS-A kernel isolates user-mode processes. The kernel mode is considered as a process space and does not have other processes except KIdle, which is an idle process provided by the system and shares the same process space with KProcess. KProcess is the root process of kernel-mode processes, and KIdle is its child process.
- The process module provides multiple processes for users and implements switching and communication between processes, facilitating your management over service programs. - The process module provides multiple processes for users and implements switching and communication between processes, facilitating your management over service programs.
- The processes use the preemption scheduling mechanism. The processes with a higher priority are scheduled first, and the processes with the same priority are scheduled using the time slice polling.
- The processes are assigned 32 priorities \(**0** to **31**\). Among them, user processes can be configured with 22 priorities from **10** \(highest\) to **31** \(lowest\).
- A higher-priority process can preempt the resources of a lower-priority process. The lower-priority process can be scheduled only after the higher-priority process is blocked or terminated.
- Each user-mode process has its own memory space, which is invisible to other processes. In this way, processes are isolated from each other.
- The user-mode root process **init** is created by the kernel. Other user-mode processes are created by the **init** process via the **fork** call.
**Process States:** - The processes use the preemption scheduling mechanism. The processes with a higher priority are scheduled first, and the processes with the same priority are scheduled using the time slice round robin.
- Init: The process is being created. - The processes are assigned 32 priorities (**0** to **31**). Among them, user processes can be configured with 22 priorities from **10** (highest) to **31** (lowest).
- Ready: The process is in the Ready queue and waits for scheduling by the CPU. - A higher-priority process can preempt the resources of a lower-priority process. The lower-priority process can be scheduled only after the higher-priority process is blocked or terminated.
- Running: The process is running.
- Pending: The process is blocked and suspended. When all threads in a process are blocked, the process is blocked and suspended.
- Zombies: The process stops running and waits for the parent process to reclaim its control block resources.
**Figure 1** Process state transition<a name="fig536823565718"></a> - Each user-mode process has its own memory space, which is invisible to other processes. In this way, processes are isolated from each other.
![](figures/process-state-transition.png "process-state-transition")
**Process State Transition:** - The user-mode root process **init** is created by the kernel. Other user-mode processes are created by the **init** process via the **fork** call.
- Init→Ready: **Process States**
When a process is created, the process enters the Init state after obtaining the process control block to start initialization. After the process is initialized, the process is inserted into the scheduling queue and therefore enters the Ready state. - Init: The process is being created.
- Ready→Running: - Ready: The process is in the Ready queue and waits for scheduling by the CPU.
When a process switchover is triggered, the process with the highest priority in the Ready queue is executed and enters the Running state. If this process has no thread in the Ready state, the process is deleted from the Ready queue and resides only in the Running state. If it has threads in the Ready state, the process still stays in the Ready queue. In this case, the process is in both the Ready and Running states, but presented as the Running state. - Running: The process is running.
- Running→Pending: - Pending: The process is blocked and suspended. When all threads in a process are blocked, the process is blocked and suspended.
When the last thread of a process enters the Pending state, all threads in the process are in the Pending state. Then, the process enters the Pending state, and process switching occurs. - Zombies: The process stops running and waits for the parent process to reclaim its control block resources.
- Pending→Ready: **Figure 1** Process state transition
When any thread in a Pending process restores to the Ready state, the process is added to the Ready queue and changes to the Ready state. ![](figures/process-state-transition.png "process-state-transition")
- Ready→Pending: **Process State Transition**
When the last ready thread in a process enters the Pending state, the process is deleted from the Ready queue, and the process changes from the Ready state to the Pending state. - Init→Ready:
When a process is created or forked, the process enters the Init state after obtaining the process control block. When the process initialization is complete, the process is added to the scheduling queue, and the process enters the Ready state.
- Running→Ready: - Ready→Running:
When process switching occurs, the process that has the highest priority and time slice in the Ready queue is executed and enters the Running state. If this process has no thread in the Ready state, the process is deleted from the Ready queue and resides only in the Running state. If it has threads in the Ready state, the process still stays in the Ready queue. In this case, the process is in both the Ready and Running states, but presented as the Running state.
A process may change from the Running state to the Ready state in either of the following scenarios: - Running→Pending:
When the last thread of a process enters the Pending state, all threads in the process are in the Pending state. Then, the process enters the Pending state, and process switching occurs.
1. After a process with a higher priority is created or restored, processes will be scheduled. The process with the highest priority in the Ready queue will change to the Running state, and the originally running process will change from the Running state to the Ready state. - Pending→Ready:
2. If scheduling policy for a process is **LOS\_SCHED\_RR** and its priority is the same as that of another process in the Ready state, this process will change from the Running state to the Ready state after its time slices are used up, and the other process with the same priority will change from the Ready state to the Running state. When any thread in a Pending process restores to the Ready state, the process is added to the Ready queue and changes to the Ready state.
- Running→Zombies: - Ready→Pending:
When the last ready thread in a process enters the Pending state, the process is deleted from the Ready queue, and the process changes from the Ready state to the Pending state.
After the main thread or all threads of a process are stopped, the process changes from the **Running** state to the **Zombies** state and waits for the parent process to reclaim resources. - Running→Ready:
A process may change from the Running state to the Ready state in either of the following scenarios:
1. After a process with a higher priority is created or restored, processes will be scheduled. The process with the highest priority in the Ready queue will change to the Running state, and the originally running process will change from the Running state to the Ready state.
2. If scheduling policy for a process is **LOS_SCHED_RR** (time slice round robin) and its priority is the same as that of another process in the Ready state, this process will change from the Running state to the Ready state after its time slices are used up, and the other process with the same priority will change from the Ready state to the Running state.
## Working Principles<a name="section174514474512"></a> - Running→Zombies:
After the main thread or all threads of a process are stopped, the process changes from the **Running** state to the **Zombies** state and waits for the parent process to reclaim resources.
## Working Principles
The OpenHarmony process module is used to isolate user-mode processes and supports the following functions: creating and exiting user-mode processes, reclaiming process resources, setting and obtaining scheduling parameters and process group IDs, and obtaining process IDs. The OpenHarmony process module is used to isolate user-mode processes and supports the following functions: creating and exiting user-mode processes, reclaiming process resources, setting and obtaining scheduling parameters and process group IDs, and obtaining process IDs.
...@@ -66,105 +68,65 @@ A user-mode process is created by forking a parent process. During forking, the ...@@ -66,105 +68,65 @@ A user-mode process is created by forking a parent process. During forking, the
A process is only a resource management unit, and the actual running is executed by threads in the process. When switching occurs between threads in different processes, the process space will be switched. A process is only a resource management unit, and the actual running is executed by threads in the process. When switching occurs between threads in different processes, the process space will be switched.
**Figure 2** Process management<a name="fig123709256334"></a> **Figure 2** Process management
![](figures/process-management.png "process-management") ![](figures/process-management.png "process-management")
## Development Guidelines<a name="section159637182521"></a>
### Available APIs<a name="section1153124135212"></a>
**Table 1** Process management module APIs
<a name="table359914125718"></a>
<table><thead align="left"><tr id="row85991712770"><th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.1"><p id="p13162121815218"><a name="p13162121815218"></a><a name="p13162121815218"></a><strong id="b1498913473"><a name="b1498913473"></a><a name="b1498913473"></a>Function</strong></p>
</th>
<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.2"><p id="p12162618623"><a name="p12162618623"></a><a name="p12162618623"></a><strong id="b3249144342911"><a name="b3249144342911"></a><a name="b3249144342911"></a>API</strong></p>
</th>
<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.2.4.1.3"><p id="p16162118427"><a name="p16162118427"></a><a name="p16162118427"></a><strong id="b1858304911219"><a name="b1858304911219"></a><a name="b1858304911219"></a>Description</strong></p>
</th>
</tr>
</thead>
<tbody><tr id="row66002121074"><td class="cellrowborder" rowspan="4" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p13571544484"><a name="p13571544484"></a><a name="p13571544484"></a>Process scheduling parameter control</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p7571644283"><a name="p7571644283"></a><a name="p7571644283"></a>LOS_GetProcessScheduler</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p205724410813"><a name="p205724410813"></a><a name="p205724410813"></a>Obtains the scheduling policy of the specified process.</p>
</td>
</tr>
<tr id="row166001712574"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p6571144286"><a name="p6571144286"></a><a name="p6571144286"></a>LOS_SetProcessScheduler</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p18572443819"><a name="p18572443819"></a><a name="p18572443819"></a>Sets the scheduling parameters, including the priority and scheduling policy, for the specified process.</p>
</td>
</tr>
<tr id="row1560071212719"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p3571144885"><a name="p3571144885"></a><a name="p3571144885"></a>LOS_GetProcessPriority</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p95710448818"><a name="p95710448818"></a><a name="p95710448818"></a>Obtains the priority of the specified process.</p>
</td>
</tr>
<tr id="row1274011131587"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p17572443812"><a name="p17572443812"></a><a name="p17572443812"></a>LOS_SetProcessPriority</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p16573445819"><a name="p16573445819"></a><a name="p16573445819"></a>Sets the priority of the specified process.</p>
</td>
</tr>
<tr id="row162882182816"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p175734417814"><a name="p175734417814"></a><a name="p175734417814"></a>Waiting for reclaiming child processes</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p165754410812"><a name="p165754410812"></a><a name="p165754410812"></a>LOS_Wait</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p5578441687"><a name="p5578441687"></a><a name="p5578441687"></a>Waits for the specified child process to terminate, and reclaims its resources.</p>
</td>
</tr>
<tr id="row81051920589"><td class="cellrowborder" rowspan="2" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p4571844289"><a name="p4571844289"></a><a name="p4571844289"></a>Process group</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p20578442083"><a name="p20578442083"></a><a name="p20578442083"></a>LOS_GetProcessGroupID</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p145704416818"><a name="p145704416818"></a><a name="p145704416818"></a>Obtains the process group ID of the specified process.</p>
</td>
</tr>
<tr id="row13410161611819"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p657944289"><a name="p657944289"></a><a name="p657944289"></a>LOS_GetCurrProcessGroupID</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p165816445819"><a name="p165816445819"></a><a name="p165816445819"></a>Obtains the process group ID of the current process.</p>
</td>
</tr>
<tr id="row1260011213718"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p125818441781"><a name="p125818441781"></a><a name="p125818441781"></a>Obtaining the process ID.</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p25814445819"><a name="p25814445819"></a><a name="p25814445819"></a>LOS_GetCurrProcessID</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p1058644687"><a name="p1058644687"></a><a name="p1058644687"></a>Obtains the ID of the current process.</p>
</td>
</tr>
<tr id="row060019121871"><td class="cellrowborder" rowspan="3" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p145810441285"><a name="p145810441285"></a><a name="p145810441285"></a>User and user group</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p10581744783"><a name="p10581744783"></a><a name="p10581744783"></a>LOS_GetUserID</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p7581944287"><a name="p7581944287"></a><a name="p7581944287"></a>Obtains the user ID of the current process.</p>
</td>
</tr>
<tr id="row1160021211713"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p18582447814"><a name="p18582447814"></a><a name="p18582447814"></a>LOS_GetGroupID</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p3581444382"><a name="p3581444382"></a><a name="p3581444382"></a>Obtains the user group ID of the current process.</p>
</td>
</tr>
<tr id="row1160018123717"><td class="cellrowborder" valign="top" headers="mcps1.2.4.1.1 "><p id="p19589442084"><a name="p19589442084"></a><a name="p19589442084"></a>LOS_CheckInGroups</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.2.4.1.2 "><p id="p5581144689"><a name="p5581144689"></a><a name="p5581144689"></a>Checks whether the specified user group ID is in the user group of the current process.</p>
</td>
</tr>
<tr id="row317461111812"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.1 "><p id="p105814419818"><a name="p105814419818"></a><a name="p105814419818"></a>Maximum number of processes supported</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.2 "><p id="p3583441888"><a name="p3583441888"></a><a name="p3583441888"></a>LOS_GetSystemProcessMaximum</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.2.4.1.3 "><p id="p115818441187"><a name="p115818441187"></a><a name="p115818441187"></a>Obtains the maximum number of processes supported by the system.</p>
</td>
</tr>
</tbody>
</table>
### How to Develop<a name="section1533674618526"></a>
Kernel-mode processes cannot be created. Therefore, kernel-mode process development is not involved. ## Development Guidelines
### Available APIs
**Table 1** APIs for processes and process groups
| API | Description |
| ------------------------- | ---------------------- |
| LOS_GetCurrProcessID | Obtains the ID of the current process. |
| LOS_GetProcessGroupID | Obtains the process group ID of the specified process.|
| LOS_GetCurrProcessGroupID | Obtains the process group ID of the current process.|
**Table 2** APIs for users and user groups
| API | Description |
| ----------------- | ---------------------------------------- |
| LOS_GetUserID | Obtains the user ID of the current process. |
| LOS_GetGroupID | Obtains the user group ID of the current process. |
| LOS_CheckInGroups | Checks whether the specified user group ID is in the user group of the current process.|
>![](../public_sys-resources/icon-note.gif) **NOTE:** **Table 3** APIs for process scheduling
>- The number of idle threads depends on the number of CPU cores. Each CPU has a corresponding idle thread.
>- Except KProcess and KIdle, other kernel-mode processes cannot be created. | API | API |
>- If a thread is created after a user-mode process enters the kernel mode by a system call, the thread belongs to a KProcess not a user-mode process. | ----------------------- | -------------------------------------------- |
| LOS_GetProcessScheduler | Obtains the scheduling policy of a process. |
| LOS_SetProcessScheduler | Sets scheduling parameters, including the priority and scheduling policy, for a process.|
| LOS_SetProcessPriority | Sets the process priority. |
| LOS_GetProcessPriority | Obtains the priority of a process. |
**Table 4** APIs for obtaining system process information
| API | Description |
| --------------------------- | -------------------------- |
| LOS_GetSystemProcessMaximum | Obtains the maximum number of processes supported by the system.|
| LOS_GetUsedPIDList | Obtains a list of used process IDs. |
**Table 5** APIs for managing processes
| API | Description |
| ---------- | -------------------------- |
| LOS_Fork | Creates a child process. |
| LOS_Wait | Waits for the child process to terminate, and reclaims its resources.|
| LOS_Waitid | Wait for the specified process to terminate. |
| LOS_Exit | Exits a process. |
### How to Develop
Kernel-mode processes cannot be created. Therefore, kernel-mode process development is not involved.
> **NOTE**
>
> - The number of idle threads depends on the number of CPU cores. Each CPU has a corresponding idle thread.
>- Except KProcess and KIdle, other kernel-mode processes cannot be created.
> - If a thread is created after a user-mode process enters the kernel mode by a system call, the thread belongs to a KProcess not a user-mode process.
# Scheduler # Scheduler
## Basic Concepts<a name="section123882355719"></a> ## Basic Concepts
The OpenHarmony LiteOS-A kernel uses the preemptive scheduling mechanism for tasks. The tasks with a higher priority are scheduled first, and the tasks with the same priority are scheduled using the time slice polling. The system runs based on the real-time timeline from the startup, which ensures good real-time performance of the scheduling algorithm. The OpenHarmony LiteOS-A kernel uses the preemptive scheduling mechanism for tasks. The tasks with a higher priority are scheduled first, and the tasks with the same priority are scheduled using the time slice polling. The system runs based on the real-time timeline from the startup, which ensures good real-time performance of the scheduling algorithm.
The OpenHarmony scheduling algorithm is embedded with the tickless mechanism, which ensures lower power consumption and on-demand response to tick interrupts. This minimizes useless tick interrupt response time and further improves the real-time performance of the system. The OpenHarmony scheduling algorithm is embedded with the tickless mechanism, which ensures lower power consumption and on-demand response to tick interrupts. This minimizes useless tick interrupt response time and further improves the real-time performance of the system.
The OpenHarmony process scheduling policy is **SCHED\_RR**, and the thread scheduling policy can be **SCHED\_RR** or **SCHED\_FIFO**. OpenHarmony supports **SCHED_RR** (time slice round robin) for process scheduling and **SCHED_RR** and **SCHED_FIFO** (first in, first out) for thread scheduling .
Threads are the minimum scheduling units in the OpenHarmony. Threads are the minimum scheduling units in OpenHarmony.
## Working Principles<a name="section143015396572"></a>
The OpenHarmony uses process priority queue and thread priority queue for scheduling. The process priority ranges from 0 to 31, and there are 32 process priority bucket queues. Each bucket queue corresponds to a thread priority bucket queue. The thread priority ranges from 0 to 31, and a thread priority bucket queue also has 32 priority queues. ## Working Principles
OpenHarmony uses process priority queue and thread priority queue for scheduling. The process priority ranges from 0 to 31, and there are 32 process priority bucket queues. Each bucket queue corresponds to a thread priority bucket queue. The thread priority ranges from 0 to 31, and a thread priority bucket queue also has 32 priority queues.
**Figure 1** Scheduling priority bucket queue
**Figure 1** Scheduling priority bucket queue<a name="fig124425991619"></a>
![](figures/scheduling-priority-bucket-queue.png "scheduling-priority-bucket-queue") ![](figures/scheduling-priority-bucket-queue.png "scheduling-priority-bucket-queue")
The OpenHarmony system starts scheduling after the kernel initialization is complete. The processes or threads created during running are added to the scheduling queues. The system selects the optimal thread for scheduling based on the priorities of the processes and threads and the time slice consumption of the threads. Once a thread is scheduled, it is deleted from the scheduling queue. If a thread is blocked during running, the thread is added to the corresponding blocking queue and triggers scheduling of another thread. If no thread in the scheduling queue can be scheduled, the system selects the thread of the KIdle process for scheduling. The OpenHarmony system starts scheduling after the kernel initialization is complete. The processes or threads created during running are added to the scheduling queues. The system selects the optimal thread for scheduling based on the priorities of the processes and threads and the time slice consumption of the threads. Once a thread is scheduled, it is deleted from the scheduling queue. If a thread is blocked during running, the thread is added to the corresponding blocking queue and triggers scheduling of another thread. If no thread in the scheduling queue can be scheduled, the system selects the thread of the KIdle process for scheduling.
**Figure 2** Scheduling process<a name="fig1163494931810"></a> **Figure 2** Scheduling process
![](figures/scheduling-process.png "scheduling-process") ![](figures/scheduling-process.png "scheduling-process")
## Development Guidelines<a name="section10604192145816"></a>
### Available APIs<a name="section207985910582"></a>
<a name="table687929113814"></a>
<table><thead align="left"><tr id="row513082983812"><th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.1.4.1.1"><p id="p121309298384"><a name="p121309298384"></a><a name="p121309298384"></a><strong id="b1684811125913"><a name="b1684811125913"></a><a name="b1684811125913"></a>Function</strong></p>
</th>
<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.1.4.1.2"><p id="p713082933817"><a name="p713082933817"></a><a name="p713082933817"></a>API</p>
</th>
<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.1.4.1.3"><p id="p20130829123810"><a name="p20130829123810"></a><a name="p20130829123810"></a><strong id="b66639257454"><a name="b66639257454"></a><a name="b66639257454"></a>Description</strong></p>
</th>
</tr>
</thead>
<tbody><tr id="row713032973813"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p0130429133818"><a name="p0130429133818"></a><a name="p0130429133818"></a>System scheduling</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p71581556124414"><a name="p71581556124414"></a><a name="p71581556124414"></a>LOS_Schedule</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p181303297387"><a name="p181303297387"></a><a name="p181303297387"></a>Triggers system scheduling.</p>
</td>
</tr>
</tbody>
</table>
### How to Develop<a name="section1015110331584"></a>
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>Scheduling cannot be triggered during the system initialization process.
## Development Guidelines
### Available APIs
| API| Description|
| -------- | -------- |
| LOS_Schedule | Triggers system scheduling.|
| LOS_GetTaskScheduler | Obtains the scheduling policy of a task.|
| LOS_SetTaskScheduler | Sets the scheduling policy for a task.|
| LOS_GetProcessScheduler | Obtains the scheduling policy of a process.|
| LOS_SetProcessScheduler | Sets scheduling parameters, including the priority and scheduling policy, for a process.|
### How to Develop
> **NOTE**
>
> Scheduling cannot be triggered during the system initialization process.
# Task # Task
## Basic Concepts<a name="section138411646175417"></a>
## Basic Concepts
Tasks 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. Tasks 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.
In the OpenHarmony kernel, a task represents a thread. In the OpenHarmony kernel, a task represents a thread.
Tasks in the processes of the same priority in the OpenHarmony kernel are scheduled and run in a unified manner. Tasks for the processes of the same priority in the OpenHarmony kernel are scheduled and run in a unified manner.
The tasks in the kernel use the preemptive scheduling mechanism, either round-robin \(RR\) scheduling or First In First Out \(FIFO\) scheduling. The tasks in the kernel use the preemptive scheduling mechanism, either round-robin (RR) scheduling or First In First Out (FIFO) scheduling.
Tasks are assigned 32 priorities, ranging from **0** \(highest\) to **31** \(lowest\). Tasks are assigned 32 priorities, ranging from **0** (highest) to **31** (lowest).
In 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. In 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.
**Task Status Description** **Task States**
- Init: The task is being created.
- Ready: The task is in the Ready queue and waits for scheduling by the CPU.
- Running: The task is running.
- 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).
- Exit: The task is complete and waits for the parent task to reclaim its control block resources.
- Init: The task is being created. **Figure 1** Task state transition
- Ready: The task is in the Ready queue and waits for scheduling by the CPU.
- Running: The task is running.
- 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\).
- Exit: The task is complete and waits for the parent task to reclaim its control block resources.
**Figure 1** Task state transition<a name="fig5251243193113"></a> ![](figures/task-state-transition.png "task-state-transition")
![](figures/task-state-transition.png "task-state-transition")
**Task State Transition** **Task State Transition**
- Init→Ready: - Init→Ready:
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.
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. - Ready→Running:
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.
- Ready→Running: - Running→Blocked:
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.
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. - Blocked→Ready:
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.
- Running→Blocked: - Ready→Blocked:
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.
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. - Running→Ready:
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.
- Blocked→Ready: - Running→Exit:
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.
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.
- Ready→Blocked: ## Working Principles
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. The 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.
- Running→Ready: When 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.
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.
- Running→Exit: ## Development Guidelines
When a running task is complete, it changes to the Exit state. If the task is set with a detach attribute \(**LOS\_TASK\_STATUS\_DETACHED**\), it will be directly destroyed after being terminated.
### Available APIs
## Working Principles<a name="section1381918945512"></a> **Table 1** APIs for creating and deleting a task
The 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. | API | Description |
| ------------------ | ------------------------------------------------------------ |
| 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. |
| LOS_TaskCreateOnly | Creates a task and blocks it. The task will not be added to the Ready queue unless it is resumed. |
| LOS_TaskDelete | Deletes a task and reclaims the resources consumed by the task control block and task stack. |
**Table 2** APIs for controlling task status
| API | Description |
| --------------- | ------------------------------------------------------------ |
| LOS_TaskResume | Resumes a suspended task. |
| LOS_TaskSuspend | Suspends a task. The suspended task will be removed from the Ready queue. |
| LOS_TaskJoin | Blocks the current task until the specified task is complete, and reclaims its resources. |
| 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.|
| LOS_TaskDelay | Delays the current task for the specified time (number of ticks). |
| LOS_TaskYield | Moves the current task from the queue of the tasks with the same priority to the end of the Ready queue.|
**Table 3** APIs for task scheduling
When a task is created, the system initializes the task stack and presets the context. The system also 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. | API | Description |
| -------------------- | ------------------------------------------------------------ |
## Development Guidelines<a name="section10649727135519"></a> | LOS_TaskLock | Locks task scheduling to prevent task switching. |
| 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. |
### Available APIs<a name="section78333315555"></a> | LOS_GetTaskScheduler | Obtains the scheduling policy of a task. |
| LOS_SetTaskScheduler | Sets the scheduling parameters, including the priority and scheduling policy, for a task. |
<a name="table687929113814"></a> | LOS_Schedule | Triggers active task scheduling. |
<table><thead align="left"><tr id="row513082983812"><th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.1.4.1.1"><p id="p121309298384"><a name="p121309298384"></a><a name="p121309298384"></a><strong id="b1288394945813"><a name="b1288394945813"></a><a name="b1288394945813"></a>Function</strong></p>
</th> **Table 4** APIs for obtaining task information
<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.1.4.1.2"><p id="p713082933817"><a name="p713082933817"></a><a name="p713082933817"></a><strong id="b184372716456"><a name="b184372716456"></a><a name="b184372716456"></a>API</strong></p>
</th> | API | Description |
<th class="cellrowborder" valign="top" width="33.33333333333333%" id="mcps1.1.4.1.3"><p id="p20130829123810"><a name="p20130829123810"></a><a name="p20130829123810"></a><strong id="b27211529174516"><a name="b27211529174516"></a><a name="b27211529174516"></a>Description</strong></p> | ------------------------ | ------------------------ |
</th> | LOS_CurTaskIDGet | Obtains the ID of the current task. |
</tr> | LOS_TaskInfoGet | Obtains task information. |
</thead> | LOS_GetSystemTaskMaximum | Obtains the maximum number of tasks supported by the system.|
<tbody><tr id="row431611256303"><td class="cellrowborder" rowspan="3" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p0297202573015"><a name="p0297202573015"></a><a name="p0297202573015"></a>Task creation and deletion</p>
</td> **Table 5** APIs for managing task priorities
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p1229720252303"><a name="p1229720252303"></a><a name="p1229720252303"></a>LOS_TaskCreateOnly</p>
</td> | API | Description |
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p12297825123016"><a name="p12297825123016"></a><a name="p12297825123016"></a>Creates a task and places the task in the Init state without scheduling.</p> | ----------------- | ------------------------------ |
</td> | LOS_CurTaskPriSet | Sets a priority for the current task.|
</tr> | LOS_TaskPriSet | Sets a priority for a task. |
<tr id="row19316182517304"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p1829732511308"><a name="p1829732511308"></a><a name="p1829732511308"></a>LOS_TaskCreate</p> | LOS_TaskPriGet | Obtains the priority of a task. |
</td>
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p19297122518303"><a name="p19297122518303"></a><a name="p19297122518303"></a>Creates a task and places it in the Init state for scheduling.</p> **Table 6** APIs for setting CPU pinning
</td>
</tr> | API | Description |
<tr id="row7316192593013"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p3297162583020"><a name="p3297162583020"></a><a name="p3297162583020"></a>LOS_TaskDelete</p> | ------------------ | ------------------------------------------- |
</td> | LOS_TaskCpuAffiSet | Binds a task to the specified CPU core. This API is used only in multi-core CPUs.|
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p3297162517308"><a name="p3297162517308"></a><a name="p3297162517308"></a>Deletes the specified task.</p> | LOS_TaskCpuAffiGet | Obtains information about the core binding of a task. This API is used only in multi-core CPUs. |
</td>
</tr>
<tr id="row13316112533020"><td class="cellrowborder" rowspan="6" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p172979255306"><a name="p172979255306"></a><a name="p172979255306"></a>Task status control</p>
</td> ### How to Develop
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p14297425103016"><a name="p14297425103016"></a><a name="p14297425103016"></a>LOS_TaskResume</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p1929732593018"><a name="p1929732593018"></a><a name="p1929732593018"></a>Resumes a suspended task.</p>
</td>
</tr>
<tr id="row1231632513012"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p5297132553014"><a name="p5297132553014"></a><a name="p5297132553014"></a>LOS_TaskSuspend</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p8297182563015"><a name="p8297182563015"></a><a name="p8297182563015"></a>Suspends the specified task.</p>
</td>
</tr>
<tr id="row1547201019421"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p5885913184219"><a name="p5885913184219"></a><a name="p5885913184219"></a>LOS_TaskJoin</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p28851313104213"><a name="p28851313104213"></a><a name="p28851313104213"></a>Suspends this task till the specified task is complete and the task control block resources are reclaimed.</p>
</td>
</tr>
<tr id="row69281012114217"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p68857132427"><a name="p68857132427"></a><a name="p68857132427"></a>LOS_TaskDetach</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p188851813184219"><a name="p188851813184219"></a><a name="p188851813184219"></a>Changes the task attribute from <strong id="b1986175411125"><a name="b1986175411125"></a><a name="b1986175411125"></a>joinable</strong> to <strong id="b18996959101215"><a name="b18996959101215"></a><a name="b18996959101215"></a>detach</strong>. After the task of the <strong id="b15851429171317"><a name="b15851429171317"></a><a name="b15851429171317"></a>detach</strong> attribute is complete, the task control block resources will be automatically reclaimed.</p>
</td>
</tr>
<tr id="row1231672512301"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p92979251305"><a name="p92979251305"></a><a name="p92979251305"></a>LOS_TaskDelay</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p1297182517306"><a name="p1297182517306"></a><a name="p1297182517306"></a>Delays a task.</p>
</td>
</tr>
<tr id="row73161725163018"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p10297152573014"><a name="p10297152573014"></a><a name="p10297152573014"></a>LOS_TaskYield</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p2297325163019"><a name="p2297325163019"></a><a name="p2297325163019"></a>Adjusts the scheduling sequence of tasks that call the task priority.</p>
</td>
</tr>
<tr id="row1231520259306"><td class="cellrowborder" rowspan="2" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p9297142511307"><a name="p9297142511307"></a><a name="p9297142511307"></a>Task scheduling control</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p429719257307"><a name="p429719257307"></a><a name="p429719257307"></a>LOS_TaskLock</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p11297142510306"><a name="p11297142510306"></a><a name="p11297142510306"></a>Locks task scheduling.</p>
</td>
</tr>
<tr id="row431442573010"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p17297625193015"><a name="p17297625193015"></a><a name="p17297625193015"></a>LOS_TaskUnlock</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p829715252308"><a name="p829715252308"></a><a name="p829715252308"></a>Unlocks task scheduling.</p>
</td>
</tr>
<tr id="row53141525123010"><td class="cellrowborder" rowspan="3" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p1729732593014"><a name="p1729732593014"></a><a name="p1729732593014"></a>Task priority control</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p629715254308"><a name="p629715254308"></a><a name="p629715254308"></a>LOS_CurTaskPriSet</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p142981925183020"><a name="p142981925183020"></a><a name="p142981925183020"></a>Sets the priority for the current task.</p>
</td>
</tr>
<tr id="row18314102563015"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p11298202513303"><a name="p11298202513303"></a><a name="p11298202513303"></a>LOS_TaskPriSet</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p629822563014"><a name="p629822563014"></a><a name="p629822563014"></a>Sets the priority for a specified task.</p>
</td>
</tr>
<tr id="row731442543011"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p1029892517302"><a name="p1029892517302"></a><a name="p1029892517302"></a>LOS_TaskPriGet</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p19298182563018"><a name="p19298182563018"></a><a name="p19298182563018"></a>Obtains the priority of a specified task.</p>
</td>
</tr>
<tr id="row18314172523011"><td class="cellrowborder" rowspan="2" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p17298225203011"><a name="p17298225203011"></a><a name="p17298225203011"></a>Obtaining task information</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p229811251307"><a name="p229811251307"></a><a name="p229811251307"></a>LOS_CurTaskIDGet</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p1029842519303"><a name="p1029842519303"></a><a name="p1029842519303"></a>Obtains the ID of the current task.</p>
</td>
</tr>
<tr id="row1331452516307"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p172984256301"><a name="p172984256301"></a><a name="p172984256301"></a>LOS_TaskInfoGet</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p122988259303"><a name="p122988259303"></a><a name="p122988259303"></a>Obtains information about the specified task.</p>
</td>
</tr>
<tr id="row93146250305"><td class="cellrowborder" rowspan="2" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p82986256300"><a name="p82986256300"></a><a name="p82986256300"></a>Binding tasks to CPU cores</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p1929862583018"><a name="p1929862583018"></a><a name="p1929862583018"></a>LOS_TaskCpuAffiSet</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p82981925163013"><a name="p82981925163013"></a><a name="p82981925163013"></a>Binds a specified task to the specified CPU. It is used only in multi-core scenarios.</p>
</td>
</tr>
<tr id="row5314192543014"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p02984251305"><a name="p02984251305"></a><a name="p02984251305"></a>LOS_TaskCpuAffiGet</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p1729822513017"><a name="p1729822513017"></a><a name="p1729822513017"></a>Obtains the core binding information of the specified task. It is used only in multi-core scenarios.</p>
</td>
</tr>
<tr id="row43141525193013"><td class="cellrowborder" rowspan="2" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p16298152514308"><a name="p16298152514308"></a><a name="p16298152514308"></a>Task scheduling parameter control</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p1529872563011"><a name="p1529872563011"></a><a name="p1529872563011"></a>LOS_GetTaskScheduler</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p1298182513010"><a name="p1298182513010"></a><a name="p1298182513010"></a>Obtains the scheduling policy of the specified task.</p>
</td>
</tr>
<tr id="row1331472519305"><td class="cellrowborder" valign="top" headers="mcps1.1.4.1.1 "><p id="p15298152514301"><a name="p15298152514301"></a><a name="p15298152514301"></a>LOS_SetTaskScheduler</p>
</td>
<td class="cellrowborder" valign="top" headers="mcps1.1.4.1.2 "><p id="p11298172553015"><a name="p11298172553015"></a><a name="p11298172553015"></a>Sets the scheduling parameters, including the priority and scheduling policy, for the specified task.</p>
</td>
</tr>
<tr id="row831492514307"><td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.1 "><p id="p12981250307"><a name="p12981250307"></a><a name="p12981250307"></a>Maximum number of tasks supported</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.2 "><p id="p112981425183019"><a name="p112981425183019"></a><a name="p112981425183019"></a>LOS_GetSystemTaskMaximum</p>
</td>
<td class="cellrowborder" valign="top" width="33.33333333333333%" headers="mcps1.1.4.1.3 "><p id="p6298525123017"><a name="p6298525123017"></a><a name="p6298525123017"></a>Obtains the maximum number of tasks supported by the system.</p>
</td>
</tr>
</tbody>
</table>
### How to Develop<a name="section16229657115514"></a>
The typical task development process is as follows: The typical task development process is as follows:
1. Call **LOS\_TaskCreate** to create a task. 1. Call **LOS_TaskCreate** to create a task.
- Specify the execution entry function for the task. - Specify the execution entry function for the task.
- Specifies the task name. - Specifies the task name.
- Specify the task stack size. - Specify the task stack size.
- Specify the priority of the task. - Specify the priority of the task.
- Specify the task attribute, which can be **LOS\_TASK\_ATTR\_JOINABLE** or **LOS\_TASK\_STATUS\_DETACHED**. - Specify the task attribute, which can be **LOS_TASK_ATTR_JOINABLE** or **LOS_TASK_STATUS_DETACHED**.
- Specify the task-core binding attribute for multi-core environment. - Specify the task-core binding attribute for multi-core environment.
2. Run the service code to implement task scheduling. 2. Run the service code to implement task scheduling.
3. 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**.
>![](../public_sys-resources/icon-note.gif) **NOTE:** 3. 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**.
>- The kernel mode has the highest permission and can operate tasks in any process.
>- 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.
### Development Example<a name="section2809723165612"></a> > **NOTE**
>
> - The kernel mode has the highest permission and can operate tasks in any process.
>
> - 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.
The sample code is as follows:
``` ### Development Example
The 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
```c
UINT32 g_taskLoID; UINT32 g_taskLoID;
UINT32 g_taskHiID; UINT32 g_taskHiID;
#define TSK_PRIOR_HI 4 #define TSK_PRIOR_HI 4
#define TSK_PRIOR_LO 5 #define TSK_PRIOR_LO 5
UINT32 ExampleTaskHi(VOID) UINT32 ExampleTaskHi(VOID)
{ {
UINT32 ret; UINT32 ret;
PRINTK("Enter TaskHi Handler.\n"); PRINTK("Enter TaskHi Handler.\n");
/* Delay the task for 2 ticks. The task is then suspended, and the remaining task with the highest priority (g_taskLoID) will be executed.*/ /* Delay the task for 2 ticks. The task is suspended, and the remaining task with the highest priority (g_taskLoID) will be executed. */
ret = LOS_TaskDelay(2); ret = LOS_TaskDelay(2);
if (ret != LOS_OK) { if (ret != LOS_OK) {
PRINTK("Delay Task Failed.\n"); PRINTK("Delay Task Failed.\n");
return LOS_NOK; return LOS_NOK;
} }
/* After 2 ticks elapse, the task is resumed and executed.*/ /* After 2 ticks elapse, the task is resumed and executed. */
PRINTK("TaskHi LOS_TaskDelay Done.\n"); PRINTK("TaskHi LOS_TaskDelay Done.\n");
/* Suspend the task.*/ /* Suspend the task. */
ret = LOS_TaskSuspend(g_taskHiID); ret = LOS_TaskSuspend(g_taskHiID);
if (ret != LOS_OK) { if (ret != LOS_OK) {
PRINTK("Suspend TaskHi Failed.\n"); PRINTK("Suspend TaskHi Failed.\n");
return LOS_NOK; return LOS_NOK;
} }
PRINTK("TaskHi LOS_TaskResume Success.\n"); PRINTK("TaskHi LOS_TaskResume Success.\n");
return LOS_OK; return LOS_OK;
} }
/* Entry function of the lower-priority task */ /* Entry function of the low-priority task. */
UINT32 ExampleTaskLo(VOID) UINT32 ExampleTaskLo(VOID)
{ {
UINT32 ret; UINT32 ret;
PRINTK("Enter TaskLo Handler.\n"); PRINTK("Enter TaskLo Handler.\n");
/* Delay the task for 2 ticks. The task is then suspended, and the remaining task with the highest priority (background task) will be executed.*/ /* Delay the task for 2 ticks. The task is suspended, and the remaining task with the highest priority (background task) will be executed. */
ret = LOS_TaskDelay(2); ret = LOS_TaskDelay(2);
if (ret != LOS_OK) { if (ret != LOS_OK) {
PRINTK("Delay TaskLo Failed.\n"); PRINTK("Delay TaskLo Failed.\n");
return LOS_NOK; return LOS_NOK;
} }
PRINTK("TaskHi LOS_TaskSuspend Success.\n"); PRINTK("TaskHi LOS_TaskSuspend Success.\n");
/* Resume the suspended task g_taskHiID.*/ /* Resume the suspended task g_taskHiID. */
ret = LOS_TaskResume(g_taskHiID); ret = LOS_TaskResume(g_taskHiID);
if (ret != LOS_OK) { if (ret != LOS_OK) {
PRINTK("Resume TaskHi Failed.\n"); PRINTK("Resume TaskHi Failed.\n");
return LOS_NOK; return LOS_NOK;
} }
PRINTK("TaskHi LOS_TaskDelete Success.\n"); PRINTK("TaskHi LOS_TaskDelete Success.\n");
return LOS_OK; return LOS_OK;
} }
/* Task test entry function, which is used to create two tasks with different priorities.*/ /* Create two tasks with different priorities in the task test entry function. */
UINT32 ExampleTaskCaseEntry(VOID) UINT32 ExampleTaskCaseEntry(VOID)
{ {
UINT32 ret; UINT32 ret;
TSK_INIT_PARAM_S initParam = {0}; TSK_INIT_PARAM_S initParam = {0};
/* Lock task scheduling.*/ /* Lock task scheduling. */
LOS_TaskLock(); LOS_TaskLock();
PRINTK("LOS_TaskLock() Success!\n"); PRINTK("LOS_TaskLock() Success!\n");
/* Parameters used to initialize the high-priority task, the resources of which can be reclaimed by LOS_TaskJoin. */
initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleTaskHi; initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleTaskHi;
initParam.usTaskPrio = TSK_PRIOR_HI; initParam.usTaskPrio = TSK_PRIOR_HI;
initParam.pcName = "HIGH_NAME"; initParam.pcName = "HIGH_NAME";
initParam.uwStackSize = LOS_TASK_MIN_STACK_SIZE; initParam.uwStackSize = LOS_TASK_MIN_STACK_SIZE;
initParam.uwResved = LOS_TASK_ATTR_JOINABLE; initParam.uwResved = LOS_TASK_ATTR_JOINABLE;
/* Create a task with a higher priority. The task will not be executed immediately after being created, because task scheduling is locked.*/ /* Create a task with higher priority. The task will not be executed immediately after being created, because task scheduling is locked. */
ret = LOS_TaskCreate(&g_taskHiID, &initParam); ret = LOS_TaskCreate(&g_taskHiID, &initParam);
if (ret != LOS_OK) { if (ret != LOS_OK) {
LOS_TaskUnlock(); LOS_TaskUnlock();
PRINTK("ExampleTaskHi create Failed! ret=%d\n", ret); PRINTK("ExampleTaskHi create Failed! ret=%d\n", ret);
return LOS_NOK; return LOS_NOK;
} }
PRINTK("ExampleTaskHi create Success!\n"); PRINTK("ExampleTaskHi create Success!\n");
/* Parameters used to initialize the low-priority task, which will be automatically destroyed after the task is complete. */
initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleTaskLo; initParam.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleTaskLo;
initParam.usTaskPrio = TSK_PRIOR_LO; initParam.usTaskPrio = TSK_PRIOR_LO;
initParam.pcName = "LOW_NAME"; initParam.pcName = "LOW_NAME";
initParam.uwStackSize = LOS_TASK_MIN_STACK_SIZE; initParam.uwStackSize = LOS_TASK_MIN_STACK_SIZE;
initParam.uwResved = LOS_TASK_STATUS_DETACHED; initParam.uwResved = LOS_TASK_STATUS_DETACHED;
/* Create a task with a lower priority. The task will not be executed immediately after being created, because task scheduling is locked.*/ /* Create a low-priority task. The task will not be executed immediately after being created, because task scheduling is locked. */
ret = LOS_TaskCreate(&g_taskLoID, &initParam); ret = LOS_TaskCreate(&g_taskLoID, &initParam);
if (ret!= LOS_OK) { if (ret!= LOS_OK) {
LOS_TaskUnlock(); LOS_TaskUnlock();
PRINTK("ExampleTaskLo create Failed!\n"); PRINTK("ExampleTaskLo create Failed!\n");
return LOS_NOK; return LOS_NOK;
} }
PRINTK("ExampleTaskLo create Success!\n"); PRINTK("ExampleTaskLo create Success!\n");
/* Unlock task scheduling. The task with the highest priority in the Ready queue will be executed.*/ /* Unlock task scheduling. The task with the highest priority in the Ready queue will be executed. */
LOS_TaskUnlock(); LOS_TaskUnlock();
ret = LOS_TaskJoin(g_taskHiID, NULL); ret = LOS_TaskJoin(g_taskHiID, NULL);
if (ret != LOS_OK) { if (ret != LOS_OK) {
...@@ -319,11 +248,12 @@ UINT32 ExampleTaskCaseEntry(VOID) ...@@ -319,11 +248,12 @@ UINT32 ExampleTaskCaseEntry(VOID)
} }
while(1){}; while(1){};
return LOS_OK; return LOS_OK;
} }
``` ```
The development is successful if the return result is as follows: The development is successful if the return result is as follows:
``` ```
LOS_TaskLock() Success! LOS_TaskLock() Success!
ExampleTaskHi create Success! ExampleTaskHi create Success!
...@@ -336,4 +266,3 @@ TaskHi LOS_TaskResume Success. ...@@ -336,4 +266,3 @@ TaskHi LOS_TaskResume Success.
TaskHi LOS_TaskDelete Success. TaskHi LOS_TaskDelete Success.
Join ExampleTaskHi Success! Join ExampleTaskHi Success!
``` ```
...@@ -3,20 +3,22 @@ ...@@ -3,20 +3,22 @@
## Kernel Startup Process ## Kernel Startup Process
The kernel startup process consists of the assembly startup and C language startup, as shown in the following figure. The kernel startup process consists of the assembly startup and C language startup, as shown in **Figure 1**.
The assembly startup involves the following operations: initializing CPU settings, disabling dCache/iCache, enabling the FPU and NEON, setting the MMU to establish the virtual-physical address mapping, setting the system stack, clearing the BSS segment, and calling the main function of the C language. The assembly startup involves the following operations: initializing CPU settings, disabling dCache/iCache, enabling the FPU and NEON, setting the MMU to establish the virtual-physical address mapping, setting the system stack, clearing the BSS segment, and calling the main function of the C language.
The C language startup involves the following operations: starting the **OsMain** function and starting scheduling. As shown in the following figure, the **OsMain** function is used for basic kernel initialization and architecture- and board-level initialization. The kernel startup framework leads the initialization process. The right part of the figure shows the phase in which external modules can register with the kernel startup framework and starts. The table below describes each phase. The C language startup involves the following operations: starting the **OsMain** function and starting scheduling.
**OsMain()** is used for basic kernel initialization and architecture- and board-level initialization. The kernel startup framework leads the initialization process. The right part of the figure shows the phase in which external modules can register with the kernel startup framework and starts. **Table 1** describes each phase.
**Figure 1** Kernel startup process<br> **Figure 1** Kernel startup process
![](figures/kernel-startup-process-2.png "kernel-startup-process-2")
![](figures/kernel-startup-process-2.png "kernel-startup-process-2")
**Table 1** Start framework
| Level | Startup Description | **Table 1** Kernel startup framework
| API| Description|
| -------- | -------- | | -------- | -------- |
| LOS_INIT_LEVEL_EARLIEST | Earliest initialization.<br>The initialization is architecture-independent. The board and subsequent modules initialize the pure software modules on which they depend.<br>Example: trace module| | LOS_INIT_LEVEL_EARLIEST | Earliest initialization.<br>The initialization is architecture-independent. The board and subsequent modules initialize the pure software modules on which they depend.<br>Example: trace module|
| LOS_INIT_LEVEL_ARCH_EARLY | Early initialization of the architecture.<br>The initialization is architecture-dependent. Subsequent modules initialize the modules on which they depend. It is recommended that functions not required for startup be placed at **LOS_INIT_LEVEL_ARCH**.| | LOS_INIT_LEVEL_ARCH_EARLY | Early initialization of the architecture.<br>The initialization is architecture-dependent. Subsequent modules initialize the modules on which they depend. It is recommended that functions not required for startup be placed at **LOS_INIT_LEVEL_ARCH**.|
...@@ -28,54 +30,52 @@ The C language startup involves the following operations: starting the **OsMain* ...@@ -28,54 +30,52 @@ The C language startup involves the following operations: starting the **OsMain*
| LOS_INIT_LEVEL_KMOD_BASIC | Initialization of the kernel basic modules.<br>Initialize the basic modules that can be detached from the kernel.<br>Example: VFS initialization| | LOS_INIT_LEVEL_KMOD_BASIC | Initialization of the kernel basic modules.<br>Initialize the basic modules that can be detached from the kernel.<br>Example: VFS initialization|
| LOS_INIT_LEVEL_KMOD_EXTENDED | Initialization of the kernel extended modules.<br>Initialize the extended modules that can be detached from the kernel.<br>Example: initialization of system call, ProcFS, Futex, HiLog, HiEvent, and LiteIPC| | LOS_INIT_LEVEL_KMOD_EXTENDED | Initialization of the kernel extended modules.<br>Initialize the extended modules that can be detached from the kernel.<br>Example: initialization of system call, ProcFS, Futex, HiLog, HiEvent, and LiteIPC|
| LOS_INIT_LEVEL_KMOD_TASK | Kernel task creation.<br>Create kernel tasks (kernel tasks and software timer tasks).<br>Example: creation of the resident resource reclaiming task, SystemInit task, and CPU usage statistics task| | LOS_INIT_LEVEL_KMOD_TASK | Kernel task creation.<br>Create kernel tasks (kernel tasks and software timer tasks).<br>Example: creation of the resident resource reclaiming task, SystemInit task, and CPU usage statistics task|
| LOS_INIT_LEVEL_FINISH | Complete of the kernel initialization.|
## Programming Example ## Development Example
**Example Description** **Example Description**
Add a kernel module and register the initialization function of the module to the kernel startup process through the kernel startup framework, so as to complete the module initialization during the kernel initialization process. Add a kernel module and register the initialization function of the module to the kernel startup process through the kernel startup framework, so as to complete the module initialization during the kernel initialization process.
You can compile and verify the sample code in **kernel/liteos_a/testsuites/kernel/src/osTest.c**.
**Sample Code** **Sample Code**
```c
```
/* Header file of the kernel startup framework */ /* Header file of the kernel startup framework */
#include "los_init.h" #include "los_init.h"
...
/* Initialization function of the new module */ /* Initialization function of the new module */
unsigned int OsSampleModInit(void) unsigned int OsSampleModInit(void)
{ {
PRINTK("OsSampleModInit SUCCESS!\n"); PRINTK("OsSampleModInit SUCCESS!\n");
......
} }
...
/* Register the new module at the target level of the kernel startup framework. */ /* Register the new module at the target level of the kernel startup framework. */
LOS_MODULE_INIT(OsSampleModInit, LOS_INIT_LEVEL_KMOD_EXTENDED); LOS_MODULE_INIT(OsSampleModInit, LOS_INIT_LEVEL_KMOD_EXTENDED);
``` ```
**Verification** **Verification**
``` ```
main core booting up... main core booting up...
/* The print information may vary depending on the running environment. */
...
/* Print the initialization function of the new module in the test code. */
OsSampleModInit SUCCESS! OsSampleModInit SUCCESS!
releasing 1 secondary cores
cpu 1 entering scheduler
cpu 0 entering scheduler
``` ```
According to the information displayed during the system startup, the kernel has called the initialization function of the registered module during the startup to initialize the module. According to the information displayed during the system startup, the kernel calls the initialization function of the registered module during the startup to initialize the module.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE** > **NOTE**
> >
> Modules at the same level cannot depend on each other. It is recommended that a new module be split based on the preceding startup phase and be registered and started as required. > Modules of the same level cannot depend on each other. It is recommended that a new module be split based on the preceding startup phase and be registered and started as required.
> >
> You can view the symbol table in the **.rodata.init.kernel.*** segment of the **OHOS_Image.map** file generated after the build is complete, so as to learn about the initialization entry of each module that has been registered with the kernel startup framework and check whether the newly registered initialization entry has taken effect. > You can view the symbol table in the **.rodata.init.kernel.*** segment of the **OHOS_Image.map** file generated after the build is complete, so as to learn about the initialization entry of each module that has been registered with the kernel startup framework and check whether the newly registered initialization entry has taken effect.
# Startup in User Mode # Startup in User Mode
## Startup of the Root Process in User Mode<a name="section79911135647"></a>
## Startup of the Root Process in User Mode
The root process is the first user-mode process in the system. The process ID is 1. The root process is the ancestor of all user-mode processes. The root process is the first user-mode process in the system. The process ID is 1. The root process is the ancestor of all user-mode processes.
**Figure 1** Process tree<a name="fig427516409375"></a> **Figure 1** Process tree
![](figures/process-tree.png "process-tree") ![](figures/process-tree.png "process-tree")
### Startup Process of the Root Process<a name="section1184317581349"></a>
### Startup Process of the Root Process
Use the link script to place the following init startup code to the specified location in the system image. Use the link script to place the following init startup code to the specified location in the system image.
```
```c
#define LITE_USER_SEC_ENTRY __attribute__((section(".user.entry"))) #define LITE_USER_SEC_ENTRY __attribute__((section(".user.entry")))
LITE_USER_SEC_ENTRY VOID OsUserInit(VOID *args) LITE_USER_SEC_ENTRY VOID OsUserInit(VOID *args)
{ {
...@@ -23,38 +27,38 @@ LITE_USER_SEC_ENTRY VOID OsUserInit(VOID *args) ...@@ -23,38 +27,38 @@ LITE_USER_SEC_ENTRY VOID OsUserInit(VOID *args)
} }
``` ```
During system startup, **OsUserInitProcess** is called to start the **init** process. The procedure is as follows: > **NOTE**
>
> The preceeding code is in **kernel/liteos_a/kernel/user/src/los_user_init.c**. The value of **g_initPath** can be **/dev/shm/init** or **/bin/init**, depending on the startup settings.
1. The kernel calls **OsLoadUserInit** to load the code. Use **OsUserInitProcess** to start the **init** process. The procedure is as follows:
2. A process space is created to start the **/bin/init** process.
### Responsibilities of the Root Process<a name="section1590220321759"></a> 1. The kernel calls **OsLoadUserInit** to load the code for startup.
- Starts key system programs or services, such as shell. 2. A process space is created to start the **/bin/init** process.
>![](../public_sys-resources/icon-note.gif) **NOTE**
>
>In OpenHarmony, the **init** process reads the **/etc/init.cfg** file and runs specified commands or starts specified processes based on configurations. For details, see [init Module](../subsystems/subsys-boot-init-cfg.md).
### Responsibilities of the Root Process
- Monitors the process for reclaiming the orphan process and clears the zombie processes in child processes. - The root process starts key system programs or services, such as shell.
> **NOTE**
> In OpenHarmony, the **init** process reads **/etc/init.cfg** and runs commands or starts processes based on the configuration. For details, see [init Configuration File](../subsystems/subsys-boot-init-cfg.md).
## Running Programs in User Mode<a name="section194576310611"></a> - The root process monitors the process for reclaiming the orphan process and clears the zombie processes in child processes.
A user-mode program can be started in either of the following ways: ## Running Programs in User Mode
- Run the shell command to start the process.
```
OHOS $ exec helloworld
OHOS $ ./helloworld
OHOS $ /bin/helloworld
```
A user-mode program can be started in either of the following ways:
- Start a new process by calling the POSIX API. - Using shell commands
Use the **Fork\(\)** method to create a process, and call the **exec\(\)** method to execute a new process. ```
OHOS $ exec helloworld
OHOS $ ./helloworld
OHOS $ /bin/helloworld
```
- Using POSIX APIs
Use **Fork()** to create a process, and call **exec()** to execute a process.
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册