Implementing OpenHarmony HDF Platform Drivers for SoC Porting

Drivers in OpenHarmony are categorized into platform drivers and device drivers. Platform drivers handle on-SoC peripherals such as GPIO, I2C, and SPI controllers. Device drivers manage external components like LCD displays, touch panels, and WLAN modules connected to the SoC.

The HDF (Hardware Driver Foundation) framework enables cross-operating system driver compatibility. When developing HDF drivers, using only HDF-provided interfaces ensures the driver maintains portability across different systems. Platform driver definitions can be found in the source directory //drivers/hdf_core/framework/support/platform/include.

Directory Structure

Platform drivers should be created under //device/vendor_name/soc_name/drivers. The recommended organization follows this hierarchy:

device/
├── vendor_name/
│   ├── drivers/
│   │   ├── common/
│   │   ├── Kconfig
│   │   └── lite.mk
│   ├── soc_name/
│   │   ├── drivers/
│   │   │   ├── dmac/
│   │   │   ├── gpio/
│   │   │   ├── i2c/
│   │   │   ├── mipi_dsi/
│   │   │   ├── mmc/
│   │   │   ├── pwm/
│   │   │   ├── rtc/
│   │   │   ├── spi/
│   │   │   ├── uart/
│   │   │   └── watchdog/
│   ├── board_name/

Porting a platform driver involves injecting an implementation instance into the HDF driver model. The following example demonstrates GPIO driver porting.

Step 1: Implementing the GPIO Driver

Create a source file at //device/vendor_name/soc_name/drivers/gpio/soc_gpio_impl.c:

#include "gpio_core.h"

struct SocGpioController {
    struct GpioCntlr base;
    void *privateData;
};

static int32_t SocGpioBind(struct HdfDeviceObject *device)
{
    (void)device;
    return HDF_SUCCESS;
}

static int32_t SocGpioInit(struct HdfDeviceObject *device)
{
    struct SocGpioController *ctrl = GpioControllerCreate();
    if (ctrl == NULL) {
        HDF_LOGE("%s: failed to create controller", __func__);
        return HDF_FAILURE;
    }
    
    int32_t result = GpioCntlrAdd(&ctrl->base);
    if (result != HDF_SUCCESS) {
        HDF_LOGE("%s: registration failed: %d", __func__, result);
        GpioControllerDestroy(ctrl);
        return result;
    }
    device->priv = ctrl;
    return HDF_SUCCESS;
}

static void SocGpioRelease(struct HdfDeviceObject *device)
{
    struct GpioCntlr *cntlr = GpioCntlrFromDevice(device);
    if (cntlr != NULL) {
        GpioCntlrRemove(cntlr);
    }
    struct SocGpioController *ctrl = (struct SocGpioController *)device->priv;
    if (ctrl != NULL) {
        GpioControllerDestroy(ctrl);
    }
}

struct HdfDriverEntry g_socGpioEntry = {
    .moduleVersion = 1,
    .Bind = SocGpioBind,
    .Init = SocGpioInit,
    .Release = SocGpioRelease,
    .moduleName = "SOC_VENDOR_gpio",
};

HDF_INIT(g_socGpioEntry);

Step 2: Vendor Build Entry

Configure the vendor-level build entry in device/vendor_name/drivers/lite.mk:

SOC_VENDOR := $(subst $",,$(LOSCFG_DEVICE_COMPANY))
SOC_CHIP := $(subst $",,$(LOSCFG_PLATFORM))

LIB_SUBDIRS += $(LITEOSTOPDIR)/../../device/$(SOC_VENDOR)/$(SOC_CHIP)/drivers/

Step 3: SoC Driver Build Entry

Create device/vendor_name/soc_name/drivers/lite.mk:

DRIVER_ROOT := $(LITEOSTOPDIR)/../../device/$(SOC_VENDOR)/$(SOC_CHIP)/drivers/

ifeq ($(LOSCFG_DRIVERS_HDF_PLATFORM_GPIO), y)
    LITEOS_BASELIB += -lhdf_gpio
    LIB_SUBDIRS += $(DRIVER_ROOT)/gpio
endif

Step 4: GPIO Module Build Configuration

Create the module build file in the gpio directory:

include $(LITEOSTOPDIR)/config.mk
include $(LITEOSTOPDIR)/../../drivers/adapter/khdf/liteos/lite.mk

MODULE_NAME := hdf_gpio

LOCAL_CFLAGS += $(HDF_INCLUDE)
LOCAL_SRCS += soc_gpio_impl.c
LOCAL_CFLAGS += -fstack-protector-strong -Wextra -Wall -Werror -fsigned-char

include $(HDF_DRIVER)

Step 5: Device Configuration

Register the driver in the product configuration file at //vendor/vendor_name/product_name/config/device_info/device_info.hcs. Platform drivers should be placed under the platform host:

root {
    platform :: host {
        device_gpio :: device {
            device0 :: deviceNode {
                policy = 0;
                priority = 10;
                permission = 0644;
                moduleName = "SOC_VENDOR_gpio";
            }
        }
    }
}

The moduleName value must match the one defined in the driver entry structure.

Tags: OpenHarmony HDF Platform Driver gpio Driver Development

Posted on Mon, 18 May 2026 23:35:21 +0000 by alwaysinit