驱动消息机制管理

使用场景

当用户态应用和内核态驱动需要交互时,可以使用HDF框架的消息机制来实现。

接口说明

消息机制的功能主要有以下两种:

  1. 用户态应用发送消息到驱动。
  2. 用户态应用接收驱动主动上报事件。

表 1 消息机制接口

方法 描述
struct HdfIoService HdfIoServiceBind(const char serviceName, mode_t permission) 用户态获取驱动的服务,获取该服务之后通过服务中的Dispatch方法向驱动发送消息。
void HdfIoServiceRecycle(struct HdfIoService service); 释放驱动服务。
int HdfDeviceRegisterEventListener(struct HdfIoService target, struct HdfDevEventlistener listener); 用户态程序注册接收驱动上报事件的操作方法。
int HdfDeviceSendEvent(struct HdfDeviceObject deviceObject, uint32_t id, struct HdfSBuf *data); 驱动主动上报事件接口。

开发步骤

  1. 将驱动配置信息中服务策略policy字段设置为2(SERVICE_POLICY_CAPACITY,参考policy定义)。

```

  1. device_sample :: Device {
  2. policy = 2;
  3. ...
  4. } ```
  5. 配置驱动信息中的服务设备节点权限(permission字段)是框架给驱动创建设备节点的权限,默认是0666,驱动开发者根据驱动的实际使用场景配置驱动设备节点的权限。
  6. 在服务实现过程中,实现服务基类成员IDeviceIoService中的Dispatch方法。

```

  1. // Dispatch是用来处理用户态发下来的消息
  2. int32_t SampleDriverDispatch(struct HdfDeviceObject device, int cmdCode, struct HdfSBuf data, struct HdfSBuf *reply)
  3. {
  4. HDF_LOGE("sample driver lite A dispatch");
  5. return 0;
  6. }
  7. int32_t SampleDriverBind(struct HdfDeviceObject *device)
  8. {
  9. HDF_LOGE("test for lite os sample driver A Open!");
  10. if (device == NULL) {
  11. HDF_LOGE("test for lite os sample driver A Open failed!");
  12. return -1;
  13. }
  14. static struct ISampleDriverService sampleDriverA = {
  15. .ioService.Dispatch = SampleDriverDispatch,
  16. .ServiceA = SampleDriverServiceA,
  17. .ServiceB = SampleDriverServiceB,
  18. };
  19. device->service = (struct IDeviceIoService *)(&sampleDriverA);
  20. return 0;
  21. } ```
  22. 驱动定义消息处理函数中的cmd类型。

```

  1. define SAMPLE_WRITE_READ 1 // 读写操作码1

    ```
  2. 用户态获取服务接口并发送消息到驱动。

```

  1. int SendMsg(const char *testMsg)
  2. {
  3. if (testMsg == NULL) {
  4. HDF_LOGE("test msg is null");
  5. return -1;
  6. }
  7. struct HdfIoService *serv = HdfIoServiceBind("sample_driver", 0);
  8. if (serv == NULL) {
  9. HDF_LOGE("fail to get service");
  10. return -1;
  11. }
  12. struct HdfSBuf *data = HdfSBufObtainDefaultSize();
  13. if (data == NULL) {
  14. HDF_LOGE("fail to obtain sbuf data");
  15. return -1;
  16. }
  17. struct HdfSBuf *reply = HdfSBufObtainDefaultSize();
  18. if (reply == NULL) {
  19. HDF_LOGE("fail to obtain sbuf reply");
  20. ret = HDF_DEV_ERR_NO_MEMORY;
  21. goto out;
  22. }
  23. if (!HdfSbufWriteString(data, testMsg)) {
  24. HDF_LOGE("fail to write sbuf");
  25. ret = HDF_FAILURE;
  26. goto out;
  27. }
  28. int ret = serv->dispatcher->Dispatch(&serv->object, SAMPLE_WRITE_READ, data, reply);
  29. if (ret != HDF_SUCCESS) {
  30. HDF_LOGE("fail to send service call");
  31. goto out;
  32. }
  33. out:
  34. HdfSBufRecycle(data);
  35. HdfSBufRecycle(reply);
  36. HdfIoServiceRecycle(serv);
  37. return ret;
  38. } ```
  39. 用户态接收该驱动上报的消息。

  40. 用户态编写驱动上报消息的处理函数。

    ```

    1. static int OnDevEventReceived(void priv, uint32_t id, struct HdfSBuf data)
    2. {
    3. OsalTimespec time;
    4. OsalGetTime(&time);
    5. HDF_LOGE("%s received event at %llu.%llu", (char *)priv, time.sec, time.usec);

    6. const char *string = HdfSbufReadString(data);

    7. if (string == NULL) {
    8. HDF_LOGE("fail to read string in event data");
    9. return -1;
    10. }
    11. HDF_LOGE("%s: dev event received: %d %s", (char *)priv, id, string);
    12. return 0;
    13. } ```
    14. 用户态注册接收驱动上报消息的操作方法。

    ```

    1. int RegisterListen()
    2. {
    3. struct HdfIoService *serv = HdfIoServiceBind("sample_driver", 0);
    4. if (serv == NULL) {
    5. HDF_LOGE("fail to get service");
    6. return -1;
    7. }
    8. static struct HdfDevEventlistener listener = {
    9. .callBack = OnDevEventReceived,
    10. .priv ="Service0"
    11. };
    12. if (HdfDeviceRegisterEventListener(serv, &listener) != 0) {
    13. HDF_LOGE("fail to register event listener");
    14. return -1;
    15. }
    16. ......
    17. HdfDeviceUnregisterEventListener(serv, &listener);
    18. HdfIoServiceRecycle(serv);
    19. return 0;
    20. } ```
    21. 驱动上报事件。

    ```

    1. int32_t SampleDriverDispatch(struct HdfDeviceObject device, int cmdCode, struct HdfSBuf data, struct HdfSBuf *reply)
    2. {
    3. ... // process api call here
    4. return HdfDeviceSendEvent(deviceObject, cmdCode, data);
    5. } ```