OpenHarmony——基于HDF驱动框架构建的Display驱动模型

概述

功能简介

LCD(Liquid Crystal Display)驱动编程,通过对显示器上电、初始化显示器驱动IC(Integrated Circuit)内部寄存器等操作,使其可以正常工作。

基于HDF(Hardware Driver Foundation)驱动框架构建的Display驱动模型作用如下:

  • 为LCD器件驱动开发提供了基础驱动框架,提升驱动开发效率。

  • 便于开发的器件驱动实现跨OS、跨芯片平台迁移。

基于HDF驱动框架的Display驱动模型如下所示:

图1 基于HDF驱动框架的Display驱动模型

Display驱动模型主要由平台驱动层、芯片平台适配层、LCD器件驱动层三部分组成。驱动模型基于HDF驱动框架开发,通过Platform层和OSAL层提供的接口,屏蔽内核形态的差异,使得器件驱动可以便利的迁移到不同OS及芯片平台。模型向上对接Display公共HAL层,支撑HDI(Hardware Device Interface)接口的实现,通过Display-HDI对图形服务提供各类驱动能力接口。

  • Display平台驱动层:通过HDF提供的IOService数据通道,与公共HAL层对接,集中接收并处理各类上层调用指令。

  • SoC平台驱动适配层:借助此SoC适配层,实现Display驱动和SoC侧驱动解耦,主要完成芯片平台相关的参数配置,并传递平台驱动层的调用到器件驱动层。

  • LCD器件驱动层:在器件驱动层中,主要实现和器件自身强相关的驱动适配接口,例如发送初始化序列、上下电、背光设置等。

基于Display驱动模型开发LCD驱动,可以借助平台提供的各种能力及接口,较大程度的降低器件驱动的开发周期和难度,提升开发效率。

基本概念

LCD接口通常可分为MIPI DSI接口、TTL接口和LVDS接口,常用的是MIPI DSI接口和TTL接口,下面对常用的MIPI DSI接口和TTL接口作简要介绍。

  • MIPI DSI接口

  • 图2 MIPI DSI接口

添加图片注释,不超过 140 字(可选)

  • MIPI DSI接口是MIPI(Mobile Industry Processor Interface)联盟定义的显示接口,主要用于移动终端显示屏接口,接口数据传输遵循MIPI协议,MIPI DSI接口为数据接口,传输图像数据,通常情况下MIPI DSI接口的控制信息以MIPI包形式通过MIPI DSI接口发送到对端IC,不需要额外的外设接口。

  • TTL接口

  • 图3 TTL接口

添加图片注释,不超过 140 字(可选)

  • ​TTL(Transistor Transistor Logic)即晶体管-晶体管逻辑,TTL电平信号由TTL器件产生,TTL器件是数字集成电路的一大门类,它采用双极型工艺制造,具有高速度、低功耗和品种多等特点。

  • TTL接口是并行方式传输数据的接口,有数据信号、时钟信号和控制信号(行同步、帧同步、数据有效信号等),在控制信号控制下完成数据传输。通常TTL接口的LCD,内部寄存器读写需要额外的外设接口,比如SPI接口、I2C接口等。

约束与限制

开发者在进行LCD驱动编程过程中,除了要关注IC的型号,还要关注LCD外围电路设计、基带芯片的LCD接口单元、背光IC的控制等多个方面,同时包括软件的上层程序。这些都是影响开发者在调试LCD驱动的影响因素。

开发指导

场景介绍

LCD驱动模型属于驱动基础适配模块,第三方需要适配OpenHarmony系统时,需要进行LCD驱动适配。LCD驱动适配基于HDF驱动框架、Platform接口及OSAL接口开发,可以做到不区分OS(LiteOS、Linux)和芯片平台(Hi35xx、Hi38xx、V3S等),为LCD器件提供统一的驱动模型。

接口说明

为了能够调整液晶显示屏的各项参数,与display建立显示通道,实现显示器的显示效果,LCD驱动需要通过display :: host注册PanelInfo结构体、接口信息,添加描述设备;LcdResetOn读取的pin脚信息,由SampleEntryInit初始化入口函数,并注册器件驱动接口,供平台驱动调用。

