driver-hdf-news.md 8.4 KB
Newer Older
W
wenjun 已提交
1 2
# Driver Message Mechanism Management<a name="EN-US_TOPIC_0000001052657065"></a>

N
NEEN 已提交
3 4 5 6
-   [When to Use](#section33014541954)
-   [Available APIs](#section538852311616)
-   [How to Develop](#section946912121153)

W
wenjun 已提交
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
## When to Use<a name="section33014541954"></a>

When user-level applications need to interact with kernel-level drivers, the driver message mechanism of the HDF can be used.

## Available APIs<a name="section538852311616"></a>

The message mechanism provides the following features:

1.  User-level applications send messages to drivers.
2.  User-level applications receive events sent by the drivers.

**Table  1**  APIs for the driver message mechanism

<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>
</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>
</th>
</tr>
</thead>
Y
yuanbo 已提交
27
<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>
W
wenjun 已提交
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
</td>
<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>
<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>
<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>
<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>
</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>
</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>
</td>
</tr>
</tbody>
</table>

## How to Develop<a name="section946912121153"></a>

D
duangavin123 已提交
52
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)\).
W
wenjun 已提交
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102

    ```
    device_sample :: Device {
        policy = 2;
        ...
    }
    ```

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.
3.  Implement the  **Dispatch**  function of the service base member  **IDeviceIoService**  during service implementation.

    ```
    // Process messages delivered by user-level applications.
    int32_t SampleDriverDispatch(struct HdfDeviceObject *device, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply)
    {
        HDF_LOGE("sample driver lite A dispatch");
        return 0;
    }
    int32_t SampleDriverBind(struct HdfDeviceObject *device)
    {
        HDF_LOGE("test for lite os sample driver A Open!");
        if (device == NULL) {
            HDF_LOGE("test for lite os sample driver A Open failed!");
            return -1;
        }
        static struct ISampleDriverService sampleDriverA = {
            .ioService.Dispatch = SampleDriverDispatch,
            .ServiceA = SampleDriverServiceA,
            .ServiceB = SampleDriverServiceB,
        };
        device->service = (struct IDeviceIoService *)(&sampleDriverA);
        return 0;
    }
    ```

4.  Define the CMD type in the message processing function.

    ```
    #define SAMPLE_WRITE_READ 1    // Read and write operation 1
    ```

5.  Enable the user-level application to obtain the service interface and send messages to the driver.

    ```
    int SendMsg(const char *testMsg)
    {
        if (testMsg == NULL) {
            HDF_LOGE("test msg is null");
            return -1;
        }
Y
yuanbo 已提交
103
        struct HdfIoService *serv = HdfIoServiceBind("sample_driver");
W
wenjun 已提交
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
        if (serv == NULL) {
            HDF_LOGE("fail to get service");
            return -1;
        }
        struct HdfSBuf *data = HdfSBufObtainDefaultSize();
        if (data == NULL) {
            HDF_LOGE("fail to obtain sbuf data");
            return -1;
        }
        struct HdfSBuf *reply = HdfSBufObtainDefaultSize();
        if (reply == NULL) {
            HDF_LOGE("fail to obtain sbuf reply");
            ret = HDF_DEV_ERR_NO_MEMORY;
            goto out;
        }
        if (!HdfSbufWriteString(data, testMsg)) {
            HDF_LOGE("fail to write sbuf");
            ret = HDF_FAILURE;
            goto out;
        }
        int ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_WRITE_READ, data, reply);
        if (ret != HDF_SUCCESS) {
            HDF_LOGE("fail to send service call");
            goto out;
        }
    out:
        HdfSBufRecycle(data);
        HdfSBufRecycle(reply);
        HdfIoServiceRecycle(serv);
        return ret;
    }
    ```

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.

        ```
        static int OnDevEventReceived(void *priv,  uint32_t id, struct HdfSBuf *data)
        {
            OsalTimespec time;
            OsalGetTime(&time);
            HDF_LOGE("%s received event at %llu.%llu", (char *)priv, time.sec, time.usec);
        
            const char *string = HdfSbufReadString(data);
            if (string == NULL) {
                HDF_LOGE("fail to read string in event data");
                return -1;
            }
            HDF_LOGE("%s: dev event received: %d %s",  (char *)priv, id, string);
            return 0;
        }
        ```

    2.  Enable the user-level application to register the function for receiving messages reported by the driver.

        ```
        int RegisterListen()
        {
Y
yuanbo 已提交
162
            struct HdfIoService *serv = HdfIoServiceBind("sample_driver");
W
wenjun 已提交
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
            if (serv == NULL) {
                HDF_LOGE("fail to get service");
                return -1;
            }
            static struct HdfDevEventlistener listener = {
                .callBack = OnDevEventReceived,
                .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);
        }
        ```