Windows CE LCD显示驱动简析(2)(基于WinCE5.0 SMDK2410 BSP的LCD显示设备驱动)

来源:互联网 发布:纹绣师上门软件 编辑:程序博客网 时间:2024/04/30 19:06

现在就来看看我们需要实现的GPE继承类S3C2410DISP.
在ddi_if_cpp(/WINCE500/PUBLIC/COMMON/OAK/DRIVERS/DISPLAY/GPE)实现了一个SafeGetGPE函数,其代码如下:

这个函数考虑了多显示器的情况,而我们只有一个显示器,因此该函数实际上只是调用GetGPE函数,并将后者的返回值作为自己的返回值返回给调用者.
而GetGPE就实现在s3c2410x_lcd.cpp中,代码如下:

在GetGPE函数中,获得了一个新生成的S3C2410DISP类实例的指针.在以后使用gGPE所指向的数据或函数时,得到的都是S3C2410DISP类型变量的成员函数和函数,只有在S3C2410DISP未定义的部分,才使用父类或更上级类的数据成员和成员函数.
在CE5.0的SMDK2410 BSP中,S3C2410DISP是GPE的继承类,而在CE 6.0的DEVICEEMULATOR BSP中的S3C2410DISP是DDGPE的继承类.DDGPE是GPE的继承类,支持了DirectDraw,由于2410LCD控制器不支持DirectDraw,实际上DDGPE和GPE继承类没有区别.
获取GPE指针后,在微软已经实现的DDI函数中就会调用GPE类的成员函数来获取和实际显示硬件相关的信息和进行相应的操作.
接下来我们就来看看S3C2410DISP的具体成员:
1.S3C2410DISP的构造函数S3C2410DISP
这个函数首先设置一些显示参数,如LCD尺寸(240*320),缓冲区大小等.然和调用InitializeHardware进行LCD控制器初始化.
然后创建GPESurf类的实例m_pPrimarySurface,该类是GPE类实例的首要显示表面.显示表面的实质是显示屏幕上的所有像素点颜色数据在内存中的镜像.
接着设置光标的属性,如果设置了CLEARTYPE(这里没有定义),则读取注册表Gamma亮度属性(如果有的话,否则使用默认值1500),这里实际用的就是默认值,使用比较低的亮度来增加字体的对比度.最后设置24位颜色掩码(static ulong gBitMasks[] = { 0xF800, 0x07E0, 0x001F };  // 565 MODE)(实际上在SetMode函数中设置)
代码如下:

其中调用了InitializeHardware来进行硬件初始化,InitializeHardware首先读取注册表获取物理和虚拟显示内存地址
即注册表中的
 "LCDVirtualFrameBase"=dword:ac100000
 "LCDPhysicalFrameBase"=dword:30100000
然后调用InitializeLCDRegisters初始化LCD控制器,最后分配内存空间给显示区域.

InitializeLCDRegisters就是初始化了LCD控制寄存器,具体内容和在eboot中的处理基本是一样的.

2.SetMode
SetMode成员函数负责设置一个显示设备及其驱动程序能支持的显示模式.
通过调用EngCreatePalette来设置RGB模式:
static ulong gBitMasks[] = { 0xF800, 0x07E0, 0x001F };  // 565 MODE
modeId是要设置的显示工作模式的索引号,由于只有一个显示设备,该值必须为0.

3.GetModeInfo
GetModeInfo函数用于供调用者获取显示设备当前正在生效的显示工作模式,在S3C2410DISP类的GetModeInfo函数就是把m_ModeInfo成员所记录的GPEMode数据复制给输出参数mode.函数另一个参数modeNumber指定要获取的模式的索引号,在S3C2410DISP类中,它必须取值为0,因为当前的显示设备只支持一种显示模式.

4.NumModes
NumModes返回设备驱动程序所能支持的显示工作模式的数量.这里显然只能为1.函数简单返回1.

5.CursorOn
显示光标.
m_CursorForcedOff:记录当前系统中是否暂时关断鼠标显示.
m_CursorDisabled:记录系统是否禁用光标.
m_CursorVisible:指示屏幕上光标当前在显示屏幕上是否可见.
当这个变量都不为真时,即光标处于显示状态.然和计算光标所处位置,如有有旋转设置,则计算相应的新的坐标.

6.CursorOff
关闭光标.
CursorOff最后设置m_CursorVisible = FALSE;来关闭光标的显示.

7.SetPointerShape
SetPointerShape用于设置显示屏幕上鼠标光标的形状,图案和位置.
pMask参数所指向的显示表面是构成鼠标光标形状轮廓的与-异掩模位图.pColorSurf是指向显示表面包含鼠标光标的颜色图案的位图,这里没有使用,不支持彩色鼠标光标.xHot和yHot是鼠标光标的热点位置.cX和cY是光标在显示屏幕上的大小.

8.MovePointer

MovePointer用于将鼠标光标移动到指定的屏幕位置.参数xPosition和yPosition记录着光标到达新位置后的热点的坐标.

9.WaitForNotBusy
WaitForNotBusy用于等待显示设备空闲下来,直到显示设备可以接收新的操作指令WaitForNotBusy才返回.这个功能通常用于复杂而且功能强大的显示卡.而S3C2410的LCD控制器没有这么强的功能,因此该函数直接返回.

10.IsBusy

IsBusy用于查询显示设备是否正忙,如果忙返回非0值,空闲返回0.同WaitForNotBusy一样,用于功能强大的显示控制器,这里直接返回0.

11.GetPhysicalVideoMemory
GetPhysicalVideoMemory函数主要供DDHAL使用,用来获取显示内存的基地址和容量大小.

12.AllocSurface
AllocSurface用于为显示设备构造显示表面,这里继承自GPE类.还有一种情况是继承自DDGPE类.这里即用于构造GPESurf类型的显示表面.
surface是输出参数,是构造所得的GPESurf对象指针的指针;width和height是要求显示表面的宽和高;format参数是构造显示表面的像素格式要求;surfaceFlags用于指定在哪里构造显示表面.

13.Line,WrappedEmulatedLine
Line函数用于在显示表面上画直线段.由于S3C2410的LCD控制器不具备硬件加速能力,所以Line函数实现在非首要显示表面上画线时使用依靠软件实现的默认画线函数GPE::EmulateLine;而在首要表面画线时,调用的是用户实现的WrappedEmulatedLine函数.封装的目的只是要处理如果所画直线的范围矩形与鼠标光标的范围矩形重叠时,要先暂时消隐光标显示,待画完直线后在回复光标.
Line:

WrappedEmulatedLine

14.BltPrepare,BltComplete
BltPrepare和BltComplete都是GPE类的纯虚函数,用户定义的继承类必须实现这两个函数.分别为块传输做准备工作和为块传输"打扫战场".BltPrepare函数负责向GPEBltParms*类型的参数传递一个负责具体块传输操作的函数指针.由于不支持硬件加速,这里无法做任何特殊处理.只是将GPE默认的块传输函数复制给GPEBltParms结构的pBlt成员.GPE的EmulatedBlt函数类似于EmulatedLine函数,是GPE类自带的用软件模拟实现的不具备硬件加速能力的默认块传输函数.BltPrepare的其余代码就是处理如果块传输操作的源或目的显示表面其中有一个是首要显示表面,并且块传输区域的范围矩形与屏幕上鼠标光标的范围矩形发生重叠,则要暂时消隐鼠标光标.暂时消隐掉的鼠标光标在块传输完成后由BltComplete函数负责恢复.
BltPrepare:
ROTATE和CLEARTYPE宏均未定义.

BltComplete:

15.InVBlank
InVBlank用来查询显示设备当前时刻是否处在垂直空白阶段.垂直空白阶段指的是CRT类型的显示设备在显示完一帧后,电子枪从屏幕的右下角返回右上角的时间间隙.对于LCD没有这个特性可以利用,因此该函数直接返回0.

16.SetPalette
SetPalette用于对显示设备设置调色板.由于当前设备使用RGB565模式的颜色方案,因此不需要使用调色板.仅仅检查参数的有效性.

17.GetGraphicsCaps
GetGraphicsCaps用于向调用者返回显示设备和驱动程序所能支持的图形处理能力.
这里返回了GCAPS_GRAY16,表示显示设备和驱动程序具备字体反锯齿能力.
返回值可能的取值为以下宏定义或组合.如GCAPS_CLEARTYPE,ClearType技术是更高级的字体反锯齿的软件功能.


18.DrvEscape
DrvEscape是DDI的同名函数DrvEscape的延续,用于获取一些特殊的,通过与设备无关的设备驱动程序接口获取不到的信息.DDI的DrvEscape函数完成了部分与具体硬件无关的查询,而将需要依赖特定的显示设备硬件信息的交给设备驱动程序的DrvEscape函数.
这里实际上并未实现该函数(CLEARTYPE和ROTATE并未定义),如果定义了这两个宏,就进行Gamma数值和翻转状态的处理.

19.DrvGetMasks
DrvGetMasks是我们唯一一个需要直接实现的DDI函数.该函数用于获取显示设备的当前模式下的颜色掩码.直接返回全局数组的指针gBitMasks,就是之前提到过的565的RGB模式.
static ulong gBitMasks[] = { 0xF800, 0x07E0, 0x001F };  // 565 MODE

至此,GPE继承类S3C2410DISP需要实现的成员函数简单介绍到这里,还有和ClearType和Rotate相关的函数没有介绍,详情可以参考SMDK2410 BSP的显示驱动文件s3c2410x_lcd.cpp.
WinCE6.0 DEVICEEMULATOR BSP(基于s3c2410)的LCD驱动架构也基本类似,唯一大的区别就是使用了DDGPE继承类而不是直接继承GPE类,DDGPE类是GPE的继承类,支持DirectDraw,由于2410的LCD控制器不支持DirectDraw,因此继承这两个类并无本质的区别.
关于显示驱动还有很多内容并未详细介绍,如DDI函数,GPESurf类,调色板等,需要继续学习.

原创粉丝点击