表1 LCD驱动适配所需接口

添加图片注释,不超过 140 字(可选)

开发步骤

  1. 添加LCD驱动相关的设备描述配置。

  2. 在SoC平台驱动适配层中适配对应的芯片平台驱动。

  3. 添加器件驱动,并在驱动入口函数Init中注册Panel驱动数据,驱动数据接口主要实现下述特性:

  4. LCD上下电

  5. 根据LCD硬件连接,使用Platform接口层提供的GPIO操作接口操作对应LCD管脚,例如复位管脚、IOVCC管脚,上电时序参考LCD供应商提供的SPEC。

  6. 发送初始化序列

  7. 根据LCD硬件接口,使用Platform接口层提供的I2C、SPI、MIPI等接口,下载LCD初始化序列,初始化参数序列可以参考LCD供应商提供的SPEC。

  8. (可选)根据需求实现HDF框架其他接口。

  9. (可选)根据需求使用HDF框架可创建其他设备节点,用于业务逻辑或者调试功能。

开发实例

以Hi35xx系列芯片为例,根据开发步骤所述,介绍LCD驱动的详细适配过程。

  1. 添加设备描述配置(vendor/bearpi/bearpi_hm_micro/hdf_config/device_info/device_info.hcs)

    /* Display驱动相关的设备描述配置 */
    display :: host {
        hostName = "display_host";
        /* Display平台驱动设备描述 */
        device_hdf_disp :: device {
            device0 :: deviceNode {
                policy = 2;
                priority = 200;
                permission = 0660;
                moduleName = "HDF_DISP";
                serviceName = "hdf_disp";
            }
        }
        /* SoC适配层驱动设备描述 */
        device_hi35xx_disp :: device {
            device0 :: deviceNode {
                policy = 0;
                priority = 199;
                moduleName = "HI351XX_DISP";
            }
        }
        /* LCD器件驱动设备描述 */
        device_lcd :: device {
            device0 :: deviceNode {
                policy = 0;
                priority = 100;
                preload = 0;
                moduleName = "LCD_Sample";
            }
            device1 :: deviceNode {
                policy = 0;
                priority = 100;
                preload = 2;
                moduleName = "LCD_SampleXX";
            }
        }
    }

    2.SoC平台驱动适配层中适配对应的芯片平台驱动(drivers/hdf_core/framework/model/display/driver/adapter_soc/hi35xx_disp.c)

    /* Display驱动适配MIPI等和芯片平台相关的配置 */
    static int32_t MipiDsiInit(struct PanelInfo *info)
    {
        int32_t ret;
        struct DevHandle *mipiHandle = NULL;
        struct MipiCfg cfg;
    
        mipiHandle = MipiDsiOpen(0);
        if (mipiHandle == NULL) {
            HDF_LOGE("%s: MipiDsiOpen failure", __func__);
            return HDF_FAILURE;
        }
        cfg.lane = info->mipi.lane;
        cfg.mode = info->mipi.mode;
        cfg.format = info->mipi.format;
        cfg.burstMode = info->mipi.burstMode;
        cfg.timing.xPixels = info->width;
        cfg.timing.hsaPixels = info->hsw;
        cfg.timing.hbpPixels = info->hbp;
        cfg.timing.hlinePixels = info->width + info->hbp + info->hfp + info->hsw;
        cfg.timing.vsaLines = info->vsw;
        cfg.timing.vbpLines = info->vbp;
        cfg.timing.vfpLines = info->vfp;
        cfg.timing.ylines = info->height;
        /* 0 : no care */
        cfg.timing.edpiCmdSize = 0;
        cfg.pixelClk = CalcPixelClk(info);
        cfg.phyDataRate = CalcDataRate(info);
        /* config mipi device */
        ret = MipiDsiSetCfg(mipiHandle, &cfg);
        if (ret != HDF_SUCCESS) {
            HDF_LOGE("%s:MipiDsiSetCfg failure", __func__);
        }
        MipiDsiClose(mipiHandle);
        HDF_LOGI("%s:pixelClk = %d, phyDataRate = %d\n", __func__,
            cfg.pixelClk, cfg.phyDataRate);
        return ret;
    }

    3.添加器件

  2. 驱动定义相关接口信息(drivers/hdf_core/framework/model/display/driver/panel/mipi_icn9700.c)
    #define RESET_GPIO                5
    #define MIPI_DSI0                 0
    #define BLK_PWM1                  1
    #define PWM_MAX_PERIOD            100000
    /* backlight setting */
    #define MIN_LEVEL                 0
    #define MAX_LEVEL                 255
    #define DEFAULT_LEVEL             100
    #define WIDTH                     480
    #define HEIGHT                    960
    #define HORIZONTAL_BACK_PORCH     20
    #define HORIZONTAL_FRONT_PORCH    20
    #define HORIZONTAL_SYNC_WIDTH     10
    #define VERTICAL_BACK_PORCH       14
    #define VERTICAL_FRONT_PORCH      16
    #define VERTICAL_SYNC_WIDTH       2
    #define FRAME_RATE                60

    定义PanelInfo结构体(drivers/hdf_core/framework/model/display/driver/hdf_disp.h)

    struct PanelInfo {
        uint32_t width;
        uint32_t height;
        uint32_t hbp;
        uint32_t hfp;
        uint32_t hsw;
        uint32_t vbp;
        uint32_t vfp;
        uint32_t vsw;
        uint32_t frameRate;
        enum LcdIntfType intfType;
        enum IntfSync intfSync;
        struct MipiDsiDesc mipi;
        struct BlkDesc blk;
        struct PwmCfg pwm;
    };

    初始化LCD屏(drivers/hdf_core/framework/model/display/driver/panel/mipi_icn9700.c)

    static uint8_t g_payLoad0[] = { 0xF0, 0x5A, 0x5A };
    static uint8_t g_payLoad1[] = { 0xF1, 0xA5, 0xA5 };
    static uint8_t g_payLoad2[] = { 0xB3, 0x03, 0x03, 0x03, 0x07, 0x05, 0x0D, 0x0F, 0x11, 0x13, 0x09, 0x0B };
    static uint8_t g_payLoad3[] = { 0xB4, 0x03, 0x03, 0x03, 0x06, 0x04, 0x0C, 0x0E, 0x10, 0x12, 0x08, 0x0A };
    static uint8_t g_payLoad4[] = { 0xB0, 0x54, 0x32, 0x23, 0x45, 0x44, 0x44, 0x44, 0x44, 0x60, 0x00, 0x60, 0x1C };
    static uint8_t g_payLoad5[] = { 0xB1, 0x32, 0x84, 0x02, 0x87, 0x12, 0x00, 0x50, 0x1C };
    static uint8_t g_payLoad6[] = { 0xB2, 0x73, 0x09, 0x08 };
    static uint8_t g_payLoad7[] = { 0xB6, 0x5C, 0x5C, 0x05 };
    static uint8_t g_payLoad8[] = { 0xB8, 0x23, 0x41, 0x32, 0x30, 0x03 };
    static uint8_t g_payLoad9[] = { 0xBC, 0xD2, 0x0E, 0x63, 0x63, 0x5A, 0x32, 0x22, 0x14, 0x22, 0x03 };
    static uint8_t g_payLoad10[] = { 0xb7, 0x41 };
    static uint8_t g_payLoad11[] = { 0xC1, 0x0c, 0x10, 0x04, 0x0c, 0x10, 0x04 };
    static uint8_t g_payLoad12[] = { 0xC2, 0x10, 0xE0 };
    static uint8_t g_payLoad13[] = { 0xC3, 0x22, 0x11 };
    static uint8_t g_payLoad14[] = { 0xD0, 0x07, 0xFF };
    static uint8_t g_payLoad15[] = { 0xD2, 0x63, 0x0B, 0x08, 0x88 };
    static uint8_t g_payLoad16[] = { 0xC6, 0x08, 0x15, 0xFF, 0x10, 0x16, 0x80, 0x60 };
    static uint8_t g_payLoad17[] = { 0xc7, 0x04 };
    static uint8_t g_payLoad18[] = {
        0xC8, 0x7C, 0x50, 0x3B, 0x2C, 0x25, 0x16, 0x1C, 0x08, 0x27, 0x2B, 0x2F, 0x52, 0x43, 0x4C, 0x40,
        0x3D, 0x30, 0x1E, 0x06, 0x7C, 0x50, 0x3B, 0x2C, 0x25, 0x16, 0x1C, 0x08, 0x27, 0x2B, 0x2F, 0x52,
        0x43, 0x4C, 0x40, 0x3D, 0x30, 0x1E, 0x06
    };
    static uint8_t g_payLoad19[] = { 0x11 };
    static uint8_t g_payLoad20[] = { 0x29 };
    static DevHandle g_mipiHandle = NULL;
    static DevHandle g_pwmHandle = NULL;

    设置Reset Pin脚状态(/drivers_hdf_core/framework/model/display/driver/panel/mipi_icn9700.c)

    static int32_t LcdResetOn(void)
    {
        int32_t ret;
        ret = GpioSetDir(RESET_GPIO, GPIO_DIR_OUT);
        if (ret != HDF_SUCCESS) {
            HDF_LOGE("GpioSetDir failure, ret:%d", ret);
            return HDF_FAILURE;
        }
        ret = GpioWrite(RESET_GPIO, GPIO_VAL_HIGH);
        if (ret != HDF_SUCCESS) {
            HDF_LOGE("GpioWrite failure, ret:%d", ret);
            return HDF_FAILURE;
        }
        /* delay 20ms */
        OsalMSleep(20);
        return HDF_SUCCESS;
    }

    器件驱动入口函数(/drivers_hdf_core/framework/model/display/driver/panel/mipi_icn9700.c)

    int32_t SampleEntryInit(struct HdfDeviceObject *object)
    {
        HDF_LOGI("%s: enter", __func__);
        if (object == NULL) {
            HDF_LOGE("%s: param is null!", __func__);
            return HDF_FAILURE;
        }
        /* 器件驱动接口注册,ops提供给平台驱动调用 */
        if (PanelDataRegister(&g_panelData) != HDF_SUCCESS) {
            HDF_LOGE("%s: PanelDataRegister error!", __func__);
            return HDF_FAILURE;
        }
        return HDF_SUCCESS;
    }
    
    struct HdfDriverEntry g_sampleDevEntry = {
        .moduleVersion = 1,
        .moduleName = "LCD_SAMPLE",
        .Init = SampleEntryInit,
    };
    
    HDF_INIT(g_sampleDevEntry);

    想学习更多华为鸿蒙HarmonyOS开发知识,在这里我为大家准备了华为鸿蒙HarmonyOS开发者资料大全,大家可以自行点击链接领取:《做鸿蒙应用开发到底学习些啥?》

    其次就是考虑到市场上还没有系统性的学习资料,同时我也整理了一份《鸿蒙 (Harmony OS)开发学习手册》特意整理成PDF文档方式,分享给大家参考学习,大家可以根据自身情况进行获取:《鸿蒙开发学习指南》

    《鸿蒙 (Harmony OS)开发学习手册》

    一、入门必看

    1. 应用开发导读(ArkTS)

    2. 应用开发导读(Java)

    3.......

    二、HarmonyOS 概念

    1. 系统定义

    2. 技术架构

    3. 技术特性

    4. 系统安全

    5......

    三、如何快速入门?《鸿蒙基础入门开发宝典!》

    1. 基本概念

    2. 构建第一个ArkTS应用

    3. 构建第一个JS应用

    4. ……

    四、开发基础知识

    1. 应用基础知识

    2. 配置文件

    3. 应用数据管理

    4. 应用安全管理

    5. 应用隐私保护

    6. 三方应用调用管控机制

    7. 资源分类与访问

    8. 学习ArkTS语言

    9. ……

    五、基于ArkTS 开发

    1. Ability开发

    2. UI开发

    3. 公共事件与通知

    4. 窗口管理

    5. 媒体

    6. 安全

    7. 网络与链接

    8. 电话服务

    9. 数据管理

    10. 后台任务(Background Task)管理

    11. 设备管理

    12. 设备使用信息统计

    13. DFX

    14. 国际化开发

    15. 折叠屏系列

    16. ……

    更多了解更多鸿蒙开发的相关知识可以参考:《鸿蒙开发学习指南》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/325339.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

