root {
            platform {
                hdmi_config {
                    template hdmi_controller {     // 模板公共参数,继承该模板的节点如果使用模板中的默认值,则节点字段可以缺省。
                        match_attr = "";           //【必要】需要和device_info.hcs中的deviceMatchAttr值一致。
                        index = 0;                 //【必要】hdmi控制器编号
                        regBasePhy = 0x10100000;   //【必要】寄存器物理基地址
                        regSize = 0xd1;            //【必要】寄存器位宽
                        irqNum = 100;              //【必要】中断号
                        maxTmdsClock = 300;
                        videoTiming = 10;
                        quantization = 1;
                        colorSpace = 0;
                        colorimetry = 0;
                        audioIfType = 0;
                        audioBitDepth = 1;
                        audioSampleRate = 2;
                        audioChannels = 1;
                        hdrColorimetry = 4;
                        hdrUserMode = 1;
                        cap = 0xd001e045;
                    }
                    controller_0x10100000 :: hdmi_controller {
                        match_attr = "adapter_hdmi_driver";
                        index = 0;
                        regBasePhy = 0x10100000;
                        irqNum = 100;
                        maxTmdsClock = 400;
                        defTmdsClock = 300;
                        maxFrlRate = 600;
                        videoTiming = 10;
                        quantization = 1;
                        colorSpace = 0;
                        colorimetry = 0;
                        audioIfType = 0;
                        audioSampleRate = 2;
                        audioChannels = 1;
                        hdrColorimetry = 4;
                        hdrUserMode = 1;
                        cap = 0xd001e045;
                    }
                }
            }
        }
        c
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
class="hide-preCode-box">

需要注意的是,新增hdmi_config.hcs配置文件后,必须在对应的hdf.hcs文件中包含hdmi_config.hcs所在路径信息,否则配置文件无法生效。

  1. 实例化HDMI控制器对象

最后一步,完成驱动入口注册之后,要以核心层HdmiCntlr对象的初始化为核心,包括厂商自定义结构体(传递参数和数据),实例化HdmiCntlr成员HdmiCntlrOps(让用户可以通过接口来调用驱动底层函数),实现HdfDriverEntry成员函数(Bind,Init,Release)。

