“3b405f129707b7b58f02482979b4121802ff798a”上不存在“NO56/csdn/middlewares.py”
未验证 提交 48022866 编写于 作者: O openharmony_ci 提交者: Gitee

!23068 翻译完成 21506+22205+22030:修改hb安装的错误描述+修改显示格式问题+修改framwork路径

Merge pull request !23068 from ester.zhou/TR-21506
# Device Driver Porting<a name="EN-US_TOPIC_0000001200252097"></a>
# Device Driver Porting
This section describes how to port device drivers.
## LCD Driver Porting<a name="section1574513454119"></a>
## LCD Driver Porting
To port an LCD driver, write the driver, create an instance of the corresponding model in the driver, and complete the registration.
The LCD drivers are stored in **//drivers/framework/model/display/driver/panel**.
The LCD drivers are stored in **//drivers/hdf_core/framework/model/display/driver/panel**.
1. Create a panel driver.
Create an HDF driver and call the **RegisterPanel** method to register a model instance during driver initialization.
```
int32_t LCDxxEntryInit(struct HdfDeviceObject *object)
{
struct PanelData *panel = CreateYourPanel();
// Register a model instance.
if (RegisterPanel(panel) != HDF_SUCCESS) {
HDF_LOGE("%s: RegisterPanel failed", __func__);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
struct HdfDriverEntry g_xxxxDevEntry = {
.moduleVersion = 1,
.moduleName = "LCD_XXXX",
.Init = LCDxxEntryInit,
};
HDF_INIT(g_xxxxDevEntry);
```
Create an HDF driver and call the **RegisterPanel** method to register a model instance during driver initialization.
```
int32_t LCDxxEntryInit(struct HdfDeviceObject *object)
{
struct PanelData *panel = CreateYourPanel();
// Register a model instance.
if (RegisterPanel(panel) != HDF_SUCCESS) {
HDF_LOGE("%s: RegisterPanel failed", __func__);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
struct HdfDriverEntry g_xxxxDevEntry = {
.moduleVersion = 1,
.moduleName = "LCD_XXXX",
.Init = LCDxxEntryInit,
};
HDF_INIT(g_xxxxDevEntry);
```
2. Configure and load the panel driver.
Modify the source code file **//vendor/vendor\_name/product\_name/config/device\_info/device\_info.hcs**. Add configurations for the device named **device\_lcd** for the display host.
Modify the source code file **//vendor/vendor_name/product_name/config/device_info/device_info.hcs**. Add configurations for the device named **device\_lcd** for the display host.
>![](../public_sys-resources/icon-caution.gif) **CAUTION:**
>Make sure the value of **moduleName** is the same as that of **moduleName** in the panel driver.
> ![icon-caution.gif](public_sys-resources/icon-caution.gif) **CAUTION**
> Make sure the value of **moduleName** is the same as that of **moduleName** in the panel driver.
```
root {
...
display :: host {
device_lcd :: device {
deviceN :: deviceNode {
policy = 0;
priority = 100;
preload = 2;
moduleName = "LCD_XXXX";
}
}
}
}
```
```
root {
...
display :: host {
device_lcd :: device {
deviceN :: deviceNode {
policy = 0;
priority = 100;
preload = 2;
moduleName = "LCD_XXXX";
}
}
}
}
```
## Touchscreen Driver Porting<a name="section20284142116422"></a>
## Touchscreen Driver Porting
This section describes how to port a touchscreen driver. The touchscreen drivers are stored in the source code directory **//drivers/framework/model/input/driver/touchscreen**. To port a touchscreen driver, register a **ChipDevice** model instance with the system.
This section describes how to port a touchscreen driver. The touchscreen drivers are stored in the source code directory **//drivers/hdf_core/framework/model/input/driver/touchscreen**. To port a touchscreen driver, register a **ChipDevice** model instance with the system.
For details about how to develop a touchscreen driver, see [Touchscreen Development Guidelines](../driver/driver-peripherals-touch-des.md).
1. Create a touchscreen driver.
Create the **touch\_ic\_name.c** file in the **touchscreen** directory. Write the following content:
```
#include "hdf_touch.h"
static int32_t HdfXXXXChipInit(struct HdfDeviceObject *device)
{
ChipDevice *tpImpl = CreateXXXXTpImpl();
if(RegisterChipDevice(tpImpl) != HDF_SUCCESS) {// Register the ChipDevice model instance.
ReleaseXXXXTpImpl(tpImpl);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
struct HdfDriverEntry g_touchXXXXChipEntry = {
.moduleVersion = 1,
.moduleName = "HDF_TOUCH_XXXX", // Make sure the value is the same as that in the subsequent configuration.
.Init = HdfXXXXChipInit,
};
Create the **touch\_ic\_name.c** file in the **touchscreen** directory. Write the following content:
```
#include "hdf_touch.h"
static int32_t HdfXXXXChipInit(struct HdfDeviceObject *device)
{
ChipDevice *tpImpl = CreateXXXXTpImpl();
if(RegisterChipDevice(tpImpl) != HDF_SUCCESS) { // Register the ChipDevice model instance.
ReleaseXXXXTpImpl(tpImpl);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
struct HdfDriverEntry g_touchXXXXChipEntry = {
.moduleVersion = 1,
.moduleName = "HDF_TOUCH_XXXX", // Make sure the value is the same as that in the subsequent configuration.
.Init = HdfXXXXChipInit,
};
HDF_INIT(g_touchXXXXChipEntry);
```
The following methods need to be implemented in **ChipDevice**:
HDF_INIT(g_touchXXXXChipEntry);
```
The following methods need to be implemented in **ChipDevice**:
<a name="table63781245516"></a>
<table><thead align="left"><tr id="row1639713218557"><th class="cellrowborder" valign="top" width="50%" id="mcps1.1.3.1.1"><p id="p53981829557"><a name="p53981829557"></a><a name="p53981829557"></a>Method</p>
</th>
<th class="cellrowborder" valign="top" width="50%" id="mcps1.1.3.1.2"><p id="p739811218557"><a name="p739811218557"></a><a name="p739811218557"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row113981214559"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="p339813214552"><a name="p339813214552"></a><a name="p339813214552"></a>int32_t (*Init)(ChipDevice *device)</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="p1139810214552"><a name="p1139810214552"></a><a name="p1139810214552"></a>Initializes the device.</p>
</td>
</tr>
<tr id="row15398122145511"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="p1139820212557"><a name="p1139820212557"></a><a name="p1139820212557"></a>int32_t (*Detect)(ChipDevice *device)</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="p939820217555"><a name="p939820217555"></a><a name="p939820217555"></a>Detects the device.</p>
</td>
</tr>
<tr id="row183981216550"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="p8398142165517"><a name="p8398142165517"></a><a name="p8398142165517"></a>int32_t (*Suspend)(ChipDevice *device)</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="p539815218558"><a name="p539815218558"></a><a name="p539815218558"></a>Places the device in sleep mode.</p>
</td>
</tr>
<tr id="row1239842115519"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="p43981295511"><a name="p43981295511"></a><a name="p43981295511"></a>int32_t (*Resume)(ChipDevice *device)</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="p173985245515"><a name="p173985245515"></a><a name="p173985245515"></a>Wakes up the device.</p>
</td>
</tr>
<tr id="row5398326559"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="p103981324554"><a name="p103981324554"></a><a name="p103981324554"></a>int32_t (*DataHandle)(ChipDevice *device)</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="p93980212554"><a name="p93980212554"></a><a name="p93980212554"></a>Reads data from the device and writes touch point data to <strong id="b576475914217"><a name="b576475914217"></a><a name="b576475914217"></a>device</strong> &gt; <strong id="b976511597218"><a name="b976511597218"></a><a name="b976511597218"></a>driver</strong> &gt; <strong id="b117661559162110"><a name="b117661559162110"></a><a name="b117661559162110"></a>frameData</strong>.</p>
</td>
</tr>
<tr id="row03987215550"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="p1039814295515"><a name="p1039814295515"></a><a name="p1039814295515"></a>int32_t (*UpdateFirmware)(ChipDevice *device)</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="p18398102105520"><a name="p18398102105520"></a><a name="p18398102105520"></a>Updates the firmware.</p>
</td>
</tr>
</tbody>
</table>
| Method | Description |
| -------- | -------- |
| int32_t&nbsp;(\*Init)(ChipDevice&nbsp;\*device) | Initializes the device. |
| int32_t&nbsp;(\*Detect)(ChipDevice&nbsp;\*device) | Detects the device. |
| int32_t&nbsp;(\*Suspend)(ChipDevice&nbsp;\*device) | Places the device in sleep mode. |
| int32_t&nbsp;(\*Resume)(ChipDevice&nbsp;\*device) | Wakes up the device. |
| int32_t&nbsp;(\*DataHandle)(ChipDevice&nbsp;\*device) | Reads data from the device and writes touch point data to device > driver > frameData. |
| int32_t&nbsp;(\*UpdateFirmware)(ChipDevice&nbsp;\*device) | Updates the firmware. |
2. Configure the product and load the driver.
All device information of the product is defined in the source code file **//vendor/vendor\_name/product\_name/config/device\_info/device\_info.hcs**. Modify the file and add configurations to the **device** named **device\_touch\_chip** in the **host** of the **input** command.
All device information of the product is defined in the source code file **//vendor/vendor_name/product_name/config/device_info/device_info.hcs**. Modify the file and add configurations to the **device** named **device\_touch\_chip** in the **host** of the **input** command.
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>Make sure the value of **moduleName** is the same as that of **moduleName** in the touchscreen driver.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**
>
> Make sure the value of **moduleName** is the same as that of **moduleName** in the touchscreen driver.
```
deviceN :: deviceNode {
policy = 0;
priority = 130;
preload = 0;
permission = 0660;
moduleName = "HDF_TOUCH_XXXX";
deviceMatchAttr = "touch_XXXX_configs";
}
```
```
deviceN :: deviceNode {
policy = 0;
priority = 130;
preload = 0;
permission = 0660;
moduleName = "HDF_TOUCH_XXXX";
deviceMatchAttr = "touch_XXXX_configs";
}
```
## WLAN Driver Porting<a name="section0969448164217"></a>
## WLAN Driver Porting
The WLAN driver is divided into two parts. One of the parts manages WLAN devices, and the other part manages WLAN traffic.
**Figure 1** OpenHarmony WLAN driver architecture<a name="fig155920160203"></a>
![](figures/hdf_wifi.png)
As shown in [Figure 1](#fig155920160203), the part on the left manages WLAN devices, and the part on the right manages WLAN traffic. The HDF WLAN framework abstracts these two parts. The porting process of the driver can be considered as the implementation of the APIs required by the two parts. These APIs are described as follows:
<a name="table1349145511213"></a>
<table><thead align="left"><tr id="row867115517211"><th class="cellrowborder" valign="top" width="17.28172817281728%" id="mcps1.1.4.1.1"><p id="p667255120"><a name="p667255120"></a><a name="p667255120"></a>API</p>
</th>
<th class="cellrowborder" valign="top" width="39.48394839483948%" id="mcps1.1.4.1.2"><p id="p9672551125"><a name="p9672551125"></a><a name="p9672551125"></a>Header File</p>
</th>
<th class="cellrowborder" valign="top" width="43.23432343234324%" id="mcps1.1.4.1.3"><p id="p166785515214"><a name="p166785515214"></a><a name="p166785515214"></a>API Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row16671955128"><td class="cellrowborder" valign="top" width="17.28172817281728%" headers="mcps1.1.4.1.1 "><p id="p86712551023"><a name="p86712551023"></a><a name="p86712551023"></a>HdfChipDriverFactory</p>
</td>
<td class="cellrowborder" valign="top" width="39.48394839483948%" headers="mcps1.1.4.1.2 "><p id="p10671551126"><a name="p10671551126"></a><a name="p10671551126"></a>drivers\framework\include\wifi\hdf_wlan_chipdriver_manager.h</p>
</td>
<td class="cellrowborder" valign="top" width="43.23432343234324%" headers="mcps1.1.4.1.3 "><p id="p26725514220"><a name="p26725514220"></a><a name="p26725514220"></a>Factory of the <strong id="b88841282246"><a name="b88841282246"></a><a name="b88841282246"></a>ChipDriver</strong>, which is used to support multiple WLAN interfaces of a chip.</p>
</td>
</tr>
<tr id="row186810552214"><td class="cellrowborder" valign="top" width="17.28172817281728%" headers="mcps1.1.4.1.1 "><p id="p11686551323"><a name="p11686551323"></a><a name="p11686551323"></a>HdfChipDriver</p>
</td>
<td class="cellrowborder" valign="top" width="39.48394839483948%" headers="mcps1.1.4.1.2 "><p id="p11686551723"><a name="p11686551723"></a><a name="p11686551723"></a>drivers\framework\include\wifi\wifi_module.h</p>
</td>
<td class="cellrowborder" valign="top" width="43.23432343234324%" headers="mcps1.1.4.1.3 "><p id="p26814555217"><a name="p26814555217"></a><a name="p26814555217"></a>Manages a specific WLAN interface.</p>
</td>
</tr>
<tr id="row13686559215"><td class="cellrowborder" valign="top" width="17.28172817281728%" headers="mcps1.1.4.1.1 "><p id="p76810555214"><a name="p76810555214"></a><a name="p76810555214"></a>NetDeviceInterFace</p>
</td>
<td class="cellrowborder" valign="top" width="39.48394839483948%" headers="mcps1.1.4.1.2 "><p id="p166818551825"><a name="p166818551825"></a><a name="p166818551825"></a>drivers\framework\include\wifi\net_device.h</p>
</td>
<td class="cellrowborder" valign="top" width="43.23432343234324%" headers="mcps1.1.4.1.3 "><p id="p368195513213"><a name="p368195513213"></a><a name="p368195513213"></a>Communicates with the protocol stack, such as sending data and setting the status of network interfaces.</p>
</td>
</tr>
</tbody>
</table>
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>For details about the API development, see [WLAN Development Guidelines](../driver/driver-peripherals-external-des.md).
**Figure 1** OpenHarmony WLAN driver architecture<a name="fig155920160203"></a>
![hdf_wifi](figures/hdf_wifi.png)
As shown in Figure 1, the part on the left manages WLAN devices, and the part on the right manages WLAN traffic. The HDF WLAN framework abstracts these two parts. The porting process of the driver can be considered as the implementation of the APIs required by the two parts. These APIs are described as follows:
| API | Header File | Description |
| -------- | -------- | -------- |
| HdfChipDriverFactory | drivers\hdf_core\framework\include\wifi\hdf_wlan_chipdriver_manager.h | Factory of the ChipDriver, which is used to support multiple WLAN interfaces of a chip. |
| HdfChipDriver | drivers\hdf_core\framework\include\wifi\wifi_module.h | Manages a specific WLAN interface. |
| NetDeviceInterFace | drivers\hdf_core\framework\include\wifi\net_device.h | Communicates with the protocol stack, such as sending data and setting the status of network interfaces. |
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**
>
> For details about the API development, see [WLAN Development Guidelines](../driver/driver-peripherals-external-des.md).
The porting procedure is as follows:
1. Create a WLAN chip driver.
Create the **hdf\_wlan\_chip\_name.c** file in **/device/vendor\_name/peripheral/wifi/chip\_name/**. The sample code is as follows:
```
static int32_t HdfWlanHisiChipDriverInit(struct HdfDeviceObject *device) {
static struct HdfChipDriverFactory factory = CreateChipDriverFactory(); // Implement the method.
struct HdfChipDriverManager *driverMgr = HdfWlanGetChipDriverMgr();
if (driverMgr->RegChipDriver(&factory) != HDF_SUCCESS) {// Register the driver factory.
HDF_LOGE("%s fail: driverMgr is NULL!", __func__);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
struct HdfDriverEntry g_hdfXXXChipEntry = {
.moduleVersion = 1,
.Init = HdfWlanXXXChipDriverInit,
.Release = HdfWlanXXXChipRelease,
.moduleName = "HDF_WIFI_CHIP_XXX" // Make sure the name is the same as the configured one.
};
Create the **hdf_wlan_chip_name.c** file in **/device/vendor_name/peripheral/wifi/chip_name/**. The sample code is as follows:
```
static int32_t HdfWlanXXXChipDriverInit(struct HdfDeviceObject *device) {
static struct HdfChipDriverFactory factory = CreateChipDriverFactory(); // Implement the method.
struct HdfChipDriverManager *driverMgr = HdfWlanGetChipDriverMgr();
if (driverMgr->RegChipDriver(&factory) != HDF_SUCCESS) { // Register the driver factory.
HDF_LOGE("%s fail: driverMgr is NULL!", __func__);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
struct HdfDriverEntry g_hdfXXXChipEntry = {
.moduleVersion = 1,
.Init = HdfWlanXXXChipDriverInit,
.Release = HdfWlanXXXChipRelease,
.moduleName = "HDF_WIFI_CHIP_XXX" // Make sure the name is the same as the configured one.
};
HDF_INIT(g_hdfXXXChipEntry);
```
In the **CreateChipDriverFactory** method, create an object of the **HdfChipDriverFactory** type. This object provides the following methods:
HDF_INIT(g_hdfXXXChipEntry);
```
In the **CreateChipDriverFactory** method, create an object of the **HdfChipDriverFactory** type. This object provides the following methods:
<a name="table8351533595"></a>
<table><thead align="left"><tr id="row25693318916"><th class="cellrowborder" valign="top" width="50%" id="mcps1.1.3.1.1"><p id="p125683311913"><a name="p125683311913"></a><a name="p125683311913"></a>Method</p>
</th>
<th class="cellrowborder" valign="top" width="50%" id="mcps1.1.3.1.2"><p id="p1656103318919"><a name="p1656103318919"></a><a name="p1656103318919"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row15612331994"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="p185663314920"><a name="p185663314920"></a><a name="p185663314920"></a>const char *driverName</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="p7563330917"><a name="p7563330917"></a><a name="p7563330917"></a>Indicates the driver name.</p>
</td>
</tr>
<tr id="row20561733993"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="p13561331297"><a name="p13561331297"></a><a name="p13561331297"></a>int32_t (*InitChip)(struct HdfWlanDevice *device)</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="p756163312914"><a name="p756163312914"></a><a name="p756163312914"></a>Initializes the chip.</p>
</td>
</tr>
<tr id="row155612337919"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="p135633315917"><a name="p135633315917"></a><a name="p135633315917"></a>int32_t (*DeinitChip)(struct HdfWlanDevice *device)</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="p3566331094"><a name="p3566331094"></a><a name="p3566331094"></a>Deinitializes the chip.</p>
</td>
</tr>
<tr id="row18567337916"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="p157203315917"><a name="p157203315917"></a><a name="p157203315917"></a>void (*ReleaseFactory)(struct HdfChipDriverFactory *factory)</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="p165716331596"><a name="p165716331596"></a><a name="p165716331596"></a>Releases the <strong id="b17274134462416"><a name="b17274134462416"></a><a name="b17274134462416"></a>HdfChipDriverFactory</strong> object.</p>
</td>
</tr>
<tr id="row1757143314912"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="p105710331694"><a name="p105710331694"></a><a name="p105710331694"></a>struct HdfChipDriver *(*Build)(struct HdfWlanDevice *device, uint8_t ifIndex)</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="p457143320911"><a name="p457143320911"></a><a name="p457143320911"></a>Creates an <strong id="b118260459243"><a name="b118260459243"></a><a name="b118260459243"></a>HdfChipDriver</strong>. In the input parameters, <strong id="b28271845162411"><a name="b28271845162411"></a><a name="b28271845162411"></a>device</strong> indicates the device information, and <strong id="b16827144519241"><a name="b16827144519241"></a><a name="b16827144519241"></a>ifIndex</strong> indicates the sequence number of this interface in the chip.</p>
</td>
</tr>
<tr id="row1157153310912"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="p155714334917"><a name="p155714334917"></a><a name="p155714334917"></a>void (*Release)(struct HdfChipDriver *chipDriver)</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="p95717338919"><a name="p95717338919"></a><a name="p95717338919"></a>Releases the chip driver.</p>
</td>
</tr>
<tr id="row1157143313914"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="p19571433993"><a name="p19571433993"></a><a name="p19571433993"></a>uint8_t (*GetMaxIFCount)(struct HdfChipDriverFactory *factory)</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="p14571334915"><a name="p14571334915"></a><a name="p14571334915"></a>Obtains the maximum number of interfaces supported by the current chip.</p>
</td>
</tr>
</tbody>
</table>
The **Build** method creates an **HdfChipDriver** object that manages the specified network interface. This object needs to provide the following methods:
<a name="table16989183941017"></a>
<table><thead align="left"><tr id="row61014406100"><th class="cellrowborder" valign="top" width="50%" id="mcps1.1.3.1.1"><p id="p111094011015"><a name="p111094011015"></a><a name="p111094011015"></a>Method</p>
</th>
<th class="cellrowborder" valign="top" width="50%" id="mcps1.1.3.1.2"><p id="p11102040201014"><a name="p11102040201014"></a><a name="p11102040201014"></a>Description</p>
</th>
</tr>
</thead>
<tbody><tr id="row111014409104"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="p21084017106"><a name="p21084017106"></a><a name="p21084017106"></a>int32_t (*init)(struct HdfChipDriver *chipDriver, NetDevice *netDev)</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="p1310184012103"><a name="p1310184012103"></a><a name="p1310184012103"></a>Initializes the current network interface. The <strong id="b18435181416253"><a name="b18435181416253"></a><a name="b18435181416253"></a>NetDeviceInterFace</strong> needs to be provided for the <strong id="b1543511144251"><a name="b1543511144251"></a><a name="b1543511144251"></a>netDev</strong>.</p>
</td>
</tr>
<tr id="row210840101012"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="p71064031013"><a name="p71064031013"></a><a name="p71064031013"></a>int32_t (*deinit)(struct HdfChipDriver *chipDriver, NetDevice *netDev)</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="p710144015101"><a name="p710144015101"></a><a name="p710144015101"></a>Deinitializes the current network interface.</p>
</td>
</tr>
<tr id="row151094011100"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="p1910340171018"><a name="p1910340171018"></a><a name="p1910340171018"></a>struct HdfMac80211BaseOps *ops</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="p31034071020"><a name="p31034071020"></a><a name="p31034071020"></a>Provides the WLAN basic capability interface set.</p>
</td>
</tr>
<tr id="row91012407102"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="p191014051019"><a name="p191014051019"></a><a name="p191014051019"></a>struct HdfMac80211STAOps *staOps</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="p810104013106"><a name="p810104013106"></a><a name="p810104013106"></a>Provides the interface set required for supporting the STA mode.</p>
</td>
</tr>
<tr id="row17101840111020"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.1 "><p id="p1010204081015"><a name="p1010204081015"></a><a name="p1010204081015"></a>struct HdfMac80211APOps *apOps</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.1.3.1.2 "><p id="p710184013105"><a name="p710184013105"></a><a name="p710184013105"></a>Provides the interface set required for supporting the AP mode.</p>
</td>
</tr>
</tbody>
</table>
| Method | Description |
| -------- | -------- |
| const&nbsp;char&nbsp;\*driverName | Indicates the driver name. |
| int32_t&nbsp;(\*InitChip)(struct&nbsp;HdfWlanDevice&nbsp;\*device) | Initializes the chip. |
| int32_t&nbsp;(\*DeinitChip)(struct&nbsp;HdfWlanDevice&nbsp;\*device) | Deinitializes the chip. |
| void&nbsp;(\*ReleaseFactory)(struct&nbsp;HdfChipDriverFactory&nbsp;\*factory) | Releases the **HdfChipDriverFactory** object. |
| struct&nbsp;HdfChipDriver&nbsp;\*(\*Build)(struct&nbsp;HdfWlanDevice&nbsp;\*device,&nbsp;uint8_t&nbsp;ifIndex) | Creates an **HdfChipDriver**. In the input parameters, **device** indicates the device information, and **ifIndex** indicates the sequence number of this interface in the chip. |
| void&nbsp;(\*Release)(struct&nbsp;HdfChipDriver&nbsp;\*chipDriver) | Releases the chip driver. |
| uint8_t&nbsp;(\*GetMaxIFCount)(struct&nbsp;HdfChipDriverFactory&nbsp;\*factory) | Obtains the maximum number of interfaces supported by the current chip. |
The **Build** method creates an **HdfChipDriver** object that manages the specified network interface. This object needs to provide the following methods:
| Method | Description |
| -------- | -------- |
| int32_t&nbsp;(\*init)(struct&nbsp;HdfChipDriver&nbsp;\*chipDriver,&nbsp;NetDevice&nbsp;\*netDev) | Initializes the current network interface. The **NetDeviceInterFace** needs to be provided for the **netDev**. |
| int32_t&nbsp;(\*deinit)(struct&nbsp;HdfChipDriver&nbsp;\*chipDriver,&nbsp;NetDevice&nbsp;\*netDev) | Deinitializes the current network interface. |
| struct&nbsp;HdfMac80211BaseOps&nbsp;\*ops | Provides the WLAN basic capability interface set. |
| struct&nbsp;HdfMac80211STAOps&nbsp;\*staOps | Provides the interface set required for supporting the STA mode. |
| struct&nbsp;HdfMac80211APOps&nbsp;\*apOps | Provides the interface set required for supporting the AP mode. |
2. Create a configuration file to describe the chips supported by the driver.
Create a chip configuration file in the product configuration directory and save it to the source code path **//vendor/vendor\_name/product\_name/config/wifi/wlan\_chip\_chip\_name.hcs**.
The sample code is as follows:
```
root {
wlan_config {
chip_name :& chipList {
chip_name :: chipInst {
match_attr = "hdf_wlan_chips_chip_name"; /* Indicates the configuration matching attribute, which is used to provide the configuration root of the driver.*/
driverName = "driverName"; /* Indicates the driver name, which must be the same as that of driverName in HdfChipDriverFactory.*/
sdio {
vendorId = 0xXXXX; /* your vendor id */
deviceId = [0xXXXX]; /*your supported devices */
}
}
}
}
}
```
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>Replace the values of **vendor\_name**, **product\_name**, and **chip\_name** in the path and file with the actual names.
>Set **vendorId** and **deviceId** to the actual vendor ID and chip ID, respectively.
Create a chip configuration file in the product configuration directory and save it to the source code path **//vendor/vendor\_name/product\_name/config/wifi/wlan\_chip\_chip\_name.hcs**.
```
root {
wlan_config {
chip_name :& chipList {
chip_name :: chipInst {
match_attr = "hdf_wlan_chips_chip_name"; /* Indicates the configuration matching attribute, which is used to provide the configuration root of the driver. */
driverName = "driverName"; /* Indicates the driver name, which must be the same as that of driverName in HdfChipDriverFactory.*/
sdio {
vendorId = 0xXXXX; /* your vendor id */
deviceId = [0xXXXX]; /*your supported devices */
}
}
}
}
}
```
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**
>
> Replace the values of **vendor\_name**, **product\_name**, and **chip\_name** in the path and file with the actual names.
>
> Set **vendorId** and **deviceId** to the actual vendor ID and chip ID, respectively.
3. Edit the configuration file and load the driver.
All device information of the product is defined in the source code file **//vendor/vendor\_name/product\_name/config/device\_info/device\_info.hcs**. Modify the file and add configurations to the **device** named **device\_wlan\_chips** in the **host** of the **network** command. The sample code is as follows:
All device information of the product is defined in the source code file **//vendor/vendor\_name/product\_name/config/device\_info/device\_info.hcs**. Modify the file and add configurations to the **device** named **device\_wlan\_chips** in the **host** of the **network** command. The sample code is as follows:
```
deviceN :: deviceNode {
policy = 0;
preload = 2;
moduleName = "HDF_WLAN_CHIPS";
deviceMatchAttr = "hdf_wlan_chips_chip_name";
serviceName = "driverName";
}
```
```
deviceN :: deviceNode {
policy = 0;
preload = 2;
moduleName = "HDF_WLAN_CHIPS";
deviceMatchAttr = "hdf_wlan_chips_chip_name";
serviceName = "driverName";
}
```
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>Make sure the value of **moduleName** is the same as that of **moduleName** in the WLAN driver.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**
>
> Make sure the value of **moduleName** is the same as that of **moduleName** in the WLAN driver.
4. Modify the **Kconfig** file to make the ported WLAN driver appear in the kernel configuration.
4. Modify the **Kconfig** file to make the ported WLAN driver appear in the kernel configuration.
Add configurations to **device/vendor\_name/drivers/Kconfig**. The sample code is as follows:
Add configurations to **device/vendor\_name/drivers/Kconfig**. The sample code is as follows:
```
config DRIVERS_HDF_WIFI_chip_name
bool "Enable chip_name Host driver"
default n
depends on DRIVERS_HDF_WLAN help
Answer Y to enable chip_name Host driver.
```
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>Replace **chip\_name** with the actual chip name.
```
config DRIVERS_HDF_WIFI_chip_name
bool "Enable chip_name Host driver"
default n
depends on DRIVERS_HDF_WLAN help
Answer Y to enable chip_name Host driver.
```
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**
>
> Replace **chip\_name** with the actual chip name.
5. Modify the build script to enable the driver to participate in the kernel build.
Add the following content to the end of the source code file **//device/vendor\_name/drivers/lite.mk**:
Add the following content to the end of the source code file **//device/vendor\_name/drivers/lite.mk**:
```
ifeq ($(LOSCFG_DRIVERS_HDF_WIFI_chip_name), y)
# After the build is complete, an object named hdf_wlan_chipdriver_chip_name needs to be linked. You are advised to use this name to prevent conflicts.
LITEOS_BASELIB += -lhdf_wlan_chipdriver_chip_name
# Add the build directory gpio.
LIB_SUBDIRS += ../peripheral/wifi/chip_name
endif
```
```
ifeq ($(LOSCFG_DRIVERS_HDF_WIFI_chip_name), y)
# After the build is complete, an object named hdf_wlan_chipdriver_chip_name needs to be linked. You are advised to use this name to prevent conflicts.
LITEOS_BASELIB += -lhdf_wlan_chipdriver_chip_name
# Add the build directory gpio.
LIB_SUBDIRS += ../peripheral/wifi/chip_name
endif
```
>![](../public_sys-resources/icon-note.gif) **NOTE:**
>Replace **chip\_name** with the actual chip name.
> ![icon-note.gif](public_sys-resources/icon-note.gif) **NOTE**
>
> Replace **chip_name** with the actual chip name.
......@@ -19,6 +19,7 @@ You can use the Bootloader provided by the chipset vendor or open-source U-Boot
## Adaptation, Building, Burning, and Startup
1. Prepare the kernel configuration files, especially the chipset-related configuration files.
Source code directory of the configuration files: **kernel/linux/config/**
Create a **<*YOUR_CHIP*>_small_defconfig** file, such as **hi3516dv300_small_defconfig**, in the **linux-4.19/arch/arm/configs/** directory. The configuration file can be created by combining the general-purpose **small_common_defconfig** file and chipset-specific configurations.
......@@ -48,7 +49,7 @@ You can use the Bootloader provided by the chipset vendor or open-source U-Boot
The burning mode varies according to the development board of the chipset. Pay attention to the size of each burnt image and the configuration of the boot parameters. Below is the U-Boot parameter settings of Hi3516D V300:
```
setenv bootargs 'mem=128M console=ttyAMA0,115200 root=/dev/mmcblk0p3 ro rootfstype=ext4 rootwait blkdevparts=mmcblk0:1M(boot),9M(kernel),50M(rootfs),50M(userfs)'
```
......@@ -65,16 +66,23 @@ Debug the **init** process, start shell, and run a simple program in the user sp
Based on the preceding process, the recommended verification procedure is as follows:
1. Create a root file system image.
Create a root file system image **rootfs.img** by following instructions in [Building Procedures](../subsystems/subsys-build-all.md). As shown in the preceding figure, the startup process is closely related to the product configuration. You need to complete the following configuration when creating **rootfs.img**:
- Component configuration
In the product component configuration file ***vendor*/{*company*}/{*product*}/config.json**, configure the **init** component of the startup subsystem and the **linux_4_1_9** component of the kernel subsystem.
- System service configuration
Modify the system service configuration file ***vendor*/{*company*}/{*product*}/init_configs/init_xxx.cfg** to start the shell service.
- File system configuration
In the file system configuration file ***vendor*/{*company*}/{*product*}/fs.yml**, create the **/bin/sh -> mksh** and **/lib/ld-musl-arm.so.1 -> libc.so** soft links. These two files are the shell executable program and the c library on which the executable program depends, respectively.
- Startup configuration
In the ***vendor*/{*company*}/{*product*}/init_configs/etc** directory, configure startup settings, including the **fstab**, **rsS**, and **S*xxx*** files. Configure the startup settings as needed.
After the build is complete, check the **rootfs** content in the product compilation output directory to determine whether the generated **rootfs.img** file meets the expectation.
......
......@@ -24,38 +24,38 @@ After learning the compilation framework and setting up the compilation environm
The directory structure is as follows: device/{*chipset solution vendor*}/{*development board*}. For example, if you are using the hispark_taurus development board from HiSilicon, create the following directory in the root directory of the code:
```
mkdir -p device/hisilicon/hispark_taurus
```
```
mkdir -p device/hisilicon/hispark_taurus
```
The chipset solution directory tree is as follows:
```
device
└── company # Chipset solution vendor
└── board # Name of the development board
├── BUILD.gn # Build script
├── hals # OS device API adaptation
├── linux # (Optional) Linux kernel version
│ └── config.gni # Linux build configuration
└── liteos_a # (Optional) LiteOS kernel version
└── config.gni # LiteOS_A build configuration
```
```
device
└── company # Chipset solution vendor
└── board # Name of the development board
├── BUILD.gn # Build script
├── hals # OS device API adaptation
├── linux # (Optional) Linux kernel version
│ └── config.gni # Linux build configuration
└── liteos_a # (Optional) LiteOS kernel version
└── config.gni # LiteOS_A build configuration
```
For example, if you are porting the Linux kernel to the hispark_taurus development board, the directory tree is as follows:
```
device
└── hisilicon
└── hispark_taurus
├── BUILD.gn
├── hals
├── ......
└── linux
└── config.gni
```
```
device
└── hisilicon
└── hispark_taurus
├── BUILD.gn
├── hals
├── ......
└── linux
└── config.gni
```
After the directory tree is created, store the source code related to the development board in the **hispark_taurus** directory.
......@@ -64,63 +64,63 @@ After learning the compilation framework and setting up the compilation environm
You can configure the build options in the **config.gni** file described in step 1. The compilation and building framework will then compile all OS components in the user space based on your configuration. The **config.gni** file contains the following key fields:
```
kernel_type: Kernel used by the development board, for example, LiteOS_A, LiteOS_M, or Linux.
kernel_version: Kernel version used by the development board, for example, 4.19.
board_cpu: CPU of the development board, for example, Cortex-A7 or RISCV32.
board_arch: Chipset architecture of the development board, for example, armv7-a or rv32imac.
board_toolchain: Name of the customized build toolchain used by the development board, for example, gcc-arm-none-eabi. If this field is not specified, ohos-clang will be used.
board_toolchain_prefix: Prefix of the toolchain, for example, gcc-arm-none-eabi.
board_toolchain_type: Toolchain type. Currently, only GCC and clang are supported.
board_cflags: Build options of the .c file configured for the development board.
board_cxx_flags: Build options of the .cpp file configured for the development board.
board_ld_flags: Linking options configured for the development board.
```
For HiSilicon's hispark_taurus development board, the content in **device/hisilicon/hispark_taurus/config.gni** is as follows:
```
# Board CPU type, e.g. "cortex-a7", "riscv32".
board_cpu = "cortex-a7"
# Name of the toolchain used for system building
# E.g. gcc-arm-none-eabi, arm-linux-harmonyeabi-gcc, ohos-clang, riscv32-unknown-elf.
# Note: The "ohos-clang" toolchain is used by default. You can also customize the toolchain.
board_toolchain = "mips-linux-gnu-gcc"
# Path where the toolchain is installed, which can be left blank if the installation path has been added to ~/.bashrc.
board_toolchain_path =
rebase_path("//prebuilts/gcc/linux-x86/arm/arm-linux-ohoseabi-gcc/bin",
root_build_dir)
# Prefix of the toolchain
board_toolchain_prefix = "arm-linux-ohoseabi-"
# Type of the compiler, which can be gcc or clang
board_toolchain_type = "gcc"
# Build options related to the development board
board_cflags = [
]
board_cxx_flags = [
]
board_ld_flags = []
# Board related headfiles search path.
board_include_dirs = []
board_include_dirs += [ rebase_path(
"//prebuilts/gcc/linux-x86/arm/arm-linux-ohoseabi-gcc/target/usr/include",
root_build_dir) ]
# Board adapter dir for OHOS components.
board_adapter_dir = ""
# Sysroot path.
board_configed_sysroot = ""
# Board storage type, it used for file system generation.
storage_type = "emmc"
```
```
kernel_type: Kernel used by the development board, for example, LiteOS_A, LiteOS_M, or Linux.
kernel_version: Kernel version used by the development board, for example, 4.19.
board_cpu: CPU of the development board, for example, Cortex-A7 or RISCV32.
board_arch: Chipset architecture of the development board, for example, armv7-a or rv32imac.
board_toolchain: Name of the customized build toolchain used by the development board, for example, gcc-arm-none-eabi. If this field is not specified, ohos-clang will be used.
board_toolchain_prefix: Prefix of the toolchain, for example, gcc-arm-none-eabi.
board_toolchain_type: Toolchain type. Currently, only GCC and clang are supported.
board_cflags: Build options of the .c file configured for the development board.
board_cxx_flags: Build options of the .cpp file configured for the development board.
board_ld_flags: Linking options configured for the development board.
```
For HiSilicon's hispark_taurus development board, the content in **device/hisilicon/hispark_taurus/config.gni** is as follows:
```
# Board CPU type, e.g. "cortex-a7", "riscv32".
board_cpu = "cortex-a7"
# Name of the toolchain used for system building
# E.g. gcc-arm-none-eabi, arm-linux-harmonyeabi-gcc, ohos-clang, riscv32-unknown-elf.
# Note: The "ohos-clang" toolchain is used by default. You can also customize the toolchain.
board_toolchain = "mips-linux-gnu-gcc"
# Path where the toolchain is installed, which can be left blank if the installation path has been added to ~/.bashrc.
board_toolchain_path =
rebase_path("//prebuilts/gcc/linux-x86/arm/arm-linux-ohoseabi-gcc/bin",
root_build_dir)
# Prefix of the toolchain
board_toolchain_prefix = "arm-linux-ohoseabi-"
# Type of the compiler, which can be gcc or clang
board_toolchain_type = "gcc"
# Build options related to the development board
board_cflags = [
]
board_cxx_flags = [
]
board_ld_flags = []
# Board related headfiles search path.
board_include_dirs = []
board_include_dirs += [ rebase_path(
"//prebuilts/gcc/linux-x86/arm/arm-linux-ohoseabi-gcc/target/usr/include",
root_build_dir) ]
# Board adapter dir for OHOS components.
board_adapter_dir = ""
# Sysroot path.
board_configed_sysroot = ""
# Board storage type, it used for file system generation.
storage_type = "emmc"
```
3. Edit the build script of the development board.
......@@ -128,16 +128,16 @@ After learning the compilation framework and setting up the compilation environm
For example, edit the **device/hisilicon/hispark_taurus/BUILD.gn** file as follows:
```
# It is recommended that the group name be the same as the development board name.
group("hispark_taurus") {
deps = [ "//kernel/linux/patches:linux_kernel" ] # Start kernel compilation.
deps += [
...... # Other compilation units of the development board
]
}
```
```
# It is recommended that the group name be the same as the development board name.
group("hispark_taurus") {
deps = [ "//kernel/linux/patches:linux_kernel" ] # Start kernel compilation.
deps += [
...... # Other compilation units of the development board
]
}
```
4. Start building and debugging.
......
......@@ -30,10 +30,10 @@ Create a file named **config.json** in the **//vendor/MyProductVendor/*{product_
{
"subsystem": "ace",
"components": [
{ "component": "ace_engine_lite", "features":[""] }
{ "component": "ace_engine_lite", "features":[] }
]
}
},
...
]
}
......@@ -41,29 +41,20 @@ Create a file named **config.json** in the **//vendor/MyProductVendor/*{product_
```
The main configurations are as follows:
**product_name**: product name. This parameter is required.
**version**: version. This parameter is required.
**type**: system level, such as **small** or **standard**. This parameter is required.
**target_cpu**: CPU type of the device, such as **arm64**, **riscv**, or **x86**. This parameter is required.
**ohos_version**: operating system version. This parameter is optional.
**device_company**: device manufacturer name. This parameter is required.
**board**: board name. This parameter is required.
**enable_ramdisk**: whether to enable the RAM disk. This parameter is required.
**kernel_type**: kernel type. This parameter is optional.
**kernel_version**: kernel version. This parameter is optional. Both **kernel_type** and **kernel_version** are fixed.
**subsystems**: subsystem to enable. A subsystem can be treated as an independently built functional block. This parameter is required.
**product_company**: device manufacturer name. It is not set in the configuration, but in the directory name, next to the vendor name. It can be accessed from **build.gn script**.
| Item| Description|
|-------|----------|
|product_name |(Mandatory) Product name.|
|version|(Mandatory) Version.|
|type|(Mandatory) System level, such as **small** and **standard**.|
|target_cpu |(Mandatory) CPU type of the device, such as **arm64**, **riscv**, or **x86**.|
|ohos_version|(Optional) Operating system version.|
|device_company|(Mandatory) Device manufacturer name.|
|board|(Mandatory) Development board name.|
|enable_ramdisk|(Mandatory) Whether to start the RAM disk.|
|kernel_type|(Optional) Kernel type.|
|kernel_version|(Optional) Kernel version. The values of both **kernel_type** and **kernel_version** are fixed in the standard system.|
|subsystems|(Mandatory) Subsystem to enable. A subsystem can be treated as an independently built functional block.|
|product_company|Device manufacturer name. It is not set in the configuration, but in the directory name, next to the vendor name. It can be accessed from **build.gn script**.|
You can find predefined subsystems in **//build/subsystem_config.json**. You can also customize subsystems.
......@@ -89,7 +80,7 @@ Now, you need to port the Linux kernel to enable it to run successfully.
### Adding a Kernel-built Subsystem to the SoC
Add the following subsystem configuration to the **//build/subsystem_config.json** file:
Modify the **//build/subsystem_config.json** file to add a subsystem. For example, if **product_name** is **MyProduct**, configure the **//vendor/MyProductVendor/MyProduct/config.json** file as follows:
```
......@@ -126,10 +117,10 @@ The **BUILD.gn** file is the only entry for building the subsystem.
The expected build result described in the table below.
| File| Description|
| File| Description|
| -------- | -------- |
| $root_build_dir/packages/phone/images/uImage | Kernel image.|
| $root_build_dir/packages/phone/images/uboot | Bootloader image.|
| $root_build_dir/packages/phone/images/uImage | Kernel image.|
| $root_build_dir/packages/phone/images/uboot | Bootloader image.|
### Verifying the Porting
......@@ -140,17 +131,18 @@ Now start build, and check whether the kernel image is generated as expected.
1. Overview of user-mode boot process
![user-mode boot](figures/user-mode boot.png)
![user-mode boot](figures/user-mode boot.png)
When the system is powered on, the kernel loads and starts services and applications as follows:
1. The kernel loads the init process, which is specified by **cmdline** of the kernel when the bootloader starts the kernel, for example, **init=/init root/dev/xxx**.
2. After the init process is started, **tmpfs** and **procfs** are mounted and basic **dev** nodes are created to establish a basic root file system.
3. The init process starts the ueventd process to listen for device hot-swap events in the kernel and creates **dev** nodes for related devices as well as partitions for the block device.
4. After mounting partitions (**system** and **vendor**) of the block device, the init process scans for the init startup script of each system service and launches the respective service ability (SA).
5. Each SA registers with the samgr process, which serves as the service registration center. The samgr process assigns each SA with an ID, which will be used by an application to access the desired SA.
6. The foundation process implements application lifecycle management. It is a special SA service process that provides the user program management framework and basic services.
7. The appspawn process directly spawns the application process, eliminating the need for the application to load the JS runtime environment. This reduces the application startup time.
1. The kernel loads the init process, which is specified by **cmdline** of the kernel when the bootloader starts the kernel, for example, **init=/init root/dev/xxx**.
2. After the init process is started, **tmpfs** and **procfs** are mounted and basic **dev** nodes are created to establish a basic root file system.
3. The init process starts the ueventd process to listen for device hot-swap events in the kernel and creates **dev** nodes for related devices as well as partitions for the block device.
4. After mounting partitions (**system** and **vendor**) of the block device, the init process scans for the init startup script of each system service and launches the respective service ability (SA).
5. Each SA registers with the samgr process, which serves as the service registration center. The samgr process assigns each SA with an ID, which will be used by an application to access the desired SA.
6. The foundation process implements application lifecycle management. It is a special SA service process that provides the user program management framework and basic services.
7. The appspawn process directly spawns the application process, eliminating the need for the application to load the JS runtime environment. This reduces the application startup time.
2. init module
......@@ -158,7 +150,7 @@ Now start build, and check whether the kernel image is generated as expected.
When porting a new chip platform, you need to add the **/vendor/etc/init/init.{hardware}.cfg** file that contains the platform-level initialization configuration. This file is used to implement platform-level initialization, for example, installing the ko driver and configuring information on the related **/proc** nodes.
The code of the init process is stored in the **//base/startup/init** directory. This process is the first process in the system and does not depend on other processes.
The code of the init process is stored in the **//base/startup/init_lite** directory. This process is the first process in the system and does not depend on other processes.
For details about how to develop the initialization configuration file, see [Startup](../subsystems/subsys-boot-overview.md).
......@@ -170,180 +162,184 @@ Now start build, and check whether the kernel image is generated as expected.
This section describes how to port a Liquid Crystal Display (LCD) driver. The hardware driver framework (HDF) designs a driver model for the LCD. To support an LCD, you must compile a driver, generate a model instance in the driver, and register the instance.
The LCD drivers are stored in the **//drivers/framework/model/display/driver/panel** directory.
The LCD drivers are stored in the **//drivers/hdf_core/framework/model/display/driver/panel** directory.
- Create a panel driver.
1. Create a panel driver.
In the **Init** method of the driver, call **RegisterPanel** to register the model instance.
In the **Init** method of the driver, call **RegisterPanel** to register the model instance. For example:
```
int32_t XXXInit(struct HdfDeviceObject *object)
{
struct PanelData *panel = CreateYourPanel();
// Registration
if (RegisterPanel(panel) != HDF_SUCCESS) {
HDF_LOGE("%s: RegisterPanel failed", __func__);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
```
int32_t XXXInit(struct HdfDeviceObject *object)
{
struct PanelData *panel = CreateYourPanel();
struct HdfDriverEntry g_xxxxDevEntry = {
.moduleVersion = 1,
.moduleName = "LCD_XXXX",
.Init = XXXInit,
};
// Registration
if (RegisterPanel(panel) != HDF_SUCCESS) {
HDF_LOGE("%s: RegisterPanel failed", __func__);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
HDF_INIT(g_xxxxDevEntry);
```
struct HdfDriverEntry g_xxxxDevEntry = {
.moduleVersion = 1,
.moduleName = "LCD_XXXX",
.Init = XXXInit,
};
- Configure and load the panel driver. All device information about the product is defined in the **//vendor/MyProductVendor/MyProduct/config/device_info/device_info.hcs** file. Modify the file by adding configurations for the device named **device_lcd** to the host named **display**. Note: The value of **moduleName** must be the same as that in the panel driver.
HDF_INIT(g_xxxxDevEntry);
```
```
root {
...
display :: host {
device_lcd :: device {
deviceN :: deviceNode {
policy = 0;
priority = 100;
preload = 2;
moduleName = "LCD_XXXX";
}
}
}
}
```
2. Configure and load the panel driver. All device information about the product is defined in the **//vendor/MyProductVendor/MyProduct/config/device_info/device_info.hcs** file. Modify the file by adding configurations for the device named **device_lcd** to the host named **display**.
Note: The value of **moduleName** must be the same as that in the panel driver.
For details about driver development, see [LCD](../driver/driver-peripherals-lcd-des.md).
```
root {
...
display :: host {
device_lcd :: device {
deviceN :: deviceNode {
policy = 0;
priority = 100;
preload = 2;
moduleName = "LCD_XXXX";
}
}
}
}
```
For details about driver development, see [LCD](../driver/driver-peripherals-lcd-des.md).
### Touchscreen
This section describes how to port a touchscreen driver. The touchscreen driver is stored in the **//drivers/framework/model/input/driver/touchscreen** directory. To port a touchscreen driver, register a **ChipDevice** model instance.
This section describes how to port a touchscreen driver. The touchscreen driver is stored in the **//drivers/hdf_core/framework/model/input/driver/touchscreen** directory. To port a touchscreen driver, register a **ChipDevice** model instance.
- Create a touchscreen driver.
1. Create a touchscreen driver.
Create the **touch_ic_name.c** file in the directory. Replace **ic_name** with the name of your chip. The file template is as follows:
Create the **touch_ic_name.c** file in the directory. Replace **ic_name** with the name of your chip. The file template is as follows:
```
#include "hdf_touch.h"
```
#include "hdf_touch.h"
static int32_t HdfXXXXChipInit(struct HdfDeviceObject *device)
{
ChipDevice *tpImpl = CreateXXXXTpImpl();
if(RegisterChipDevice(tpImpl) != HDF_SUCCESS) {
ReleaseXXXXTpImpl(tpImpl);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
static int32_t HdfXXXXChipInit(struct HdfDeviceObject *device)
{
ChipDevice *tpImpl = CreateXXXXTpImpl();
if(RegisterChipDevice(tpImpl) != HDF_SUCCESS) {
ReleaseXXXXTpImpl(tpImpl);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
struct HdfDriverEntry g_touchXXXXChipEntry = {
.moduleVersion = 1,
.moduleName = "HDF_TOUCH_XXXX",
.Init = HdfXXXXChipInit,
};
struct HdfDriverEntry g_touchXXXXChipEntry = {
.moduleVersion = 1,
.moduleName = "HDF_TOUCH_XXXX",
.Init = HdfXXXXChipInit,
};
HDF_INIT(g_touchXXXXChipEntry);
```
HDF_INIT(g_touchXXXXChipEntry);
```
Implement the following APIs in **ChipDevice**:
Implement the following interfaces in **ChipDevice**:
| API| Description|
| -------- | -------- |
| int32_t&nbsp;(\*Init)(ChipDevice&nbsp;\*device) | Initializes a touchscreen.|
| int32_t&nbsp;(\*Detect)(ChipDevice&nbsp;\*device) | Detects a touchscreen.|
| int32_t&nbsp;(\*Suspend)(ChipDevice&nbsp;\*device) | Suspends a touchscreen.|
| int32_t&nbsp;(\*Resume)(ChipDevice&nbsp;\*device) | Resumes a touchscreen.|
| int32_t&nbsp;(\*DataHandle)(ChipDevice&nbsp;\*device) | Reads data from a touchscreen and writes the touch point data to **device** > **driver** > **frameData**.|
| int32_t&nbsp;(\*UpdateFirmware)(ChipDevice&nbsp;\*device) | Upgrades the firmware.|
- Configure the product and load the driver.
| API| Description|
| -------- | -------- |
| int32_t (\*Init)(ChipDevice \*device) | Initializes a touchscreen.|
| int32_t (\*Detect)(ChipDevice \*device) | Detects a touchscreen.|
| int32_t (\*Suspend)(ChipDevice \*device) | Suspends a touchscreen.|
| int32_t (\*Resume)(ChipDevice \*device) | Resumes a touchscreen.|
| int32_t (\*DataHandle)(ChipDevice \*device) | Reads data from a touchscreen and writes the touch point data to **device** > **driver** > **frameData**.|
| int32_t (\*UpdateFirmware)(ChipDevice \*device) | Upgrades the firmware.|
2. Configure the product and load the driver.
All device information about the product is defined in the **//vendor/MyProductVendor/MyProduct/config/device_info/device_info.hcs** file. Modify the file by adding configurations for the device named **device_touch_chip** to the host named **input**. Note: The value of **moduleName** must be the same as that in the touchscreen driver.
All device information about the product is defined in the **//vendor/MyProductVendor/MyProduct/config/device_info/device_info.hcs** file. Modify the file by adding configurations for the device named **device_touch_chip** to the host named **input**. Note: The value of **moduleName** must be the same as that in the touchscreen driver.
```
deviceN :: deviceNode {
policy = 0;
priority = 130;
preload = 0;
permission = 0660;
moduleName = "HDF_TOUCH_XXXX";
deviceMatchAttr = "touch_XXXX_configs";
}
```
```
deviceN :: deviceNode {
policy = 0;
priority = 130;
preload = 0;
permission = 0660;
moduleName = "HDF_TOUCH_XXXX";
deviceMatchAttr = "touch_XXXX_configs";
}
```
For details about driver development, see [Touchscreen](../driver/driver-peripherals-touch-des.md).
For details about driver development, see [Touchscreen](../driver/driver-peripherals-touch-des.md).
### WLAN
The WLAN driver is divided into two parts. One of the parts manages WLAN devices, and the other part manages WLAN traffic. HDF WLAN provides abstraction for the two parts. Currently, only the WLAN with the SDIO interface is supported.
**Figure 1** WLAN chip
**Figure 1** WLAN chip
![hdf_wifi](figures/hdf_wifi.png)
![hdf_wifi](figures/hdf_wifi.png)
To support a chip, implement a **ChipDriver** for it. The major task is to implement the following interfaces provided by **HDF_WLAN_CORE** and **NetDevice**.
| API| Header File| Description|
| -------- | -------- | -------- |
| HdfChipDriverFactory | //drivers/framework/include/wifi/hdf_wlan_chipdriver_manager.h | Supports multiple WLAN interfaces of a chip.|
| HdfChipDriver | //drivers/framework/include/wifi/wifi_module.h | Manages a specific WLAN interface. Each WLAN interface corresponds to an **HdfChipDriver**.|
| NetDeviceInterFace | //drivers/framework/include/net/net_device.h | Communicates with the protocol stack, such as sending data and setting the status of network interfaces.|
| HdfChipDriverFactory | //drivers/hdf_core/framework/include/wifi/hdf_wlan_chipdriver_manager.h | Supports multiple WLAN interfaces of a chip.|
| HdfChipDriver | //drivers/hdf_core/framework/include/wifi/wifi_module.h | Manages a specific WLAN interface. Each WLAN interface corresponds to an **HdfChipDriver**.|
| NetDeviceInterFace | //drivers/hdf_core/framework/include/net/net_device.h | Communicates with the protocol stack, such as sending data and setting the status of network interfaces.|
To port a WLAN driver, perform the following steps:
1. Create an HDF driver. You are advised to place the code file in the **//device/MySoCVendor/peripheral/wifi/chip_name/** directory. The file template is as follows:
```
static int32_t HdfWlanHisiChipDriverInit(struct HdfDeviceObject *device) {
static struct HdfChipDriverFactory factory = CreateChipDriverFactory();
struct HdfChipDriverManager *driverMgr = HdfWlanGetChipDriverMgr();
if (driverMgr->RegChipDriver(&factory) != HDF_SUCCESS) {
HDF_LOGE("%s fail: driverMgr is NULL!", __func__);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
```
static int32_t HdfWlanXXXChipDriverInit(struct HdfDeviceObject *device) {
static struct HdfChipDriverFactory factory = CreateChipDriverFactory();
struct HdfChipDriverManager *driverMgr = HdfWlanGetChipDriverMgr();
if (driverMgr->RegChipDriver(&factory) != HDF_SUCCESS) {
HDF_LOGE("%s fail: driverMgr is NULL!", __func__);
return HDF_FAILURE;
}
return HDF_SUCCESS;
}
struct HdfDriverEntry g_hdfXXXChipEntry = {
.moduleVersion = 1,
.Init = HdfWlanXXXChipDriverInit,
.Release = HdfWlanXXXChipRelease,
.moduleName = "HDF_WIFI_CHIP_XXX"
};
struct HdfDriverEntry g_hdfXXXChipEntry = {
.moduleVersion = 1,
.Init = HdfWlanXXXChipDriverInit,
.Release = HdfWlanXXXChipRelease,
.moduleName = "HDF_WIFI_CHIP_XXX"
};
HDF_INIT(g_hdfXXXChipEntry);
```
HDF_INIT(g_hdfXXXChipEntry);
```
Create an **HdfChipDriverFactory** in the **CreateChipDriverFactory**. The APIs are as follows:
Create an **HdfChipDriverFactory** in the **CreateChipDriverFactory**. The APIs are as follows:
| API| Description|
| -------- | -------- |
| const&nbsp;char&nbsp;\*driverName | Indicates the driver name.|
| int32_t&nbsp;(\*InitChip)(struct&nbsp;HdfWlanDevice&nbsp;\*device) | Initializes a chip.|
| int32_t&nbsp;(\*DeinitChip)(struct&nbsp;HdfWlanDevice&nbsp;\*device) | Deinitializes a chip.|
| void&nbsp;(*ReleaseFactory)(struct&nbsp;HdfChipDriverFactory&nbsp;*factory) | Releases the **HdfChipDriverFactory** object.|
| struct&nbsp;HdfChipDriver&nbsp;*(_Build)(struct&nbsp;HdfWlanDevice&nbsp;\*device,&nbsp;uint8*t&nbsp;ifIndex) | Creates an **HdfChipDriver**. In the input parameters, **device** indicates the device information, and **ifIndex** indicates the sequence number of this interface in the chip.|
| void&nbsp;(*Release)(struct&nbsp;HdfChipDriver&nbsp;*chipDriver) | Releases the **HdfChipDriver**.|
| uint8_t&nbsp;(\*GetMaxIFCount)(struct&nbsp;HdfChipDriverFactory&nbsp;\*factory) | Obtains the maximum number of APIs supported by the current chip.|
Implement the following APIs in the **HdfChipDriver**.
| API| Description|
| -------- | -------- |
| int32_t&nbsp;(\*init)(struct&nbsp;HdfChipDriver&nbsp;\*chipDriver,&nbsp;NetDevice&nbsp;\*netDev) | Initializes the current network interface. The **NetDeviceInterFace** needs to be provided for the **netDev**.|
| int32_t&nbsp;(\*deinit)(struct&nbsp;HdfChipDriver&nbsp;\*chipDriver,&nbsp;NetDevice&nbsp;\*netDev) | Deinitializes the current network interface.|
| struct&nbsp;HdfMac80211BaseOps&nbsp;\*ops | Provides the WLAN basic capability interface set.|
| struct&nbsp;HdfMac80211STAOps&nbsp;\*staOps | Provides the interface set required for supporting the standalone (STA) mode.|
| struct&nbsp;HdfMac80211APOps&nbsp;\*apOps | Provides the interface set required for supporting the access point (AP) mode.|
| API| Description|
| -------- | -------- |
| const char \*driverName | Indicates the driver name.|
| int32_t (\*InitChip)(struct HdfWlanDevice \*device) | Initializes a chip.|
| int32_t (\*DeinitChip)(struct HdfWlanDevice \*device) | Deinitializes a chip.|
| void (_ReleaseFactory)(struct HdfChipDriverFactory _factory) | Releases the **HdfChipDriverFactory** object.|
| struct HdfChipDriver _(_Build)(struct HdfWlanDevice \*device, uint8_t ifIndex) | Creates an **HdfChipDriver**. In the input parameters, **device** indicates the device information, and **ifIndex** indicates the sequence number of this interface in the chip.|
| void (_Release)(struct HdfChipDriver _chipDriver) | Releases the **HdfChipDriver**.|
| uint8_t (\*GetMaxIFCount)(struct HdfChipDriverFactory \*factory) | Obtains the maximum number of APIs supported by the current chip.|
Implement the following APIs in the **HdfChipDriver**.
| API| Description|
| -------- | -------- |
| int32_t (\*init)(struct HdfChipDriver \*chipDriver, NetDevice \*netDev) | Initializes the current network interface. The **NetDeviceInterFace** needs to be provided for the **netDev**.|
| int32_t (\*deinit)(struct HdfChipDriver \*chipDriver, NetDevice \*netDev) | Deinitializes the current network interface.|
| struct HdfMac80211BaseOps \*ops | Provides the WLAN basic capability interface set.|
| struct HdfMac80211STAOps \*staOps | Provides the interface set required for supporting the standalone (STA) mode.|
| struct HdfMac80211APOps \*apOps | Provides the interface set required for supporting the access point (AP) mode.|
2. Compile the configuration file to describe the devices supported by the driver.
......@@ -353,65 +349,68 @@ Implement the following APIs in the **HdfChipDriver**.
The sample code is as follows:
```
root {
wlan_config {
chip_name :& chipList {
chip_name :: chipInst {
match_attr = "hdf_wlan_chips_chip_name"; /* Configure the matching attribute, which is used to provide the configuration root of the driver.*/
driverName = "driverName"; /* The value must be the same as that of driverName in HdfChipDriverFactory.*/
sdio {
vendorId = 0x0296;
deviceId = [0x5347];
}
}
}
}
}
```
```
root {
wlan_config {
chip_name :& chipList {
chip_name :: chipInst {
match_attr = "hdf_wlan_chips_chip_name"; /* Configure the matching attribute, which is used to provide the configuration root of the driver.*/
driverName = "driverName"; /* The value must be the same as that of driverName in HdfChipDriverFactory.*/
sdio {
vendorId = 0x0296;
deviceId = [0x5347];
}
}
}
}
}
```
3. Edit the configuration file and load the driver.
All device information about the product is defined in the **//vendor/MyProductVendor/MyProduct/config/device_info/device_info.hcs** file. Modify the file by adding configurations for the device named **device_wlan_chips** to the host named **network**. Note: The value of **moduleName** must be the same as that in the touchscreen driver.
All device information about the product is defined in the **//vendor/MyProductVendor/MyProduct/config/device_info/device_info.hcs** file. Modify the file by adding configurations for the device named **device_wlan_chips** to the host named **network**.
Note: The value of **moduleName** must be the same as that in the touchscreen driver.
```
deviceN :: deviceNode {
policy = 0;
preload = 2;
moduleName = "HDF_WLAN_CHIPS";
deviceMatchAttr = "hdf_wlan_chips_chip_name";
serviceName = "driverName";
}
```
```
deviceN :: deviceNode {
policy = 0;
preload = 2;
moduleName = "HDF_WLAN_CHIPS";
deviceMatchAttr = "hdf_wlan_chips_chip_name";
serviceName = "driverName";
}
```
4. Build the driver.
- Create a kernel configuration menu. Create a **Kconfig** file in the **//device/MySoCVendor/peripheral** directory. The file template is as follows:
- Create a kernel configuration menu. Create a **Kconfig** file in the **//device/MySoCVendor/peripheral** directory. The file template is as follows:
```
config DRIVERS_WLAN_XXX
bool "Enable XXX WLAN Host driver"
default n
depends on DRIVERS_HDF_WIFI
help
Answer Y to enable XXX Host driver. Support chip xxx
```
```
config DRIVERS_WLAN_XXX
bool "Enable XXX WLAN Host driver"
default n
depends on DRIVERS_HDF_WIFI
help
Answer Y to enable XXX Host driver. Support chip xxx
```
Add the following configuration to the end of the **//drivers/hdf_core/adapter/khdf/linux/model/network/wifi/Kconfig** file:
Add the following sample code to the end of the **//drivers/adapter/khdf/linux/model/network/wifi/Kconfig** file to add the configuration menu to the kernel:
```
source "../../../../../device/MySoCVendor/peripheral/Kconfig"
```
```
source "../../../../../device/MySoCVendor/peripheral/Kconfig"
```
- Create a build script.
Add the following configuration to the end of the **//drivers/hdf_core/adapter/khdf/linux/model/network/wifi/Makefile** file:
- Create a build script.
Add the following configuration to the end of the **//drivers/adapter/khdf/linux/model/network/wifi/Makefile** file:
```
HDF_DEVICE_ROOT := $(HDF_DIR_PREFIX)/../device
obj-$(CONFIG_DRIVERS_WLAN_XXX) += $(HDF_DEVICE_ROOT)/MySoCVendor/peripheral/build/standard/
```
```
HDF_DEVICE_ROOT := $(HDF_DIR_PREFIX)/../device
obj-$(CONFIG_DRIVERS_WLAN_XXX) += $(HDF_DEVICE_ROOT)/MySoCVendor/peripheral/build/standard/
```
When **DRIVERS_WLAN_XXX** is enabled in the kernel, **makefile** in **//device/MySoCVendor/peripheral/build/standard/** is called. For details about the development, see [LED Peripheral Control](../guide/device-wlan-led-control.md).
When **DRIVERS_WLAN_XXX** is enabled in the kernel, **makefile** in **//device/MySoCVendor/peripheral/build/standard/** is called. For details about the development, see [LED Peripheral Control](../guide/device-wlan-led-control.md).
......@@ -14,51 +14,37 @@ Perform the following steps on Ubuntu.
1. Run the following command to install hb and update it to the latest version:
```
pip3 install --user build/lite
```shell
python3 -m pip install --user build/hb
```
2. Set an environment variable.
```
```shell
vim ~/.bashrc
```
Copy the following command to the last line of the .bashrc file, save the file, and exit.
```
```shell
export PATH=~/.local/bin:$PATH
```
Update the environment variable.
```
```shell
source ~/.bashrc
```
3. Run the **hb -h** command in the source code directory. If the following information is displayed, the installation is successful:
```
usage: hb
OHOS build system
positional arguments:
{build,set,env,clean}
build Build source code
set OHOS build settings
env Show OHOS build env
clean Clean output
optional arguments:
-h, --help show this help message and exit
```
![hb_help](figures/hb_help.png)
> ![icon-notice.gif](public_sys-resources/icon-notice.gif) **NOTICE**
> - To uninstall hb, run the following command:
>
> ```
> pip3 uninstall ohos-build
>
> ```shell
> python3 -m pip uninstall ohos-build
> ```
>
> - If any issue occurs during the hb installation, see [FAQs](quickstart-pkg-common-hberr.md).
......@@ -77,26 +63,26 @@ Perform the following steps on Ubuntu.
2. [Download LLVM](https://repo.huaweicloud.com/harmonyos/compiler/clang/9.0.0-36191/linux/llvm-linux-9.0.0-36191.tar).
3. Decompress the LLVM installation package to **~/llvm**.
```
```shell
tar -zxvf llvm.tar -C ~/
```
4. Set an environment variable.
```
```shell
vim ~/.bashrc
```
Copy the following command to the last line of the .bashrc file, save the file, and exit.
```
```shell
export PATH=~/llvm/bin:$PATH
```
5. Validate the environment variable.
```
```shell
source ~/.bashrc
```
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册