1-Docker-基础

本文内容多处参考黑马程序员的公开资料,仅用来个人梳理,原资料地址:https://b11et3un53m.feishu.cn/wiki/MWQIw4Zvhil0I5ktPHwcoqZdnec Docker介绍 为什么要用Docker? 以Mysql安装为例,想要在Linux系统上安装Mysql&…

前任开发在代码里下毒了,支付下单居然没加幂等

分享是最有效的学习方式。 故事 又是一个风和日丽没好的一天,小猫戴着耳机,安逸地听着音乐,撸着代码,这种没有会议的日子真的是巴适得板。 不料祸从天降,组长火急火燎地跑过来找到了小猫。“快排查一下,目…

【Emgu CV教程】5.1、几何变换之平移

图像的几何变换对于图像处理来说,也是最基础的那一档次,包括平移、旋转、缩放、透视变换等等,也就是对图像整理形状的改变,用到的函数都比较简单,理解起来也很容易。但是为了凑字数,还是一个函数一个函数的…

类和对象特性

#include<iostream> #include<string> using namespace std; class peron{ public:peron(string person){cout << "peron调用构造函数" << endl;tperson person;}~peron(){cout << "peron调用析构函数" << endl;}//手…

22k+star炒鸡好用的开源的网盘神器FileBrowser Docker自建个人网盘神器教程

