1、程序简介该程序是基于OpenHarmony标准系统编写的基础外设类:RGB LED。
详细资料请参考OpenHarmony官网:
2、硬件设计RGB LED灯整体硬件电路如下图所示,硬件电路中包含了三个GPIO控制管脚控制RGB LED灯,低电平点亮LED灯,高电平熄灭LED灯。电路简单,这边不对此进行多余的说明。
3、程序解析
3.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 # 应用层控制程序
复制代码 3.2 内核HDF驱动程序
3.2.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.3 应用层程序
3.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;
- }
复制代码 4、运行程序
系统启动后,命令行运行命令:
5、运行结果
运行结果:
- # rgb_led
- auto test RGB LED
- # rgb_led 1
- RGB mode[--R][0x1]
- # rgb_led 2
- RGB mode[-G-][0x2]
- # rgb_led 3
- RGB mode[-GR][0x3]
- # rgb_led 4
- RGB mode[B--][0x4]
- # rgb_led 5
- RGB mode[B-R][0x5]
- # rgb_led 6
- RGB mode[BG-][0x6]
- # rgb_led 7
- RGB mode[BGR][0x7]
复制代码