分享
 
 
 

SkyEye硬件模拟平台LCD/TouchScreen仿真

王朝other·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

1. LCD模拟的构思和设计概述

LCD模拟模块的设计思路是,使用GTK+图形系统在X Window系统和Win32系统上实现一个LCD屏幕模拟,在SkyEye上运行的嵌入式操作系统中的LCD驱动程序象驱动真正的LCD控制器一样发送控制命令或对LCD显示内存进行访问操作,而SkyEye解释这些控制命令,并根据这些命令对LCD屏幕窗口进行相应的GTK+图形操作,完成对不同灰度或颜色图形的绘制。

在SkyEye模拟器中,如果嵌入式操作系统要执行I/O 地址访问,具体的处理过程由特定CPU 和开发板I/O 模拟模块中的read/write_byte/halfword/word 函数处理。所以LCD模拟模块关注的主要是内存模拟模块模拟出来的LCD显示内存中存储的数据。 LCD的显示内存映射到内存RAM中,代表了要在LCD屏幕上显示的图像。显示内存必须足够大,以处理显示屏幕上所有的象素。应用程序通过直接或间接地存取显示内存中的数据来进行进行图形操作,改变屏幕显示的内容。

LCD模拟模块对GTK+的使用目前仅限于根据分辨率(例如320x240,640x480)创建相应大小的窗口以及根据显示内存中的数据逐点在该窗口进行绘制,因为画点是LCD屏幕最基本的动作,所有其它的相对复杂工作如图形绘制,嵌入式GUI系统的实现都应该由基于LCD驱动程序的应用程序(包括基于FrameBuffer驱动程序的嵌入式GUI系统,例如MiniGUI)通过对LCD显示内存的读写操作来实现,SkyEye"看到"的只是显存中对应于屏幕上各个点的像素值,而不关心这些像素值组成的是什么样的图像。基于MiniGUI的应用程序在SkyEye运行的效果截图如图 0-1所示。

SkyEye中LCD模拟部分的示意图如图 0-2(包括与真实情况的比较):

LCD模拟模块的实现先后采用了两种方案,在第一种方案中,在SkyEye的内存模拟模块中,在每一次的写内存操作之后判断其地址是否属于LCD显示内存的地址范围,如果在该范围之内则调用LCD模拟模块中的GTK+画点函数gdk_draw_point(),根据由像素值查找彩色查找表CLUT得到的RGB值(对于真彩色,颜色深度为16,24,32时,RGB值可以直接由像素值得到),在模拟屏幕窗口的相应位置画一个相应灰度或颜色的点。

该方案的优点在于实现起来简单,且模拟了真实的LCD最基本的画点动作,对于图像随时间流逝而只有小范围变化的情况具有一定的优势,因为对显存有写操作时才有画点操作,但是也有两个方面的缺点,其一,与SkyEye模拟器的内存模拟模块耦合紧密,破坏了模块间的独立性;其二,对于图像随时间流逝而大范围变化的情况,本方案效率低下,在LCD驱动程序连续的每两次写显存操作中,都要经历一个单位延迟时间,其长度等于一次地址范围的判断,一次CLUT查找及一次GTK+画点函数的调用所耗费的时间,对于一次全屏操作,以320x240x8为例,若以字节为单位写显存,则额外的时间延迟将320x240x8/8=76800倍于单位延迟时间。

而第二种方案则直接定时(时间间隔可调,例如设置成200ms) 调用GTK+的绘图函数gdk_draw_rgb_image()将显存中的数据一次性绘制到窗口中。该方案模拟了DMA的定时扫描方式,与真实的DMA方式不同的是,在真实的硬件上,DMA方式无须CPU参与,可与CPU并行工作,而用软件模拟的硬件无法做到这一点,只能串行地定时扫描显示内存,其时间延迟不可避免的比真实硬件大。

第二方案降低了LCD模拟模块与内存模拟模块之间的耦合度,其缺点是不能实时地反映显存的快速变化。如果将定时间隔设置得过大,则增大了窗口内容刷新时的闪烁;如果定时间隔设置得过小,定时扫描过于频繁地发生,对系统资源是一种浪费。

2. SkyEye中的LCD模拟分析

SkyEye的lcd仿真首先是在模拟ep7312时实现的,所以在本文分析lcd仿真时是以ep7312的lcd模块为例,对于模拟其它的开发板时添加lcd模块的方法是一样的。在SkyEye源码中的clps7110.h文件中有如下定义:

//lcd控制寄存器地址

#define LCDCON0x02c0/* LCD Control register */

#define VBUFSIZ0x00001fff

/* Video buffer size (bits/128-1) */

#define LINELEN0x0007e000

/* Line length (pix/16-1) */

#define LINELEN_SHIFT13

#define PIXPSC0x01f80000

/* Pixel prescale (526628/pixels-1) */

#define PIXPSC_SHIFT19

#define ACPSC0x3e000000

/* AC prescale */

#define ACPSC_SHIFT25