目录 简介 1.拉取镜像 2.创建并启动容器 2.1创建目录 2.2启初始化一个容器用于导出配置文件和数据库&#xff0c;只挂载数据目录 2.3先将数据库文件和配置文件复制出来 2.4停止容器并删除容器 2.5创建完整的容器 3.愉快地使用 3.1示例&#xff1a; 3.2图片预览 3.3json…

快速更改flutter已有项目的项目名称和id等

如果你使用了别人已有的仓库模板或者想更改现有项目的名称&#xff0c;是一件非常繁琐的工作&#xff0c;需要修改全平台的文件还是相当麻烦的&#xff0c;所以这里推荐一个小工具&#xff0c;可以帮助大家快速实现更改项目名称的目的&#xff0c;这个工具地址&#xff1a;rena…

YOLOv8改进 | 检测头篇 | 利用DBB重参数化模块魔改检测头实现暴力涨点 (支持检测、分割、关键点检测)

一、本文介绍 本文给大家带来的改进机制是二次创新的机制,二次创新是我们发表论文中关键的一环,本文给大家带来的二次创新机制是通过DiverseBranchBlock(DBB)模块来改进我们的检测头形成一个新的检测头Detect_DBB,其中DBB是一种重参数化模块,其训练时采用复杂结构,推理时…