说明:
从驱动角度看,自定义结构体是参数和数据的载体。HDF会读取hdmi_config.hcs文件中的数值并通过DeviceResourceIface来初始化结构体成员,且其中一些重要数值(例如设备号、总线号等)也会被传递给核心层HdmiCntlr对象。

        struct HdmiAdapterHost {
            struct HdmiCntlr *cntlr;        //【必要】是核心层控制对象,具体描述如下。
            volatile unsigned char *regBase;//【必要】寄存器基地址
            uint32_t regBasePhy;            //【必要】寄存器物理基地址
            uint32_t regSize;               //【必要】寄存器位宽
            uint32_t irqNum;                //【必要】中断号
        };

        struct HdmiCntlr {
            struct IDeviceIoService service;
            struct HdfDeviceObject *hdfDevObj;
            struct PlatformDevice device;
            struct OsalMutex mutex;
            struct PlatformQueue *msgQueue;
            struct HdmiCntlrCap cap;
            struct HdmiAttr attr;
            struct HdmiCntlrOps *ops;
            uint32_t deviceIndex;
            uint32_t state;                 // 控制器状态
            enum HdmiTmdsModeType tmdsMode;
            struct HdmiDevice *hdmi;
            struct HdmiInfoframe infoframe;
            struct HdmiScdc *scdc;
            struct HdmiDdc ddc;
            struct HdmiFrl *frl;
            struct HdmiHdcp *hdcp;
            struct HdmiCec *cec;
            struct HdmiEvent event;
            struct HdmiHdr *hdr;
            void *priv;
        };
        c
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"> class="hide-preCode-box">
        static struct HdmiCntlrOps g_hdmiAdapterHostOps = {
            .hardWareInit = HdmiAdapterHardWareInit,
            .hardWareStatusGet = HdmiAdapterHardWareStatusGet,
            .controllerReset = HdmiAdapterControllerReset,
            .hotPlugStateGet = HdmiAdapterHotPlugStateGet,
            .hotPlugInterruptStateGet = HdmiAdapterHotPlugInterruptStateGet,
            .lowPowerSet = HdmiAdapterLowPowerSet,
            .tmdsModeSet = HdmiAdapterTmdsModeSet,
            .tmdsConfigSet = HdmiAdapterTmdsConfigSet,
            .infoframeEnable = HdmiAdapterInfoframeEnable,
            .infoframeSend = HdmiAdapterInfoframeSend,
            .infoframeDataSet = HdmiAdapterInfoframeDataSet,
            .cecMsgSend = HdmiAdapterCecMsgSend,
            .audioPathEnable = HdmiAdapterAudioPathEnable,
            .audioPathSet = HdmiAdapterAudioPathSet,
            .phyOutputEnable = HdmiAdapterPhyOutputEnable,
            .phyOutputSet = HdmiAdapterPhyOutputSet,
            .blackDataSet = HdmiAdapterBlackDataSet,
            .videoMuteEnable = HdmiAdapterVideoMuteEnable,
            .videoPathSet = HdmiAdapterVideoPathSet,
            .audioMuteEnable = HdmiAdapterAudioMuteEnable,
            .avmuteSet = HdmiAdapterAvmuteSet,
            .ddcTransfer = HdmiAdapterDdcTransfer,
            .scdcSourceScrambleGet = HdmiAdapterScdcSourceScrambleGet,
            .scdcSourceScrambleSet = HdmiAdapterScdcSourceScrambleSet,
            .frlSet = HdmiAdapterFrlSet,
            .frlEnable = HdmiAdapterFrlEnable,
            .audioNctsSet = HdmiAdapterAudioNctsSet,
            .frlTrainingConfigSet = HdmiAdapterFrlTrainingConfigSet,
            .frlTrainingStart = HdmiAdapterFrlTrainingStart,
            .frlGetTriningRslt = HdmiAdapterFrlGetTriningRslt,
            .hdcpRegInit = HdmiAdapterHdcpRegInit,
            .hdcpGenerateAksvAndAn = HdmiAdapterHdcpGenerateAksvAndAn,
            .hdcpOptReg = HdmiAdapterHdcpOptReg,
            .hdrTimerSet = HdmiAdapterHdrTimerSet,
        };
        c
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"> class="hide-preCode-box">

入参:

HdfDeviceObject是整个驱动对外呈现的接口参数,具备HCS配置文件的信息。

返回值:

HDF_STATUS相关状态 (表2为部分展示,如需使用其他状态,可参考//drivers/hdf_core/interfaces/inner_api/utils/hdf_base.h中HDF_STATUS的定义)。

表 2 HDF_STATUS相关状态说明

class="table-box">
状态(值)问题描述
HDF_ERR_INVALID_OBJECT控制器对象非法
HDF_ERR_MALLOC_FAIL内存分配失败
HDF_ERR_IOI/O 错误
HDF_SUCCESS初始化成功
HDF_FAILURE初始化失败

函数说明:

初始化自定义结构体对象HdmiAdapterHost,初始化HdmiCntlr成员,调用核心层HdmiCntlrAdd函数。

HdmiCntlr,HdmiAdapterHost,HdfDeviceObject之间互相赋值,方便其他函数可以相互转化。

        static int32_t HdmiAdapterBind(struct HdfDeviceObject *obj)
        {
            struct HdmiCntlr *cntlr = NULL;
            struct HimciAdapterHost *host = NULL;
            int32_t ret;
            cntlr = (struct HdmiCntlr *)OsalMemCalloc(sizeof(struct HdmiCntlr));
            if (cntlr == NULL) {
                HDF_LOGE("%s: malloc cntlr failed!", __func__);
                return HDF_ERR_MALLOC_FAIL;
            }
            host = (struct HimciAdapterHost *)OsalMemCalloc(sizeof(struct HimciAdapterHost));
            if (host == NULL) {
                HDF_LOGE("%s: malloc host failed!", __func__);
                return HDF_ERR_MALLOC_FAIL;
            }
            cntlr->priv = (void *)host;              //【必要】将host存放至cntlr的私有数据
            cntlr->ops = &g_hdmiHostOps;             //【必要】HdmiCntlrOps的实例化对象的挂载
            cntlr->hdfDevObj = obj;                  //【必要】使HdfDeviceObject与HdmiCntlr可以相互转化的前提
            obj->service = &cntlr->service;          //【必要】使HdfDeviceObject与HdmiCntlr可以相互转化的前提
            ret = HdmiAdapterCntlrParse(cntlr, obj); //【必要】初始化cntlr,失败则goto __ERR。
            ...... 
            ret = HdmiAdapterHostParse(host, obj);   //【必要】初始化host对象的相关属性,失败则goto __ERR。
            ......
            ret = HdmiAdapterHostInit(host, cntlr);  // 厂商自定义的初始化,失败则goto __ERR。
            ......
            ret = HdmiCntlrAdd(cntlr);               // 调用核心层函数,失败则goto __ERR。
            ......
            HDF_LOGD("HdmiAdapterBind: success.");
            return HDF_SUCCESS;
        __ERR:
            HdmiAdapterDeleteHost(host);
            HDF_LOGD("HdmiAdapterBind: fail, err = %d.", ret);
            return ret;
        }
        c
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}"> class="hide-preCode-box">

