写点什么

OpenHarmony:如何使用 HDF 驱动控制 LED 灯

  • 2023-09-08
    福建
  • 本文字数:4020 字

    阅读完需:约 13 分钟

OpenHarmony:如何使用HDF驱动控制LED灯

一、程序简介

该程序是基于 OpenHarmony 标准系统编写的基础外设类:RGB LED。

目前已在凌蒙派-RK3568 开发板跑通。详细资料请参考官网:https://gitee.com/Lockzhiner-Electronics/lockzhiner-rk3568-openharmony/tree/master/samples/b02_hdf_rgb_led

详细资料请参考 OpenHarmony 官网:

  • GPIO 平台驱动开发

  • GPIO 应用程序开发

二、硬件设计

RGB LED 灯整体硬件电路如下图所示,硬件电路中包含了三个 GPIO 控制管脚控制 RGB LED 灯,低电平点亮 LED 灯,高电平熄灭 LED 灯。电路简单,这边不对此进行多余的说明。


三、程序解析

1、目录结构

b02_hdf_rgb_led├── config              # HDF资源配置文件目录    ├── config.hcs      # 接口IO配置文件    ├── device_info.hcs # 设备信息配置文件├── drivers             # 内核HDF驱动程序目录    ├── rgb_led_drv.c   # 内核HDF驱动程序    ├── Makefile        # 内核HDF驱动编译脚本├── figures             # MD文档图片├── BUILD.gn            # GN文件├── rgb_led.c           # 应用层控制程序
复制代码

2、内核 HDF 驱动程序

(1)接口函数

  • 函数名:HdfRgbLedDriverInit.

  • 功能说明:HDF 初始化注册,读取 HDF 资源配置文件,获取三色灯控制 GPIO 管脚。

int32_t HdfRgbLedDriverInit(struct HdfDeviceObject *deviceObject){    if (deviceObject == NULL) {        HDF_LOGE("g_rgbLedDriverEntry: %s failed", __func__);        return HDF_ERR_INVALID_OBJECT;    }    struct DeviceResourceIface *CfgOps = NULL;    CfgOps = DeviceResourceGetIfaceInstance(HDF_CONFIG_SOURCE);    if (CfgOps == NULL || CfgOps->GetUint32 == NULL) {        HDF_LOGE("%s: DeviceResourceGetIfaceInstance failed", __func__);        return HDF_FAILURE;    }    if (CfgOps->GetUint32(deviceObject->property, "rgb_led_version", &g_rgbLedCfg.rgb_led_version, 0) != HDF_SUCCESS) {        HDF_LOGE("%s: read rgb_led_version failed", __func__);        return HDF_FAILURE;    }    if (CfgOps->GetUint32(deviceObject->property, "rgb_led_red", &g_rgbLedCfg.rgb_led_red, 0) != HDF_SUCCESS) {        g_rgbLedCfg.rgb_led_version = 0;        HDF_LOGE("%s: read rgb_led_red failed", __func__);        return HDF_FAILURE;    }    if (CfgOps->GetUint32(deviceObject->property, "rgb_led_green", &g_rgbLedCfg.rgb_led_green, 0) != HDF_SUCCESS) {        g_rgbLedCfg.rgb_led_version = 0;        HDF_LOGE("%s: read rgb_led_green failed", __func__);        return HDF_FAILURE;    }    if (CfgOps->GetUint32(deviceObject->property, "rgb_led_blue", &g_rgbLedCfg.rgb_led_blue, 0) != HDF_SUCCESS) {        g_rgbLedCfg.rgb_led_version = 0;        HDF_LOGE("%s: read rgb_led_blue failed", __func__);        return HDF_FAILURE;    }    HDF_LOGI("g_rgbLedDriverEntry: %s success", __func__);    return HDF_SUCCESS;}
复制代码
  • 函数名:HdfRgbLedDriverRelease。

  • 功能说明:HDF 去注册。

void HdfRgbLedDriverRelease(struct HdfDeviceObject *deviceObject){    if (deviceObject == NULL) {        HDF_LOGE("g_rgbLedDriverEntry: %s failed", __func__);        return;    }    HDF_LOGI("g_rgbLedDriverEntry: %s success", __func__);    return;}
复制代码
  • 函数名:HdfRgbLedDriverBind。

  • 功能说明:HDF 绑定解析函数。

int32_t HdfRgbLedDriverBind(struct HdfDeviceObject *deviceObject){    if (deviceObject == NULL) {        HDF_LOGE("g_rgbLedDriverEntry: %s failed", __func__);        return HDF_ERR_INVALID_OBJECT;    }    static struct IDeviceIoService ledDriverServ = {        .Dispatch = rgbLedDriverDispatch,    };    deviceObject->service = (struct IDeviceIoService *)(&ledDriverServ);    HDF_LOGI("g_rgbLedDriverEntry: %s success NodeName[%s]", __func__,        deviceObject->property->name);    return HDF_SUCCESS;}
复制代码
  • 函数名:rgbLedDriverDispatch。

  • 功能说明:解析函数,解析应用层下发的命令,执行命令对应操作,RGB_LED_WRITE 控制三色灯亮灭。

