Driver Messaging Mechanism
When to Use
The HDF messaging mechanism implements the interaction between the user-mode applications and kernel-mode drivers.
Available APIs
The messaging mechanism allows:
-
User-mode applications to send messages to drivers.
-
User-mode applications to receive events from drivers.
Table 1 APIs for the driver messaging mechanism
API | Description |
---|---|
struct HdfIoService *HdfIoServiceBind(const char *serviceName); | Obtains a driver service. The Dispatch() method in the driver service obtained sends messages to the driver. |
void HdfIoServiceRecycle(struct HdfIoService *service); | Releases a driver service. |
int HdfDeviceRegisterEventListener(struct HdfIoService *target, struct HdfDevEventlistener *listener); | Registers the method for receiving events reported by the driver. |
int HdfDeviceSendEvent(struct HdfDeviceObject *deviceObject, uint32_t id, struct HdfSBuf *data); | Sends events. |
How to Develop
-
In the driver configuration, set policy to 2. For more details, see policy.
device_sample :: Device { policy = 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.
-
Implement the Dispatch() method of IDeviceIoService.
// Dispatch messages sent from the user-mode application. 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; }
-
Define the cmd type in the message processing function.
#define SAMPLE_WRITE_READ 1 // Read and write operation 1
-
Bind the driver service and the user-mode application to enable messages to be sent to the driver.
int SendMsg(const char *testMsg) { if (testMsg == NULL) { HDF_LOGE("test msg is null"); return -1; } struct HdfIoService *serv = HdfIoServiceBind("sample_driver"); 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; }
-
Enable the user-mode application to receive messages from the driver.
-
Enable the driver to report events to the user-mode application.
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; }
-
Register the method for receiving the messages from the driver.
int RegisterListen() { struct HdfIoService *serv = HdfIoServiceBind("sample_driver"); 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; }
-
Enable the driver to report events.
int32_t SampleDriverDispatch(struct HdfDeviceObject *device, int cmdCode, struct HdfSBuf *data, struct HdfSBuf *reply) { ... // Process the API call. return HdfDeviceSendEvent(deviceObject, cmdCode, data); }
-