//下面两个控制lcd是单色、4级灰度或16级灰度(每个像素点有几位决定灰度级)

#define GSEN0x40000000

/* Grayscale enable (0: monochrome) */

#define GSMD0x80000000

/* Grayscale mode (0: 2 bit, 1: 4 bit) */

//SYSCON寄存器的一位,控制lcd是否enable(SYSCON就是state-io.syscon)

#defineLCDEN0x00001000

/* LCD enable */

在SkyEye源码中的skyeye_lcd. c文件中有如下定义:

#define LCD_BASE 0xC0000000 // lcd显示内存起始地址

在SkyEye源码中的skyeye_mach_ep7312.c文件中有:

state-mach_io.lcdcon=(ARMword *)&io.lcdcon;

// lcd控制寄存器

state-mach_io.lcd_is_enable=(ARMword *)&io.lcd_is_enable;

// 是否打开lcd

state-mach_io.lcd_addr_begin=(ARMword *)&io.lcd_addr_begin; // lcd显示内存起始地址

state-mach_io.lcd_addr_end=(ARMword *)&io.lcd_addr_end;

// lcd显示内存结束地址

在ep7312_io_do_cycle函数中也就是每个时钟后会调用:

skyeye_config.mach-mach_io_do_cycle(state);

SkyEye模拟ep7312时,会在skyeye_mach_ep7312.c中的函数ep7312_mach_init注册

this_mach-mach_io_do_cycle = ep7312_io_do_cycle;

在ep7312_io_do_cycle中调用lcd_cycle,这里

lcd_cycle(state)=gtk_main_iteration_do(FALSE);

检查gtk窗口是否有事件需要处理,没有则立即返回。

ep7312_io_read_word函数中:

如果读LCDCON寄存器的地址

返回 data = state-io.lcdcon;

switch (addr - 0x80000000) {

//如果用户写系统控制寄存器,让lcd的状态从关闭变为打开,则重新初始化lcd。

case SYSCON:

tmp = io.syscon;

io.syscon = data;

//chy 2004-03-11

if ((tmp & LCDEN) != (data & LCDEN)) {

ep7312_update_lcd(state);

}

break;

… …

//如果用户改写lcd控制寄存器,改变lcd的控制参数,则重新初始化lcd

case LCDCON:

tmp = io.lcdcon;

io.lcdcon = data;

//chy 2004-03-11 tmp compare with data

if ((tmp & (VBUFSIZ|LINELEN|GSEN|GSMD)) != (data & (VBUFSIZ|LINELEN|GSEN|GSMD))) {

ep7312_update_lcd(state);

}

break;

… …

}

//在应用程序改写SYSCON或LCDCON时,重新初始化LCD时被调用

static void ep7312_update_lcd(ARMul_State *state)

{

ep7312_lcd_disable(state);

if (io.syscon & LCDEN) {

ARMword lcdcon = io.lcdcon;

ARMword vbufsiz = lcdcon & VBUFSIZ;

ARMword linelen = (lcdcon & LINELEN) LINELEN_SHIFT;

int width, height, depth;

switch (lcdcon & (GSEN|GSMD)) {

case GSEN:

depth = 2;

break;

case GSEN|GSMD:

depth = 4;

break;

default:

depth = 1;

break;

}

width = (linelen + 1) * 16;

height = (vbufsiz + 1) * 128 / depth / width;

//以上是取得lcd的高,宽,像素位数(都从LCDCON寄存器中来)

//使用以上参数重新初始化lcd

ep7312_lcd_enable(state, width, height, depth);

}

}

3. LCD相关函数分析

skyeye_lcd.c中的函数:

//当LCDCON寄存器被改写时,调用lcd_enable重新初始化lcd仿真屏幕窗口

void lcd_enable(ARMul_State *state, int width, int height, int depth)

{

int i;

static int once = 0;

GdkColor tmpColor;

char * title;

char mode[100];

if(skyeye_config.no_lcd){

return;

}//如果不使用lcd,则返回

if (!once) {

once++;

gtk_init(&global_argc, &global_argv);

}//只在第一次运行时初始化一个gtk模拟出的lcd屏幕窗口

lcd_width = width;

//lcd仿真屏幕宽度

lcd_height = height;

//lcd仿真屏幕高度

lcd_depth = depth;

//表示一个象素所用的bit数(决定颜色深度)

*(state-mach_io.lcd_is_enable)=1;

//根据显示模式计算lcd显示内存的结束地址

*(state-mach_io.lcd_addr_end) = *(state-mach_io.lcd_addr_begin) + (width * height * depth / 8);

printf("SKYEYE:

lcd_addr_begin 0x%x,lcd_addr_end 0x%x, width %d, height %d, depth %d\n",*(state-mach_io.lcd_addr_end),

*(state-mach_io.lcd_addr_begin),width, height,depth);

//建立顶层窗口

window = gtk_window_new(GTK_WINDOW_TOPLEVEL);

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有