入参:

HdfDeviceObject是整个驱动对外暴露的接口参数,具备HCS配置文件的信息。

返回值:

HDF_STATUS相关状态。

函数说明

实现HdmiAdapterInit函数。

        static int32_t HdmiAdapterInit(struct HdfDeviceObject *obj)
        {
            return HDF_SUCCESS;
        }
        c
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

入参:

HdfDeviceObject是整个驱动对外暴露的接口参数,具备HCS配置文件的信息。

返回值:

函数说明:

释放内存和删除控制器,该函数需要在驱动入口结构体中赋值给Release接口,当HDF框架调用Init函数初始化驱动失败时,可以调用Release释放驱动资源。

说明:
所有强制转换获取相应对象的操作前提是在Init函数中具备对应赋值的操作。

        static void HdmiAdapterRelease(struct HdfDeviceObject *obj)
        {
            struct HdmiCntlr *cntlr = NULL;
            ......
            cntlr = (struct HdmiCntlr *)obj->service;               // 这里有HdfDeviceObject到HdmiCntlr的强制转化,通过service成员,赋值见Bind函数。
            ......
            HimciDeleteHost((struct HimciAdapterHost *)cntlr->priv);// 厂商自定义的内存释放函数,这里有HdmiCntlr到HimciAdapterHost的强制转化。
        }
        c
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">
  1. 驱动调试

【可选】针对新增驱动程序,建议验证驱动基本功能,例如挂载后的信息反馈,HDMI传输等。

如果大家想更加深入的学习 OpenHarmony(鸿蒙南向) 开发的全栈内容,不妨可以参考以下相关学习文档进行学习,助你快速提升自己:

OpenHarmony 开发环境搭建:https://qr18.cn/CgxrRy

《OpenHarmony源码解析》:https://qr18.cn/CgxrRy

系统架构分析:https://qr18.cn/CgxrRy

OpenHarmony 设备开发学习手册:https://qr18.cn/CgxrRy

在这里插入图片描述

OpenHarmony面试题(内含参考答案):https://qr18.cn/CgxrRy

写在最后

data-report-view="{"mod":"1585297308_001","spm":"1001.2101.3001.6548","dest":"https://blog.csdn.net/maniuT/article/details/140994941","extend1":"pc","ab":"new"}">> id="blogExtensionBox" style="width:400px;margin:auto;margin-top:12px" class="blog-extension-box"> class="blog_extension blog_extension_type2" id="blog_extension"> class="extension_official" data-report-click="{"spm":"1001.2101.3001.6471"}" data-report-view="{"spm":"1001.2101.3001.6471"}"> class="blog_extension_card_left"> class="blog_extension_card_cont"> 鸿蒙开发学习资料领取!!! class="blog_extension_card_cont_r"> 微信名片
注:本文转载自blog.csdn.net的沧海一笑-dj的文章"https://blog.csdn.net/dengjin20104042056/article/details/99315016"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接

评论记录:

未查询到任何数据!