Java Chassis 3技术解密:注册中心分区隔离

原文链接&#xff1a;Java Chassis 3技术解密&#xff1a;注册中心分区隔离-云社区-华为云 注册中心负责实例的注册和发现&#xff0c;对微服务可靠运行起到举足轻重的作用。实例变更感知周期是注册中心最重要的技术指标之一。感知周期代表提供者的实例注册或者下线后&#xf…

MVP的思维方式

MVP释义&#xff1a;做最小可行产品&#xff0c;做最有价值的人 首席产品官MVP社区 2023-09-04 08:53 北京 MVP&#xff0c;即“Minimum Viable Product”&#xff0c;中文翻译为“最小可行产品”&#xff0c;指的是在产品开发过程中&#xff0c;将资源集中在最核心的功能上&a…

Redis教程——Redis bitmap位图操作(图解)

在平时开发过程中&#xff0c;经常会有一些 bool 类型数据需要存取。比如记录用户一年内签到的次数&#xff0c;签了是 1&#xff0c;没签是 0。如果使用 key-value 来存储&#xff0c;那么每个用户都要记录 365 次&#xff0c;当用户成百上亿时&#xff0c;需要的存储空间将非…

帆软后台(外观配置-主题)文件上传漏洞

漏洞利用 帆软上传主题获取shell&#xff08;管理系统-外观配置&#xff09; 添加主题上传的压缩包中放入shell.jsp马 &#xff08;没有添加主题功能直接构造数据包&#xff09; POST /WebReport/ReportServer?opfr_attach&cmdah_upload&filenametest.zip&widt…

