驱动消息机制管理

使用场景

当用户态应用和内核态驱动需要交互时,可以使用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. }
  2. 配置驱动信息中的服务设备节点权限(permission字段)是框架给驱动创建设备节点的权限,默认是0666,驱动开发者根据驱动的实际使用场景配置驱动设备节点的权限。

  3. 在服务实现过程中,实现服务基类成员IDeviceIoService中的Dispatch方法。

    1. // Dispatch是用来处理用户态发下来的消息
    2. int32_tSampleDriverDispatch(structHdfDeviceObject*device,int cmdCode,structHdfSBuf*data,structHdfSBuf*reply)
    3. {
    4. HDF_LOGE("sample driver lite A dispatch");
    5. return0;
    6. }
    7. int32_tSampleDriverBind(structHdfDeviceObject*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. staticstructISampleDriverService sampleDriverA ={
    15. .ioService.Dispatch=SampleDriverDispatch,
    16. .ServiceA=SampleDriverServiceA,
    17. .ServiceB=SampleDriverServiceB,
    18. };
    19. device->service =(structIDeviceIoService*)(&sampleDriverA);
    20. return0;
    21. }
  4. 驱动定义消息处理函数中的cmd类型。

    1. #define SAMPLE_WRITE_READ 1// 读写操作码1
  5. 用户态获取服务接口并发送消息到驱动。

    1. intSendMsg(constchar*testMsg)
    2. {
    3. if(testMsg == NULL){
    4. HDF_LOGE("test msg is null");
    5. return-1;
    6. }
    7. structHdfIoService*serv =HdfIoServiceBind("sample_driver",0);
    8. if(serv == NULL){
    9. HDF_LOGE("fail to get service");
    10. return-1;
    11. }
    12. structHdfSBuf*data =HdfSBufObtainDefaultSize();
    13. if(data == NULL){
    14. HDF_LOGE("fail to obtain sbuf data");
    15. return-1;
    16. }
    17. structHdfSBuf*reply =HdfSBufObtainDefaultSize();
    18. if(reply == NULL){
    19. HDF_LOGE("fail to obtain sbuf reply");
    20. ret = HDF_DEV_ERR_NO_MEMORY;
    21. gotoout;
    22. }
    23. if(!HdfSbufWriteString(data, testMsg)){
    24. HDF_LOGE("fail to write sbuf");
    25. ret = HDF_FAILURE;
    26. gotoout;
    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. gotoout;
    32. }
    33. out:
    34. HdfSBufRecycle(data);
    35. HdfSBufRecycle(reply);
    36. HdfIoServiceRecycle(serv);
    37. return ret;
    38. }
  6. 用户态接收该驱动上报的消息。

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

      1. staticintOnDevEventReceived(void*priv,uint32_t id,structHdfSBuf*data)
      2. {
      3. OsalTimespec time;
      4. OsalGetTime(&time);
      5. HDF_LOGE("%s received event at %llu.%llu",(char*)priv, time.sec, time.usec);
      6. constchar*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. return0;
      13. }
    2. 用户态注册接收驱动上报消息的操作方法。

      1. intRegisterListen()
      2. {
      3. structHdfIoService*serv =HdfIoServiceBind("sample_driver",0);
      4. if(serv == NULL){
      5. HDF_LOGE("fail to get service");
      6. return-1;
      7. }
      8. staticstructHdfDevEventlistener 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. return0;
      20. }
    3. 驱动上报事件。

      1. int32_tSampleDriverDispatch(structHdfDeviceObject*device,int cmdCode,structHdfSBuf*data,structHdfSBuf*reply)
      2. {
      3. ...// process api call here
      4. returnHdfDeviceSendEvent(deviceObject, cmdCode, data);
      5. }