提交 046d3680 编写于 作者: A Annie_wang

update docs

Signed-off-by: NAnnie_wang <annie.wangli@huawei.com>
上级 47d6c5bc
# Driver Message Mechanism Management<a name="EN-US_TOPIC_0000001052657065"></a> # Driver Messaging Mechanism
## When to Use<a name="section33014541954"></a>
## When to Use
When user-level applications need to interact with kernel-level drivers, the driver message mechanism of the HDF can be used.
The HDF messaging mechanism implements the interaction between the user-mode applications and kernel-mode drivers.
## Available APIs<a name="section538852311616"></a>
The message mechanism provides the following features: ## Available APIs
1. User-level applications send messages to drivers. The messaging mechanism allows:
2. User-level applications receive events sent by the drivers.
1. User-mode applications to send messages to drivers.
**Table 1** APIs for the driver message mechanism
2. User-mode applications to receive events from drivers.
<a name="table208212674114"></a>
<table><thead align="left"><tr id="row08282618416"><th class="cellrowborder" valign="top" width="46.379999999999995%" id="mcps1.2.3.1.1"><p id="p382132664112"><a name="p382132664112"></a><a name="p382132664112"></a><strong id="b142817619332"><a name="b142817619332"></a><a name="b142817619332"></a>Function</strong></p> **Table 1** APIs for the driver messaging mechanism
</th>
<th class="cellrowborder" valign="top" width="53.620000000000005%" id="mcps1.2.3.1.2"><p id="p4826264419"><a name="p4826264419"></a><a name="p4826264419"></a><strong id="b201539486743916"><a name="b201539486743916"></a><a name="b201539486743916"></a>Description</strong></p> | API| Description|
</th> | -------- | -------- |
</tr> | struct&nbsp;HdfIoService&nbsp;\*HdfIoServiceBind(const&nbsp;char&nbsp;\*serviceName); | Obtains a driver service. The **Dispatch()** method in the driver service obtained sends messages to the driver.|
</thead> | void&nbsp;HdfIoServiceRecycle(struct&nbsp;HdfIoService&nbsp;\*service); | Releases a driver service.|
<tbody><tr id="row1582426174114"><td class="cellrowborder" valign="top" width="46.379999999999995%" headers="mcps1.2.3.1.1 "><p id="p182341916144420"><a name="p182341916144420"></a><a name="p182341916144420"></a>struct HdfIoService *HdfIoServiceBind(const char *serviceName)</p> | int&nbsp;HdfDeviceRegisterEventListener(struct&nbsp;HdfIoService&nbsp;\*target,&nbsp;struct&nbsp;HdfDevEventlistener&nbsp;\*listener); | Registers the method for receiving events reported by the driver.|
</td> | int&nbsp;HdfDeviceSendEvent(struct&nbsp;HdfDeviceObject&nbsp;\*deviceObject,&nbsp;uint32_t&nbsp;id,&nbsp;struct&nbsp;HdfSBuf&nbsp;\*data); | Sends events. |
<td class="cellrowborder" valign="top" width="53.620000000000005%" headers="mcps1.2.3.1.2 "><p id="p58272614113"><a name="p58272614113"></a><a name="p58272614113"></a>Obtains a specified driver service. After the service is obtained, the <strong id="b9799159433"><a name="b9799159433"></a><a name="b9799159433"></a>Dispatch</strong> function of the service is used to send messages to the driver.</p>
</td>
</tr> ## How to Develop
<tr id="row578565084913"><td class="cellrowborder" valign="top" width="46.379999999999995%" headers="mcps1.2.3.1.1 "><p id="p15786185024918"><a name="p15786185024918"></a><a name="p15786185024918"></a>void HdfIoServiceRecycle(struct HdfIoService *service);</p>
</td> 1. In the driver configuration, set **policy** to **2**. For more details, see [policy](../driver/driver-hdf-servicemanage.md).
<td class="cellrowborder" valign="top" width="53.620000000000005%" headers="mcps1.2.3.1.2 "><p id="p47861750154912"><a name="p47861750154912"></a><a name="p47861750154912"></a>Releases a specified driver service.</p>
</td> ```
</tr> device_sample :: Device {
<tr id="row1382112617413"><td class="cellrowborder" valign="top" width="46.379999999999995%" headers="mcps1.2.3.1.1 "><p id="p482182611415"><a name="p482182611415"></a><a name="p482182611415"></a>int HdfDeviceRegisterEventListener(struct HdfIoService *target, struct HdfDevEventlistener *listener);</p> policy = 2;
</td> ...
<td class="cellrowborder" valign="top" width="53.620000000000005%" headers="mcps1.2.3.1.2 "><p id="p18825261412"><a name="p18825261412"></a><a name="p18825261412"></a>Receives events sent by the drivers.</p> }
</td> ```
</tr>
<tr id="row498956124019"><td class="cellrowborder" valign="top" width="46.379999999999995%" headers="mcps1.2.3.1.1 "><p id="p6412911184019"><a name="p6412911184019"></a><a name="p6412911184019"></a>int HdfDeviceSendEvent(struct HdfDeviceObject *deviceObject, uint32_t id, struct HdfSBuf *data);</p> 2. Set the driver permission. By default, the **permission** field is set to **0666**, which allows the driver to create device nodes. You can set this field based on service requirements.
</td>
<td class="cellrowborder" valign="top" width="53.620000000000005%" headers="mcps1.2.3.1.2 "><p id="p1698915634018"><a name="p1698915634018"></a><a name="p1698915634018"></a>Sends events.</p> 3. Implement the **Dispatch()** method of **IDeviceIoService**.
</td>
</tr> ```
</tbody> // Dispatch messages sent from the user-mode application.
</table> int32_t SampleDriverDispatch(struct HdfDeviceObject *device, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply)
{
## How to Develop<a name="section946912121153"></a> HDF_LOGE("sample driver lite A dispatch");
return 0;
1. Set the value of the **policy** field in the driver configuration information to **2** \(SERVICE\_POLICY\_CAPACITY, see [Driver Service Management](driver-hdf-servicemanage.md)\). }
int32_t SampleDriverBind(struct HdfDeviceObject *device)
``` {
device_sample :: Device { HDF_LOGE("test for lite os sample driver A Open!");
policy = 2; if (device == NULL) {
... HDF_LOGE("test for lite os sample driver A Open failed!");
} return -1;
``` }
static struct ISampleDriverService sampleDriverA = {
2. The **permission** field in the driver configuration information indicates the permission provided for the driver to create device nodes. The default value is **0666**. You can configure the value of this field based on the actual application scenario of the driver. .ioService.Dispatch = SampleDriverDispatch,
3. Implement the **Dispatch** function of the service base member **IDeviceIoService** during service implementation. .ServiceA = SampleDriverServiceA,
.ServiceB = SampleDriverServiceB,
``` };
// Process messages delivered by user-level applications. device->service = (struct IDeviceIoService *)(&sampleDriverA);
int32_t SampleDriverDispatch(struct HdfDeviceObject *device, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply) return 0;
{ }
HDF_LOGE("sample driver lite A dispatch"); ```
return 0;
} 4. Define the cmd type in the message processing function.
int32_t SampleDriverBind(struct HdfDeviceObject *device)
{ ```
HDF_LOGE("test for lite os sample driver A Open!"); #define SAMPLE_WRITE_READ 1 // Read and write operation 1
if (device == NULL) { ```
HDF_LOGE("test for lite os sample driver A Open failed!");
return -1; 5. Bind the driver service and the user-mode application to enable messages to be sent to the driver.
}
static struct ISampleDriverService sampleDriverA = { ```
.ioService.Dispatch = SampleDriverDispatch, int SendMsg(const char *testMsg)
.ServiceA = SampleDriverServiceA, {
.ServiceB = SampleDriverServiceB, if (testMsg == NULL) {
}; HDF_LOGE("test msg is null");
device->service = (struct IDeviceIoService *)(&sampleDriverA); return -1;
return 0; }
} struct HdfIoService *serv = HdfIoServiceBind("sample_driver");
``` if (serv == NULL) {
HDF_LOGE("fail to get service");
4. Define the CMD type in the message processing function. return -1;
}
``` struct HdfSBuf *data = HdfSBufObtainDefaultSize();
#define SAMPLE_WRITE_READ 1 // Read and write operation 1 if (data == NULL) {
``` HDF_LOGE("fail to obtain sbuf data");
return -1;
5. Enable the user-level application to obtain the service interface and send messages to the driver. }
struct HdfSBuf *reply = HdfSBufObtainDefaultSize();
``` if (reply == NULL) {
int SendMsg(const char *testMsg) HDF_LOGE("fail to obtain sbuf reply");
{ ret = HDF_DEV_ERR_NO_MEMORY;
if (testMsg == NULL) { goto out;
HDF_LOGE("test msg is null"); }
return -1; if (!HdfSbufWriteString(data, testMsg)) {
} HDF_LOGE("fail to write sbuf");
struct HdfIoService *serv = HdfIoServiceBind("sample_driver"); ret = HDF_FAILURE;
if (serv == NULL) { goto out;
HDF_LOGE("fail to get service"); }
return -1; int ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_WRITE_READ, data, reply);
} if (ret != HDF_SUCCESS) {
struct HdfSBuf *data = HdfSBufObtainDefaultSize(); HDF_LOGE("fail to send service call");
if (data == NULL) { goto out;
HDF_LOGE("fail to obtain sbuf data"); }
return -1; out:
} HdfSBufRecycle(data);
struct HdfSBuf *reply = HdfSBufObtainDefaultSize(); HdfSBufRecycle(reply);
if (reply == NULL) { HdfIoServiceRecycle(serv);
HDF_LOGE("fail to obtain sbuf reply"); return ret;
ret = HDF_DEV_ERR_NO_MEMORY; }
goto out; ```
}
if (!HdfSbufWriteString(data, testMsg)) { 6. Enable the user-mode application to receive messages from the driver.
HDF_LOGE("fail to write sbuf"); 1. Enable the driver to report events to the user-mode application.
ret = HDF_FAILURE;
goto out; ```
} static int OnDevEventReceived(void *priv, uint32_t id, struct HdfSBuf *data)
int ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_WRITE_READ, data, reply); {
if (ret != HDF_SUCCESS) { OsalTimespec time;
HDF_LOGE("fail to send service call"); OsalGetTime(&time);
goto out; HDF_LOGE("%s received event at %llu.%llu", (char *)priv, time.sec, time.usec);
}
out: const char *string = HdfSbufReadString(data);
HdfSBufRecycle(data); if (string == NULL) {
HdfSBufRecycle(reply); HDF_LOGE("fail to read string in event data");
HdfIoServiceRecycle(serv); return -1;
return ret; }
} HDF_LOGE("%s: dev event received: %d %s", (char *)priv, id, string);
``` return 0;
}
6. Enable the user-level application to receive messages reported by the driver. ```
1. Enable the user-level application to compile the function for processing messages reported by the driver. 2. Register the method for receiving the messages from the driver.
``` ```
static int OnDevEventReceived(void *priv, uint32_t id, struct HdfSBuf *data) int RegisterListen()
{ {
OsalTimespec time; struct HdfIoService *serv = HdfIoServiceBind("sample_driver");
OsalGetTime(&time); if (serv == NULL) {
HDF_LOGE("%s received event at %llu.%llu", (char *)priv, time.sec, time.usec); HDF_LOGE("fail to get service");
return -1;
const char *string = HdfSbufReadString(data); }
if (string == NULL) { static struct HdfDevEventlistener listener = {
HDF_LOGE("fail to read string in event data"); .callBack = OnDevEventReceived,
return -1; .priv ="Service0"
} };
HDF_LOGE("%s: dev event received: %d %s", (char *)priv, id, string); if (HdfDeviceRegisterEventListener(serv, &listener) != 0) {
return 0; HDF_LOGE("fail to register event listener");
} return -1;
``` }
......
2. Enable the user-level application to register the function for receiving messages reported by the driver. HdfDeviceUnregisterEventListener(serv, &listener);
HdfIoServiceRecycle(serv);
``` return 0;
int RegisterListen() }
{ ```
struct HdfIoService *serv = HdfIoServiceBind("sample_driver"); 3. Enable the driver to report events.
if (serv == NULL) {
HDF_LOGE("fail to get service"); ```
return -1; int32_t SampleDriverDispatch(struct HdfDeviceObject *device, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply)
} {
static struct HdfDevEventlistener listener = { ... // Process the API call.
.callBack = OnDevEventReceived, return HdfDeviceSendEvent(deviceObject, cmdCode, data);
.priv ="Service0" }
}; ```
if (HdfDeviceRegisterEventListener(serv, &listener) != 0) {
HDF_LOGE("fail to register event listener");
return -1;
}
......
HdfDeviceUnregisterEventListener(serv, &listener);
HdfIoServiceRecycle(serv);
return 0;
}
```
3. Enable the driver to report events.
```
int32_t SampleDriverDispatch(struct HdfDeviceObject *device, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply)
{
... // process api call here
return HdfDeviceSendEvent(deviceObject, cmdCode, data);
}
```
# HDF Overview<a name="EN-US_TOPIC_0000001051611604"></a> # HDF Overview
## Introduction<a name="section0649162112376"></a>
The Hardware Driver Foundation \(HDF\) provides the following driver framework capabilities: driver loading, driver service management, and driver message mechanism. This unified driver architecture platform is designed to provide a more precise and efficient development environment, where you can perform one-time development and multi-system deployment. ## Introduction
## Driver Loading<a name="section68701942154319"></a> The Hardware Driver Foundation (HDF) provides driver framework capabilities including driver loading, driver service management, and driver messaging mechanism. It strives to build a unified driver architecture platform to provide a more precise and efficient development environment, where you can perform one-time development for multi-device deployment.
Both on-demand loading and sequential loading are supported.
- On-demand loading ## Driver Loading
Drivers can be loaded by default during the operating system \(OS\) startup or be loaded dynamically after the OS startup. The HDF supports the following loading modes:
- Sequential loading - On-demand loading
The driver is loaded by default during the operating system (OS) boot process or dynamically loaded after OS is started.
Drivers can be loaded based on their priorities during the OS startup. - Sequential loading
The driver is loaded based on its priority during the OS boot process.
## Driver Service Management<a name="section12453133414412"></a> ## Driver Service Management
The HDF centrally manages driver services. You can directly obtain a specified driver service by using the API provided by the HDF. The HDF allows centralized management of driver services. You can obtain a driver service by using the API provided by the HDF.
## Driver Message Mechanism<a name="section129410710451"></a>
The HDF provides a unified driver message mechanism, which allows message interactions between user-level applications and kernel-level drivers. ## Driver messaging mechanism
The HDF provides a unified driver messaging mechanism, which allows messages to be exchanged between user-mode applications and kernel-mode drivers.
# HDF Development Example<a name="EN-US_TOPIC_0000001052451677"></a> # HDF Development Example
The following example shows how to add driver configuration, compile the driver code, and implement interaction between the user-state applications and the driver.
## Adding Configuration<a name="section27261067111"></a> The following is a HDF-based driver development example.
Add the driver configuration to the HDF configuration file \(for example, **vendor/hisilicon/xxx/hdf_config/device\_info**\).
Example: ## Adding Driver Configuration
Add the driver configuration to the HDF configuration file, for example, **vendor/hisilicon/xxx/hdf_config/device_info**.
``` ```
root { root {
device_info { device_info {
...@@ -44,10 +45,12 @@ root { ...@@ -44,10 +45,12 @@ root {
} }
``` ```
## Compiling the Driver Code<a name="section177988005"></a>
The following is the sample driver code compiled based on HDF (for details, see [Driver Development](driver-hdf-development.md)): ## Writing the Driver Code
Write the driver code based on the HDF. For more details, see [Driver Development](../driver/driver-hdf-development.md).
``` ```
#include <fcntl.h> #include <fcntl.h>
#include <sys/stat.h> #include <sys/stat.h>
...@@ -79,7 +82,7 @@ int32_t HdfSampleDriverDispatch( ...@@ -79,7 +82,7 @@ int32_t HdfSampleDriverDispatch(
void HdfSampleDriverRelease(struct HdfDeviceObject *deviceObject) void HdfSampleDriverRelease(struct HdfDeviceObject *deviceObject)
{ {
// Release resources here // Release resources.
return; return;
} }
...@@ -116,10 +119,12 @@ struct HdfDriverEntry g_sampleDriverEntry = { ...@@ -116,10 +119,12 @@ struct HdfDriverEntry g_sampleDriverEntry = {
HDF_INIT(g_sampleDriverEntry); HDF_INIT(g_sampleDriverEntry);
``` ```
## Compiling the Code for Interaction<a name="section6205173816412"></a>
The following is the sample code compiled based on HDF for interaction between the driver and user-state applications. You can place the code in **drivers/adapter/uhdf** for compilation. For details about the **build.gn** file, see **drivers/framework/sample/platform/uart/dev/build.gn**. ## Implementing Interaction Between the Application and the Driver
Write the code for interaction between the user-mode application and the driver. Place the code in the **drivers/adapter/uhdf** directory for compilation. For details about **build.gn**, see **drivers/framework/sample/platform/uart/dev/build.gn**.
``` ```
#include <fcntl.h> #include <fcntl.h>
#include <sys/stat.h> #include <sys/stat.h>
...@@ -227,9 +232,13 @@ int main() ...@@ -227,9 +232,13 @@ int main()
} }
``` ```
>![](../public_sys-resources/icon-note.gif) **NOTE:** > ![icon-note.gif](../public_sys-resources/icon-note.gif) **NOTE**<br/>
>The code compilation of user-state applications depends on the dynamic libraries **hdf\_core** and **osal** provided by HDF because user-state applications use the message sending interface of HDF. In the GN file, add the following dependencies: > The user-mode application uses the message sending API of the HDF, and the compilation of the user-mode application depends on the dynamic libraries **hdf_core** and **osal** provided by the HDF. Therefore, you need to add the following dependencies to the .gn file:
>deps = \[ >
>"//drivers/adapter/uhdf/manager:hdf\_core", > deps = [
>"//drivers/adapter/uhdf/posix:hdf\_posix\_osal", >
>\] > "//drivers/adapter/uhdf/manager:hdf_core",
>
> "//drivers/adapter/uhdf/posix:hdf_posix_osal",
>
> ]
# Driver Service Management<a name="EN-US_TOPIC_0000001052777057"></a> # Driver Service Management
Driver services are objects of open capabilities provided by the HDF and are managed by the HDF in a unified manner. Using driver service management, you can release and obtain driver services. Driver services are objects of capabilities provided by HDF driver devices to external systems and are managed by the HDF in a unified manner. Driver service management involves providing and obtaining driver services.
The HDF uses the **policy** field in the configuration file to define policies for drivers to release services externally. The values and meanings of this field are as follows:
The HDF uses the **policy** field in the configuration file to define policies for drivers to provide services externally. The values this field are as follows:
``` ```
typedef enum { typedef enum {
/* The driver does not provide services. */ /* The driver does not provide services. */
SERVICE_POLICY_NONE = 0, SERVICE_POLICY_NONE = 0,
/* The driver provides services for kernel-space applications. */ /* The driver provides services only for kernel-mode applications. */
SERVICE_POLICY_PUBLIC = 1, SERVICE_POLICY_PUBLIC = 1,
/* The driver provides services for both kernel- and user-space applications. */ /* The driver provides services for both kernel- and user-mode applications. */
SERVICE_POLICY_CAPACITY = 2, SERVICE_POLICY_CAPACITY = 2,
/* The driver services are not released externally but can be subscribed to. */ /** The driver services are not provided externally but can be subscribed to. */
SERVICE_POLICY_FRIENDLY = 3, SERVICE_POLICY_FRIENDLY = 3,
/* The driver services are private. They are neither released nor subscribed to. */ /* The driver private services cannot be provided externally or subscribed to. */
SERVICE_POLICY_PRIVATE = 4, SERVICE_POLICY_PRIVATE = 4,
/* The service policy is incorrect. */ /** Invalid service policy. */
SERVICE_POLICY_INVALID SERVICE_POLICY_INVALID
} ServicePolicy; } ServicePolicy;
``` ```
## When to Use<a name="section14244270117"></a>
The driver service management capability can be used if the driver provides capabilities using APIs. ## When to Use
## Available APIs<a name="section1432412561722"></a>
The table below describes the APIs used for driver service management.
**Table 1** APIs for driver service management
<a name="table8431122013592"></a>
<table><thead align="left"><tr id="row13431820135919"><th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.1"><p id="p1670132714592"><a name="p1670132714592"></a><a name="p1670132714592"></a><strong id="b12478202911367"><a name="b12478202911367"></a><a name="b12478202911367"></a>Function</strong></p>
</th>
<th class="cellrowborder" valign="top" width="50%" id="mcps1.2.3.1.2"><p id="p770172785910"><a name="p770172785910"></a><a name="p770172785910"></a><strong id="b134538148443950"><a name="b134538148443950"></a><a name="b134538148443950"></a>Description</strong></p>
</th>
</tr>
</thead>
<tbody><tr id="row1743112017594"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p18601333135911"><a name="p18601333135911"></a><a name="p18601333135911"></a>int32_t (*Bind)(struct HdfDeviceObject *deviceObject);</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p46015332591"><a name="p46015332591"></a><a name="p46015332591"></a>Binds a service interface to the HDF. You need to implement the <strong id="b876584084419"><a name="b876584084419"></a><a name="b876584084419"></a>Bind</strong> function.</p>
</td>
</tr>
<tr id="row1543212045914"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p19601163314590"><a name="p19601163314590"></a><a name="p19601163314590"></a>const struct HdfObject *DevSvcManagerClntGetService(const char *svcName);</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p1601123318598"><a name="p1601123318598"></a><a name="p1601123318598"></a>Obtains a specified driver service.</p>
</td>
</tr>
<tr id="row20432162019594"><td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.1 "><p id="p960173310590"><a name="p960173310590"></a><a name="p960173310590"></a>int HdfDeviceSubscribeService(</p>
<p id="p126021533165915"><a name="p126021533165915"></a><a name="p126021533165915"></a>struct HdfDeviceObject *deviceObject, const char *serviceName, struct SubscriberCallback callback);</p>
</td>
<td class="cellrowborder" valign="top" width="50%" headers="mcps1.2.3.1.2 "><p id="p06029334597"><a name="p06029334597"></a><a name="p06029334597"></a>Subscribes to a specified driver service.</p>
</td>
</tr>
</tbody>
</table>
## How to Develop<a name="section393515164416"></a>
The development of driver service management includes compiling, binding, obtaining, and subscribing to driver services. The details are as follows:
1. Release a driver service.
```
Define the driver service structure.
struct ISampleDriverService {
struct IDeviceIoService ioService; // The first member of the service structure must be a member of the IDeviceIoService type.
int32_t (*ServiceA)(void); // The first service interface of the driver.
int32_t (*ServiceB)(uint32_t inputCode); // The second service interface of the driver. The rest can be deduced by analogy.
};
Implementation of the driver service interface
int32_t SampleDriverServiceA(void)
{
// You need to implement the service logic.
return 0;
}
int32_t SampleDriverServiceB(uint32_t inputCode)
{
// You need to implement the service logic.
return 0;
}
```
2. Bind the driver service to the HDF and implement the **Bind** function in the **HdfDriverEntry** structure.
```
int32_t SampleDriverBind(struct HdfDeviceObject *deviceObject)
{
// deviceObject indicates the pointer to the device object created by the HDF for each driver. It is used to store device-related private data and service interfaces.
if (deviceObject == NULL) {
HDF_LOGE("Sample device object is null!");
return -1;
}
static struct ISampleDriverService sampleDriverA = {
.ServiceA = SampleDriverServiceA,
.ServiceB = SampleDriverServiceB,
};
deviceObject->service = &sampleDriverA.ioService;
return 0;
}
```
3. Obtain the driver service.
You can either use the API or subscription mechanism provided by the HDF to obtain the driver service.
- Using the API
After the driver is loaded, you can obtain the driver service using the API provided by the HDF, as shown in the following:
```
const struct ISampleDriverService *sampleService =
(const struct ISampleDriverService *)DevSvcManagerClntGetService("sample_driver");
if (sampleService == NULL) {
return -1;
}
sampleService->ServiceA();
sampleService->ServiceB(5);
```
- Using the subscription mechanism
If the kernel mode is unaware of the time for loading drivers \(on the same host\), use the subscription mechanism provided by the HDF to subscribe to the drivers. After the drivers are loaded, the HDF releases the driver services to you. The implementation is as follows:
```
// Subscription callback function. After the subscribed drivers are loaded, the HDF releases the driver services to you using this function.
// object indicates the pointer to the private data of the subscriber, and service indicates the pointer to the subscribed service.
int32_t TestDriverSubCallBack(struct HdfDeviceObject *deviceObject, const struct HdfObject *service)
{
const struct ISampleDriverService *sampleService =
(const struct ISampleDriverService *)service;
if (sampleService == NULL) {
return -1;
}
sampleService->ServiceA();
sampleService->ServiceB(5);
}
// Implement the subscription process.
int32_t TestDriverInit(struct HdfDeviceObject *deviceObject)
{
if (deviceObject == NULL) {
HDF_LOGE("Test driver init failed, deviceObject is null!");
return -1;
}
struct SubscriberCallback callBack;
callBack.deviceObject = deviceObject;
callBack.OnServiceConnected = TestDriverSubCallBack;
int32_t ret = HdfDeviceSubscribeService(deviceObject, "sample_driver", callBack);
if (ret != 0) {
HDF_LOGE("Test driver subscribe sample driver failed!");
}
return ret;
}
```
The driver service management capability can be used if the driver provides capabilities using APIs.
## Available APIs
The table below describes the APIs for driver service management.
**Table 1** APIs for driver service management
| API| Description|
| -------- | -------- |
| int32_t&nbsp;(\*Bind)(struct&nbsp;HdfDeviceObject&nbsp;\*deviceObject); | Binds a service API to the HDF. You need to implement the **Bind()** function.|
| const&nbsp;struct&nbsp;HdfObject&nbsp;\*DevSvcManagerClntGetService(const&nbsp;char&nbsp;\*svcName); | Obtains a driver service.|
| int&nbsp;HdfDeviceSubscribeService(<br>struct&nbsp;HdfDeviceObject&nbsp;\*deviceObject,&nbsp;const&nbsp;char&nbsp;\*serviceName,&nbsp;struct&nbsp;SubscriberCallback&nbsp;callback); | Subscribes to a driver service.|
## How to Develop
The development procedure is as follows:
1. Define the services to be provided by the driver.
```
Define the driver service structure.
struct ISampleDriverService {
struct IDeviceIoService ioService; // The first member must be of the IDeviceIoService type.
int32_t (*ServiceA)(void); // API of the first driver service.
int32_t (*ServiceB)(uint32_t inputCode); // API of the second driver service. You can add more as required.
};
Implement the driver service APIs.
int32_t SampleDriverServiceA(void)
{
// You need to implement the service logic.
return 0;
}
int32_t SampleDriverServiceB(uint32_t inputCode)
{
// You need to implement the service logic.
return 0;
}
```
2. Bind the driver service to the HDF and implement the **Bind()** function in the **HdfDriverEntry** structure.
```
int32_t SampleDriverBind(struct HdfDeviceObject *deviceObject)
{
// deviceObject is a pointer to the device object created by the HDF for each driver. The device object holds private device data and service APIs.
if (deviceObject == NULL) {
HDF_LOGE("Sample device object is null!");
return -1;
}
static struct ISampleDriverService sampleDriverA = {
.ServiceA = SampleDriverServiceA,
.ServiceB = SampleDriverServiceB,
};
deviceObject->service = &sampleDriverA.ioService;
return 0;
}
```
3. Obtain the driver service.
The driver service can be obtained by using the API or subscription mechanism provided by the HDF.
- Using the API
Use the API provided by the HDF to obtain the driver service if the driver has been loaded.
```
const struct ISampleDriverService *sampleService =
(const struct ISampleDriverService *)DevSvcManagerClntGetService("sample_driver");
if (sampleService == NULL) {
return -1;
}
sampleService->ServiceA();
sampleService->ServiceB(5);
```
- Using the subscription mechanism
If the kernel mode is unaware of the time for loading drivers on the same host, use the subscription mechanism provided by the HDF to subscribe to the drivers. After the drivers are loaded, the HDF sends the driver services to the subscriber. The implementation is as follows:
```
// Callback invoked to return the driver services after the subscribed driver is loaded.
// object is the pointer to the private data of the subscriber, and service is the pointer to the subscribed service object.
int32_t TestDriverSubCallBack(struct HdfDeviceObject *deviceObject, const struct HdfObject *service)
{
const struct ISampleDriverService *sampleService =
(const struct ISampleDriverService *)service;
if (sampleService == NULL) {
return -1;
}
sampleService->ServiceA();
sampleService->ServiceB(5);
}
// Implement the subscription process.
int32_t TestDriverInit(struct HdfDeviceObject *deviceObject)
{
if (deviceObject == NULL) {
HDF_LOGE("Test driver init failed, deviceObject is null!");
return -1;
}
struct SubscriberCallback callBack;
callBack.deviceObject = deviceObject;
callBack.OnServiceConnected = TestDriverSubCallBack;
int32_t ret = HdfDeviceSubscribeService(deviceObject, "sample_driver", callBack);
if (ret != 0) {
HDF_LOGE("Test driver subscribe sample driver failed!");
}
return ret;
}
```
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
This section describes how to develop the touchscreen driver based on the input driver model. [Figure 1](#fig6251184817261) shows an overall architecture of the touchscreen driver. This section describes how to develop the touchscreen driver based on the input driver model. [Figure 1](#fig6251184817261) shows an overall architecture of the touchscreen driver.
The input driver is developed based on the hardware driver foundation \(HDF\), platform APIs, and operating system abstraction layer \(OSAL\) APIs. It provides hardware driver capabilities through the input Hardware Driver Interfaces \(HDIs\) for upper-layer input services to control the touchscreen. The input driver is developed based on the hardware driver foundation \(HDF\), platform APIs, and operating system abstraction layer \(OSAL\) APIs. It provides hardware driver capabilities through the input Hardware Device Interfaces \(HDIs\) for upper-layer input services to control the touchscreen.
**Figure 1** Architecture of the input driver model<a name="fig6251184817261"></a> **Figure 1** Architecture of the input driver model<a name="fig6251184817261"></a>
...@@ -88,7 +88,7 @@ Perform the following steps: ...@@ -88,7 +88,7 @@ Perform the following steps:
1. Add the touchscreen driver-related descriptions. 1. Add the touchscreen driver-related descriptions.
Currently, the input driver is developed based on the HDF and is loaded and started by the HDF. Register the driver information, such as whether to load the driver and the loading priority in the configuration file. Then, the HDF starts the registered driver modules one by one. For details about the driver configuration, see [Driver Development](driver-hdf-development.md#section1969312275533). Currently, the input driver is developed based on the HDF and is loaded and started by the HDF. Register the driver information, such as whether to load the driver and the loading priority in the configuration file. Then, the HDF starts the registered driver modules one by one. For details about the driver configuration, see [Driver Development](driver-hdf-development.md#how-to-develop).
2. Complete the board-level configuration and private data configuration of the touchscreen. 2. Complete the board-level configuration and private data configuration of the touchscreen.
...@@ -96,7 +96,7 @@ Perform the following steps: ...@@ -96,7 +96,7 @@ Perform the following steps:
3. Implement differentiated adaptation APIs of the touchscreen. 3. Implement differentiated adaptation APIs of the touchscreen.
Use the platform APIs to perform operations for the reset pins, interrupt pins, and power based on the communications interfaces designed for boards. For details about the GPIO-related operations, see [GPIO](driver-platform-gpio-des.md#section1635911016188). Use the platform APIs to perform operations for the reset pins, interrupt pins, and power based on the communications interfaces designed for boards. For details about the GPIO-related operations, see [GPIO](driver-platform-gpio-des.md#overview).
## Development Example<a name="section263714411191"></a> ## Development Example<a name="section263714411191"></a>
......
...@@ -89,7 +89,7 @@ The ADC module adaptation involves the following steps: ...@@ -89,7 +89,7 @@ The ADC module adaptation involves the following steps:
>![](../public_sys-resources/icon-note.gif) **NOTE** >![](../public_sys-resources/icon-note.gif) **NOTE**
>For details, see [Available APIs](#availableapis). >For details, see [Available APIs](#available-apis).
4. Debug the driver. 4. Debug the driver.
......
...@@ -284,7 +284,7 @@ The DAC module adaptation procedure is as follows: ...@@ -284,7 +284,7 @@ The DAC module adaptation procedure is as follows:
``` ```
![](../public_sys-resources/icon-note.gif) **NOTE**<br/> ![](../public_sys-resources/icon-note.gif) **NOTE**<br/>
For details about **DacMethod**, see [Available APIs](#section752964871810). For details about **DacMethod**, see [Available APIs](#available-apis).
- **Init** function - **Init** function
......
...@@ -70,7 +70,7 @@ The I2C module adaptation involves the following steps: ...@@ -70,7 +70,7 @@ The I2C module adaptation involves the following steps:
>![](../public_sys-resources/icon-note.gif) **NOTE** >![](../public_sys-resources/icon-note.gif) **NOTE**
>For details, see [Available APIs](#availableapis). >For details, see [Available APIs](#available-apis).
4. Debug the driver. 4. Debug the driver.
......
...@@ -52,7 +52,7 @@ The I3C module adaptation involves the following steps: ...@@ -52,7 +52,7 @@ The I3C module adaptation involves the following steps:
3. Instantiate the I3C controller object. 3. Instantiate the I3C controller object.
- Initialize **I3cCntlr**. - Initialize **I3cCntlr**.
- Instantiate **I3cMethod** in **I3cCntlr**. For details, see [Available APIs](#Available_apis). - Instantiate **I3cMethod** in **I3cCntlr**. For details, see [Available APIs](#available-apis).
4. Register an interrupt handler. 4. Register an interrupt handler.
Register an interrupt handler for the controller to implement the device hot-join and in-band interrupt (IBI) features. Register an interrupt handler for the controller to implement the device hot-join and in-band interrupt (IBI) features.
......
...@@ -118,7 +118,7 @@ The MIPI DSI module adaptation involves the following steps: ...@@ -118,7 +118,7 @@ The MIPI DSI module adaptation involves the following steps:
>![](../public_sys-resources/icon-note.gif) **NOTE** >![](../public_sys-resources/icon-note.gif) **NOTE**
>For details, see [Available APIs](#availableapis). >For details, see [Available APIs](#available-apis).
4. Debug the driver. 4. Debug the driver.
......
...@@ -209,7 +209,7 @@ The MMC module adaptation involves the following steps: ...@@ -209,7 +209,7 @@ The MMC module adaptation involves the following steps:
>![](../public_sys-resources/icon-note.gif) **NOTE** >![](../public_sys-resources/icon-note.gif) **NOTE**
>For details, see [Available APIs](#availableapis). >For details, see [Available APIs](#available-apis).
4. Debug the driver. 4. Debug the driver.
......
...@@ -81,7 +81,7 @@ The PWM module adaptation involves the following steps: ...@@ -81,7 +81,7 @@ The PWM module adaptation involves the following steps:
>![](../public_sys-resources/icon-note.gif) **NOTE** >![](../public_sys-resources/icon-note.gif) **NOTE**
>For details, see [Available APIs](#availableapis). >For details, see [Available APIs](#available-apis).
4. Debug the driver. 4. Debug the driver.
......
...@@ -196,7 +196,7 @@ The RTC module adaptation involves the following steps: ...@@ -196,7 +196,7 @@ The RTC module adaptation involves the following steps:
>![](../public_sys-resources/icon-note.gif) **NOTE** >![](../public_sys-resources/icon-note.gif) **NOTE**
>For details, see [Available APIs](#availableapis). >For details, see [Available APIs](#available-apis).
4. Debug the driver. 4. Debug the driver.
......
...@@ -292,7 +292,7 @@ The SDIO module adaptation involves the following steps: ...@@ -292,7 +292,7 @@ The SDIO module adaptation involves the following steps:
>![](../public_sys-resources/icon-note.gif) **NOTE** >![](../public_sys-resources/icon-note.gif) **NOTE**
>For details, see [Available APIs](#availableapis). >For details, see [Available APIs](#available-apis).
4. Debug the driver. 4. Debug the driver.
......
# UART<a name="EN-US_TOPIC_0000001153656474"></a> # UART<a name="EN-US_TOPIC_0000001153656474"></a>
- [Overview](#section1761881586154520)
- [How to Develop](#section944397404154520)
- [UartHostMethod](#section192316441461)
- [Development Example](#section774610224154520)
## Overview<a name="section1761881586154520"></a> ## Overview<a name="section1761881586154520"></a>
In the Hardware Driver Foundation \(HDF\), the Universal Asynchronous Receiver/Transmitter \(UART\) uses the independent service mode for API adaptation. In this mode, each device independently publishes a device service to handle external access requests. After receiving an access request from an API, the device manager extracts the parameters in the request to call the internal method of the target device. In the independent service mode, the service management capabilities of the HDF Device Manager can be directly used. However, you need to configure a device node for each device, which increases the memory usage. In the Hardware Driver Foundation \(HDF\), the Universal Asynchronous Receiver/Transmitter \(UART\) uses the independent service mode for API adaptation. In this mode, each device independently publishes a device service to handle external access requests. After receiving an access request from an API, the device manager extracts the parameters in the request to call the internal method of the target device. In the independent service mode, the service management capabilities of the HDF Device Manager can be directly used. However, you need to configure a device node for each device, which increases the memory usage.
...@@ -186,7 +180,7 @@ The UART module adaptation involves the following steps: ...@@ -186,7 +180,7 @@ The UART module adaptation involves the following steps:
>![](../public_sys-resources/icon-note.gif) **NOTE** >![](../public_sys-resources/icon-note.gif) **NOTE**
>For details, see [Available APIs](#availableapis). >For details, see [Available APIs](#available-apis).
4. Debug the driver. 4. Debug the driver.
......
...@@ -129,7 +129,7 @@ The Watchdog module adaptation involves the following steps: ...@@ -129,7 +129,7 @@ The Watchdog module adaptation involves the following steps:
>![](../public_sys-resources/icon-note.gif) **NOTE** >![](../public_sys-resources/icon-note.gif) **NOTE**
>For details, see [Available APIs](#availableapis). >For details, see [Available APIs](#available-apis).
4. Debug the driver. 4. Debug the driver.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册