int32_t rgbLedDriverDispatch(struct HdfDeviceIoClient *client, int32_t cmdId,    struct HdfSBuf *dataBuf, struct HdfSBuf *replyBuf){    int32_t result = HDF_FAILURE;    int32_t rgbLedMode = 0;
if (client == NULL || client->device == NULL) { HDF_LOGE("driver device is NULL"); return HDF_ERR_INVALID_OBJECT; } if (g_rgbLedCfg.rgb_led_version != RGB_LED_VERSION) { HDF_LOGE("driver rgb_led_version not match"); return HDF_FAILURE; } switch (cmdId) { case RGB_LED_WRITE: result = HdfSbufReadInt32(dataBuf, &rgbLedMode); if (result) { HDF_LOGI("%s: mode:[0x%X][%s%s%s]", __func__, rgbLedMode, (rgbLedMode&RGB_LED_RED_BIT)?"R":"-", (rgbLedMode&RGB_LED_GREEN_BIT)?"G":"-", (rgbLedMode&RGB_LED_BLUE_BIT)?"B":"-");
LedGpioCtrl(g_rgbLedCfg.rgb_led_red, (rgbLedMode&RGB_LED_RED_BIT)?LED_ON:LED_OFF); LedGpioCtrl(g_rgbLedCfg.rgb_led_green, (rgbLedMode&RGB_LED_GREEN_BIT)?LED_ON:LED_OFF); LedGpioCtrl(g_rgbLedCfg.rgb_led_blue, (rgbLedMode&RGB_LED_BLUE_BIT)?LED_ON:LED_OFF); } break; default: HDF_LOGE("%s: receiving unknown command", __func__); break; } return result;}
复制代码
  • 函数名:LedGpioCtrl。

  • 功能说明:LED GPIO 控制函数,低电平点亮 LED,高电平熄灭 LED。

static int32_t LedGpioCtrl(uint16_t gpio, int32_t mode){    uint16_t level = GPIO_VAL_HIGH;
if (HDF_SUCCESS != GpioSetDir(gpio, GPIO_DIR_OUT)) { HDF_LOGE("%s: GpioSetDir failed", __func__); return HDF_FAILURE; }
if (mode == LED_ON) { level = GPIO_VAL_LOW; } else if (mode == LED_OFF) { level = GPIO_VAL_HIGH; }
if (HDF_SUCCESS != GpioWrite(gpio, level)) { HDF_LOGE("%s: GpioWrite failed", __func__); return HDF_FAILURE; } return HDF_SUCCESS;}
复制代码

3、应用层程序

(1)应用层代码分析

程序启动后获取命令行参数,如果命令行不带参数,RGB 三色灯运行跑马灯;如果命令行带参数,根据传入的参数的低三位映射点亮对应的红灯、绿灯和蓝灯;通过 HdfIoServiceBind 绑定 RGB 三色灯 HDF 服务,获取 HDF 空间缓冲区,向缓冲区写入需要控制的 RGB 三色灯低三位数据,通过 RGB_LED_WRITE 命令下发到 HDF 驱动中,从而控制 RGB 三色灯亮灭。程序运行结束,回收 HDF 空间缓冲区和 HDF 服务。

int main(int argc, char* argv[]){    int ret = HDF_SUCCESS;    int32_t mode = -1;    if (argc == ARGS_NUM) {        mode = atoi(argv[1]);        /*low-3bits*/        mode &= 0x7;        HILOG_INFO(LOG_APP, "[%s] main enter: mode[%s%s%s][0x%X]",            LOG_TAG,            (mode&RGB_LED_BLUE_BIT)?"B":"-",            (mode&RGB_LED_GREEN_BIT)?"G":"-",            (mode&RGB_LED_RED_BIT)?"R":"-",            mode);        printf("RGB mode[%s%s%s][0x%X]\n",            (mode&RGB_LED_BLUE_BIT)?"B":"-",            (mode&RGB_LED_GREEN_BIT)?"G":"-",            (mode&RGB_LED_RED_BIT)?"R":"-",            mode);    } else {        HILOG_INFO(LOG_APP, "[%s] main enter: auto test RGB LED", LOG_TAG);        printf("auto test RGB LED\n");    }
struct HdfIoService *serv = HdfIoServiceBind(RGB_LED_SERVICE_NAME); if (serv == NULL) { HILOG_ERROR(LOG_APP, "get service %s failed", RGB_LED_SERVICE_NAME); return -1; } struct HdfSBuf *data = HdfSbufObtainDefaultSize(); if (data == NULL) { HILOG_ERROR(LOG_APP, "obtain data failed"); return -1; }
if (mode == -1) { mode = 0x8; while (mode) { HdfSbufFlush(data); if (!HdfSbufWriteInt32(data, --mode)) { HILOG_ERROR(LOG_APP, "write data failed"); return -1; } ret = serv->dispatcher->Dispatch(&serv->object, RGB_LED_WRITE, data, NULL); sleep(1); } } else { if (!HdfSbufWriteInt32(data, mode)) { HILOG_ERROR(LOG_APP, "write data failed"); return -1; } ret = serv->dispatcher->Dispatch(&serv->object, RGB_LED_WRITE, data, NULL); }
HdfSbufRecycle(data); HdfIoServiceRecycle(serv); HILOG_INFO(LOG_APP, "[%s] main exit.", LOG_TAG);
return ret;}
复制代码

四、运行程序

系统启动后,命令行运行命令:

rgb_led
复制代码

五、运行结果

运行结果:

# rgb_ledauto test RGB LED
# rgb_led 1RGB mode[--R][0x1]# rgb_led 2RGB mode[-G-][0x2]# rgb_led 3RGB mode[-GR][0x3]# rgb_led 4RGB mode[B--][0x4]# rgb_led 5RGB mode[B-R][0x5]# rgb_led 6RGB mode[BG-][0x6]# rgb_led 7RGB mode[BGR][0x7]
复制代码


发布于: 刚刚阅读数: 4
用户头像

还未添加个人签名 2023-06-19 加入

还未添加个人简介

评论

发布
暂无评论
OpenHarmony:如何使用HDF驱动控制LED灯_HDF_互联网工科生_InfoQ写作社区