Windows CE显示驱动分析

news/2024/10/17 0:20:03/

      Windows CE中显示驱动不是流接口驱动,它属于本机驱动,本机驱动的注册表信息在注册表中一般是以[HKEY_LOCAL_MACHINE\SYSTEM\]开始的路径的信息,而流驱动的注册表信息一般是以[HKEY_LOCAL_MACHINE\Drivers\BuiltIn\]开始的路径的信息。

显示驱动由图形、窗口、事件子系统(Gwes)直接加载,而不是设备管理器,驱动加载过程如下:

GWES.dll被加载后,GWES将根据注册表键HKEY_LOCAL_MACHINE\System\GDI\DisplayCandidates下面的项来找显示驱动,在Platform.reg中可以看到如下代码:

; GWES will pass this value to the Display driver; the driver will open the
; key to which it points to read its configuration.
[HKEY_LOCAL_MACHINE\System\GDI\DisplayCandidates]
"Candidate10"="Drivers\\Display\\s3c6410\\Config"

 

[HKEY_LOCAL_MACHINE\Drivers\Display\s3c6410\Config]
"DisplayDll"="My_s3c6410_disp.dll"
[HKEY_LOCAL_MACHINE\System\GDI\Drivers]
"Display"="My_s3c6410_disp.dll"
; Settings to rotate the screen by 0 degrees clockwise upon download
[HKEY_LOCAL_MACHINE\System\GDI\Rotation]
"Angle"=dword:0

      GWES就能找到s3c6410_disp.dll并且加载,并且把s3c6410_disp.dll作为一项写到HKEY_LOCAL_MACHINE\System\GDI\Driver键下面:

“Display”=“s3c6410_disp.dll

因为显示要实现独立于硬件的操作,驱动程序使用了分层的体系结构(可以看做为MDD层和PDD层)。

1、显示驱动的MDD

提到显示驱动的MDD层就需要知道GPE类,GPE类就相当于显示驱动的MDD层,GPE的标准定义是图形原语引擎(Graphics Primitive Engine),GPE是一个抽象类,是对显示设备的抽象,可以看做是显示驱动的通用的实现,其中包含很多纯虚函数,所以用户不能直接定义GPE类型的变量,只能以它为基类构造自己的GPE继承类,然后才能定义实例。我们也正是利用它的继承类来实现对于具体硬件的抽象,即实现我们的PDD层,同时完成基类中对应函数的实现。GPE类在gpe.h文件中定义,gpe.h在%_WINCEROOTMON\OAK\INC下。

    说到显示驱动不得不提到的就是DDI,DDI是Display Driver Interface 的缩写,如果看过串口函数的都知道,串口的MDD与PDD层的通信是通过一系列的接口函数实现的。而这里的DDI也是作为借口函数将GWES与设备驱动(PDD)联系起来的,逻辑上DDI函数的实现代码是构造生成任何一个显示设备驱动程序动态链接库的必不可少的内容。它并不需要驱动开发人员实现,微软已经帮我们实现了其中的代码。DDI的接口函数在ddi_if.cpp中实现的,源文件在%_WINCEROOT%PUBLIC\COMMON\OAK\DRIVERS\DISPLAY\GPE下;那这些函数是怎么被调用的呢?其实开发者需要设计一个GPE类的继承类,并定义一个该类的实例将其指针传递给DDI个函数供他们自身的实现,这个GPE继承类的实例就是目标硬件平台的显示设备的软件抽象,它必须正确反应特定显示设备的特性。

2、显示驱动的PDD

        显示设备的PDD层是与具体硬件相关的,它是GPE类的一个继承类,就拿6410的显示驱动来举例,准确的说,S3C6410Disp类的父类还不是GPE,而是DDGPE,DDGPE的父类才是GPE,之所以中间加了一个DDGPE类,是因为当前讨论的显示驱动程序既要支持DDI,又要支持DirectDraw。DDGPE类在文件Ddgpe.h中定义, 源文件在%_WINCEROOT%\PUBLIC\COMMON\OAK\INC下。一个GPE继承类实例对应一个显示设备硬件,所以GPE类型的所有数据成员都对应一个显示设备的某一方面的属性数据。用户可以并尽可能的根据具体的硬件设备所支持的功能实现GPE中的数据成员及函数。

3、那么具体上GWES子系统是如何获得DDI函数呢?
      Windows CE系统的设备驱动要实现自身的功能,不外乎导出函数和启动运行IST线程,但显示驱动只会向屏幕输出显示数据,不会启动IST线程。一下为6410显示驱动动态链接库导出函数:

LIBRARY DDI
EXPORTS
DrvEnableDriver
HALInit

     表面上只有两个导出函数,然而仅DrvEnableDriver一个函数又向Windows CE操作系统的GWES子系统提供了27个DDI函数指针。DrvEnableDriver函数是任何一个Windows CE的显示设备驱动程序都必不可少需要向GWES导出的,它是驱动程序的入口函数,他负责向GDI提供DDI指针。DrvEnableDriver()调用了GPEEnableDriver()函数,此函数在Ddi_if.cpp中实现,在此函数中可以看到,通过memcpy(pded, &pDrvFn, cj);代码将DDI的函数接口指针赋给pded提供给GWES,pDrvFn是一个DRVENABLEDATA类型的数组,DRVENABLEDATA数据结构组织了DDI的函数指针。