uniapp中,子组件给父页面传值(父组件)

前言 最近在做的一个小程序项目中&#xff0c;有一个身份切换的功能&#xff0c;点击切换按钮时&#xff0c;子组件向父组件传递身份信息&#xff0c;父页面依据这个身份信息对页面进行显示与隐藏。 具体实现 子组件中定义一个点击事件,在这里是identitySwitching()方法 &l…

Vue项目中如何解决跨域详解

文章目录 一、跨域是什么二、如何解决CORSProxy方案一方案二方案三 一、跨域是什么 跨域本质是浏览器基于同源策略的一种安全手段 同源策略&#xff08;Sameoriginpolicy&#xff09;&#xff0c;是一种约定&#xff0c;它是浏览器最核心也最基本的安全功能 所谓同源&#x…

如何学习three.js

如何学习three.js 前言1. 基础概念场景&#xff08;Scene&#xff09;&#xff1a; three.js中所有物体的容器。你可以把它想象成一个舞台&#xff0c;在这里添加物体、光源等。相机&#xff08;Camera&#xff09;&#xff1a; 决定了哪部分场景会被渲染。最常用的是透视相机&…

SecureCRT6中文版安装资源,一键安装

SecureCRT 6 是一款由 VanDyke Software 开发的终端仿真程序&#xff0c;它为用户提供了一个安全的远程访问工具&#xff0c;可以通过 SSH、Telnet、Rlogin 和串口等协议连接到远程服务器或设备。 它适用于各种操作系统&#xff0c;如 Windows、Mac 和 Linux。它提供了强大的功…

SELinux、SELinux运行模式、破解Linux系统密码、firewalld防火墙介绍、构建基本FTP服务、systemd管理服务、设置运行模式

1 路漫漫其修远兮&#xff0c;吾将上下而求索 2 DNS服务器 作用&#xff1a;负责域名解析的服务器&#xff0c;将域名解析为IP地址 /etc/resolv.conf:指定DNS服务器地址配置文件 3 常用的网络工具 ip命令&#xff08;Linux最基础的命令&#xff09; 1.查看IP地址 [rootserv…

C#,入门教程(19)——循环语句(for,while,foreach)的基础知识

上一篇&#xff1a; C#&#xff0c;入门教程(18)——分支语句&#xff08;switch-case&#xff09;的基础知识https://blog.csdn.net/beijinghorn/article/details/124039953 一、for循环 当老师进入教室&#xff0c;从门口开始分别按行、列点名&#xff0c;看看哪位翘课&…

【脑筋急转弯系列】乒乓球称重问题

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学习,不断总结,共同进步,活到老学到老导航 檀越剑指大厂系列:全面总结 jav…

EndNote登录一直显示The username/password specified is not valid

EndNote登录一直显示The username/password specified is not valid EndNote20今天想打开之前的share library的时候一直显示 ‘The Username/password specified is not valid’&#xff0c;查了很多解决方案&#xff0c;现在献上解决方案&#xff1a; 该密码然后重新登陆…

js 回文串

思路&#xff1a; 判断一个字符串是否为回文字符串的基本思路是比较字符串的正序和倒序是否相同。 两者相同&#xff0c;则该字符串是回文字符串&#xff0c;否则不是。 要实现这一思路&#xff0c;我们可以使用 JavaScript 字符串的一些方法。我是忽略了所有的空格和符号&…