4、DDI函数又是如何与显示设备硬件打交道的呢?

    在ddi_id.cpp中我们可以看到有一个函数SafeGetGPE(),其实现代码如下:

GPE *
SafeGetGPE(
HANDLE hDriver
)
{
GPE * pGPE = NULL;
__try                                 
{
if ((hDriver != (HANDLE)SINGLE_DRIVER_HANDLE) && (pfnGetGPEPerCard != NULL))
{
pGPE = (*pfnGetGPEPerCard)((int)hDriver);
}
else
{	
pGPE = GetGPE();    //此函数在S3c6410_disp.cpp中定义

}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
pGPE = NULL;
}
return pGPE;
}

      考虑了多个显是控制器在系统中并存的问题,所以SafeGetGPE函数才会显得那么复杂。实际上多数嵌入式设备只有一个显示控制器。这里只调用了GetGPE函数,具体函数内容如下:

GPE *
GetGPE()
{
if (!gGPE)
{
gGPE = new S3C6410Disp();
}
return gGPE;
}

     这里的gGPE是一个GPE指针类型的全局变量,但是在GetGPE函数的实现代码直接将一个新生成S3C6410Disp类实例的指针赋值给它,S3C6410Disp类是GPE的继承类,父类的指针可以引用继承类的变量,并且对数据成员和成员函数的引用以继承类的实现或定义优先,所以使用gGPE所指向的数据或函数时,得到的是S3C6410Disp类型变量的成员数据或函数实现,只有在S3C6410Disp未定义的部分,才使用父类的数据成员和数据。这样一来,DDI函数就可以使用指向我们所创建的实例指针来访问我们具体的驱动程序了。

开发Display驱动的大致步骤如下:
(1)  继承GPE类并定义一个该类的实例。

(2)  实现GetGPE()函数,把该类的实例返回给上层的DDI接口。
(3)  实现DrvEnableDriver(..)函数并导出这个接口。

(4)  实现GPE类中的函数。

    

 


http://www.ppmy.cn/news/585189.html

相关文章

全志T3 Linux显示驱动分析

1、总体架构 全志T3处理器的显示框架是基于标准Linux的帧缓冲架构,其结构如图 1.1所示。显示控制器DE的驱动架构如图 1.2所示,包括屏蔽差异的显示管理抽象层,以及显示图层驱动、显示设备驱动、背光驱动、enhance驱动和capture驱动。 图 1.1 …

树莓派 PHP白屏,树莓派3.5英寸屏幕安装显示驱动,解决白屏问题

前几天为了树莓派显示DNS解析统计,我购买了一个3.5英寸的树莓派显示屏幕,它采用的显示方式是SPI方式,占用树莓派的26个IO口,由于不是采用HDMI方式显示,所以要安装树莓派显示驱动,否则屏幕是一片空白。本文教大家如何在树莓派Raspberry官方镜像下安装显示驱动。 不安装驱动…

OLED显示模块驱动原理及应用

OLED显示模块驱动原理及应用 本文以中景园OLED显示模块为例,介绍模块的应用和OLED显示及驱动的基本原理。文中介绍了显示模块、SSD1306驱动芯片以及GT20L16S1Y字库芯片相关技术内容及原理,并加上了作者的理解和应用记录。 一、 模块介绍 1. OLED显示…

Adobe Premiere Pro CC 2019启动时提示找不到任何具有视频播放功能的模板,请更新视频显示驱动程序并再次启动/PR启动时提示找不到任何具有视频播放功能的模板

Adobe Premiere Pro CC 2019启动时提示找不到任何具有视频播放功能的模板,请更新视频显示驱动程序并再次启动/PR启动时提示找不到任何具有视频播放功能的模板 一、开头 最近刚开学,算是把整个开学过程记录了一下,拍了很多视频素材&#xff0…

7段数码管显示驱动电路参数推导

7段数码管价格低廉驱动简单,能够显示数字0~9、字符A、b、C、d、E、 F、P、q、L等,被广泛应用于电子产品的简单数据的显示。比如温控仪的温度及设置参数的显示、电子钟的时间显示、电梯的楼层显示等。 以前感觉7段数码管的驱动电路很简单,而且…

五、TDDI 触控、显示驱动一体化技术

TDDI(触控、显示驱动一体化技术)即触控与显示驱动器集成(Touch and Display Driver Integration )。目前智能手机的触控和显示功能都由两块芯片独立控制,而TDDI最大的特点是把触控芯片与显示芯片整合进单一芯片中。 T…

手把手教你写HT1621显示驱动,简单明了,内含原码,方便移植,

HT1621显示驱动 Author:家有仙妻谢掌柜 Date:2021/1/5 最近用到了HT1621来驱动一个断码屏,写在这里记录自己的成长历程,也分享出去供大家参考! /* 首先声明在本程序中和移植相关的针对不同MCU所需要的做出的修改如下…

计算机硬件系统设计—码表数码管显示驱动设计

码表数码管显示驱动设计 功能:利用4个并行的7段数码管显示16位的BCD码。 输入:16位BCD码。 输出:4个7段数码管的控制信号(32位数据) S4T,S4B,S3T,S3B,S2T,S2B,S1T,S1B 。 这32位数据中,每8位数据用来控制显示1个7段数码管的控制信号。 要求: (1)将16位BCD码分为4组,每组…