S5PV210开发系列四_uCGUI的移植

S5PV210开发系列四

uCGUI的移植

象棋小子          1048272975

GUI(图形用户界面)极大地方便了非专业用户的使用,用户无需记忆大量的命令,取而代之的是可以通过窗口、菜单、按键等方式进行操作。在某些场合,设计一款人机界面丰富友好的嵌入式产品能赢得更多的用户。笔者此处就S5PV210基于uCGUI图形用户界面的使用作一个简单的介绍。

1. uCGUI移植概述

1.1. S5PV210 Bootloader

笔者的S5PV210的Bootloader设置最高的CPU主频1GHZ,MMU进行1:1内存空间线性映射,并开启L1 I/D Cache、L2 Cache、硬件分支预测功能,使CPU能达到最大的吞吐量性能。初始化内存,能够识别sd/mmc启动和Nand flash启动,自动加载应用代码到RAM位置。统一的中断管理架构、重定向底层IO操作,支持代码直接下载内存运行以及Nandflash下载,能够更加专注于应用的开发。

1.2. uCGUI源码

笔者以uCGUI 3.98这个版本移植作为讲解,这个版本的uCGUI是开放源码的最高版本,之后版本只提供库文件,不再开源,关于uCGUI概述、使用、移植等详细内容,可以直接阅读uCGUI用户手册。

1.3. uCGUI接口实现

uCGUI根据其使用的功能,必须先实现其相应的功能接口。对于uCGUI,显示以及时基计时这两部分是必须的,因此必须实现其接口。显示即是实现相应的屏驱动,时基计时即是实现1ms/tick的定时计数,uCGUI用来实现时间计时。此处还使用uCGUI触摸屏功能,因此也应实现相应的触摸屏驱动。

2. 接口移植驱动

2.1. 屏驱动

屏驱动主要提供设置某一坐标像素颜色接口Display_SetPixel 和从某一坐标读出像素颜色接口Display_GetPixel给uCGUI即可。S5PV210具有RGB接口,因此屏驱动也主要是RGB接口的初始化,根据具体的屏,设置其水平分辩率、垂直分辩率、像素时钟、缓存位置等即可。RGB控制器是通过DMA的方式把显存帧数据传输到外部接口,因此CPU对显存数据的更改均应写回显存所在的物理主存,不然会有Cache数据一致性的问题。

Bootloader对于Cache提供了对应的四种内存分配策略:

cached, write-back,写回模式,CPU的每次读写如果Cache命中则只读写Cache,不读写主存。这种模式不用过多地读写缓慢的主存,因此CPU具有最高的性能,默认的内存分配方式。

cached, write-through,写通模式,CPU每次读如果Cache命中则只读Cache,不读主存,每次写即使Cache命中更新Cache外,还会随后写入主存,降低了系统的写速度,在Bootloader中的内存域为” .mem_cnb”。

non-cached, buffered,不可Cached,写缓存开启。CPU每次读写均不会Cache命中,CPU写数据时写入缓存后立即继续执行,缓存随后更新到主存。未用Cache功能,CPU读写性能相对低下,在Bootloader中的内存域为” .mem_ncb”。

non-cached, non-buffered,不可Cached,未开启写缓存。CPU每次读写均从主存读写,由于主存的缓慢,这种模式读写性能低下,在Bootloader中的内存域为” .mem_ncnb”。

对于RGB显存,除了写回模式外,其它模式写均会更新主存,不存在显示的一致性问题,为了达到最高的CPU性能,RGB显存应分配在写通模式内存区。

//16 bit(565)

uint16_tDisplayBuffer[HSize*VSize] @ ".mem_cnb"; // cached, write through

同时,对于数据DMA,为保证数据一致性总是,可用最简单的方式,DMA区域内存分配到non-cached, non-buffered域,虽然牺牲性能,但没有Cache一致性问题。

uint32_tDMA_Buffer[xxx] @ ".mem_ncnb";

2.2. 触摸屏驱动

触摸屏驱动主要提供有触摸时返回触摸点X位置接口TP_GetPoint1_X和返回触摸点Y位置接口TP_GetPoint1_Y给uCGUI即可。笔者使用的是电容屏,一般电容屏均是使用I2C接口,因此必须先实现I2C驱动。电容屏一般支持多点触摸,但uCGUI只支持单点触摸,因此电容屏中断输出配置成查询方式,通过查询中断线的电平状态来确定有无触摸事件。

int32_tTP_GetPoint1_X(void)

{

uint8_t Point1_X[2];

if (!(GPH0DAT_REG & FT5206_INT)) { // 触屏按下时,INT拉低

// 获得12位X轴坐标

TP_ReadRegs(FT5206_TOUCH1_XH, Point1_X,2);

if (!(GPH0DAT_REG & FT5206_INT)) {

//获得AD时应保持按下,不然AD值可能不准确,应丢弃

return((((int32_t)(Point1_X[0]&0xf)) << 8) | Point1_X[1]);

}

}

return -1; //返回无效值,表未按下或释放了

}

int32_tTP_GetPoint1_Y(void)

{

uint8_t Point1_Y[2];

if (!(GPH0DAT_REG & FT5206_INT)) { // 触屏按下时,INT拉低

// 获得12位Y轴坐标

TP_ReadRegs(FT5206_TOUCH1_YH, Point1_Y,2);

if (!(GPH0DAT_REG & FT5206_INT)) {

//获得AD时应保持按下,不然AD值可能不准确,应丢弃

return((((int32_t)(Point1_Y[0]&0xf)) << 8) | Point1_Y[1]);

}

}

return -1; //返回无效值,表未按下或释放了

}

int32_tTP_WriteRegs(uint8_t WriteAddr, uint8_t *pData,uint8_t Len)

{

uint8_t Packet[64];

uint8_t i;

if (Len >= sizeof(Packet)) {

return -1;

}

Packet[0] = WriteAddr;

for (i=0; i<Len; i++) {

Packet[i+1] = pData[i];

}

return I2C_WriteBytes(FT5206_ADDR, Packet,Len+1);

}

int32_tTP_ReadRegs(uint8_t ReadAddr, uint8_t *pData, uint8_t Len)

{

int32_t Ret;

// 写需读取的内部寄存器地址

Ret = I2C_WriteBytes(FT5206_ADDR,&ReadAddr, 1);

if (Ret == 0) {

return I2C_ReadBytes(FT5206_ADDR, pData,Len);

}

return Ret;

}

2.3. 定时器驱动

uCGUI通过OS_TimeMS来作为时基,因此需要一个定时器实现1ms/tick更新OS_TimeMS这个时基计数器。此处采用S5PV210的Timer4,初始化并注册相应的中断后,在其中断回调函数更新OS_TimeMS,同时处理uCGUI约100HZ频率查询触摸屏输入任务。

uint8_tTP_Period;

staticvoid Timer4_Callback(void)

{

extern volatile int OS_TimeMS;

OS_TimeMS++; // 1ms计数,在GUI_X.c中定义,用来uCGUI延时计数

#ifGUI_SUPPORT_TOUCH

TP_Period++;

if (TP_Period >= 10) { // 每隔10ms检查触摸屏输入

TP_Period = 0;

IRQ_DisableInt(INT_TIMER4); // 禁止同一中断重入

IRQ_Enable(); // 在定时器中断处理中允许I2C嵌套中断

GUI_TOUCH_Exec(); // 保证100HZ的触摸屏输入检查

IRQ_EnableInt(INT_TIMER4);

}

#endif

}

3. uCGUI修改

3.1. GUIConfig目录

进入GUIConfig目录,打开GUIConf.h对GUI进行总体的配置,由于内存充足,可以设置较大的动态内存以及支持内存设备,此处并不支持操作系统以及鼠标。修改后的内容如下:

#ifndef GUICONF_H

#define GUICONF_H

#define GUI_OS                    (0)  /* 不支持多任务 */

#defineGUI_SUPPORT_TOUCH         (1)  /* Support a touch screen (req. win-manager)*/

#define GUI_SUPPORT_MOUSE         (0) /* 不支持鼠标 */

#defineGUI_SUPPORT_UNICODE       (1)  /* Support mixed ASCII/UNICODE strings */

#defineGUI_DEFAULT_FONT         &GUI_Font6x8

#defineGUI_ALLOC_SIZE            (4*1024*1024)  /* 动态内存4M*/

/*********************************************************************

*

*         Configuration of available packages

*/

#defineGUI_WINSUPPORT            1  /* Window manager package available */

#defineGUI_SUPPORT_MEMDEV        1  /* Memory devices available */

#defineGUI_SUPPORT_AA            1  /* Anti aliasing available */

#endif  /* Avoidmultiple inclusion */

打开LCDConf.h对LCD进行配置,笔者使用的是16位(R:5-G:6-B:5)色深800*480的RGB屏,清空LCDConf.h中的所有内容,因为这是其它LCD屏的配置,与所用屏完全不一致,修改后的内容如下:

#ifndef LCDCONF_H

#define LCDCONF_H

/*********************************************************************

*                   Generalconfiguration of LCD

**********************************************************************

*/

#define LCD_XSIZE          (800)      /* 屏X水平像素点 */

#define LCD_YSIZE          (480)      /* 屏Y水平像素点 */

#define LCD_BITSPERPIXEL   (16)     /* 16位色深*/

#define LCD_CONTROLLER     (-1)       /* 宏开关,使用LCDDriver下的模板 */

#define LCD_FIXEDPALETTE   (565)      /* R:5-G:6-B:5 */

#define LCD_SWAP_RB        (1)      /*RB颜色调换 */

#define LCD_SWAP_XY        (0)      /* 屏x,y方向不调换 */

#define LCD_INIT_CONTROLLER()   Display_Init()/* 屏驱动初始化接口 */

#endif /* LCDCONF_H */

打开GUITouchConf.h对触摸屏进行配置,笔者使用的是电容屏,驱动IC已处理好返回的触摸坐标值与屏像素坐标一一对应,也可以在移植后进行校准。

#ifndefGUITOUCH_CONF_H

#defineGUITOUCH_CONF_H

#define GUI_TOUCH_AD_LEFT    0   /* 触摸屏能返回最左边的值 */

#defineGUI_TOUCH_AD_RIGHT   800  /* 触摸屏能返回最右边的值 */

#defineGUI_TOUCH_AD_TOP     0    /* 触摸屏能返回最上面的值 */

#defineGUI_TOUCH_AD_BOTTOM  480  /* 触摸屏能返回最下面的值 */

#defineGUI_TOUCH_SWAP_XY    0    /* 触摸屏x,y方向不调换  */

#defineGUI_TOUCH_MIRROR_X   0    /* 触摸屏x方向不镜像调换*/

#defineGUI_TOUCH_MIRROR_Y   0    /* 触摸屏y方向不镜像调换*/

#endif /*GUITOUCH_CONF_H */

3.2. LCDDriver目录

进入GUI->LCDDriver目录,需修改uCGUI关于实际LCD的底层接口调用。由于我们在LCDConf.h里配置LCD_CONTROLLER为-1,这个宏开关会选择LCDTemplate.c这个模板文件进行编译,其它的接口文件不会被编译。LCDTemplate.c里面已经有相关的模板代码,只需加入LCD_L0_SetPixelIndex()和LCD_L0_GetPixelIndex()的实现即可,LCD_L0_SetPixelIndex设置LCD某一坐标的像素值,LCD_L0_GetPixelIndex从LCD某一坐标读出像素值,分别对应RGB屏驱动底层函数Display_SetPixel
()和Display_GetPixel()。加入这两个底层函数即可。

LCD_L0_SetPixelIndex()修改后代码如下:

void LCD_L0_SetPixelIndex(int x, int y, int PixelIndex) {

GUI_USE_PARA(x);

GUI_USE_PARA(y);

GUI_USE_PARA(PixelIndex);

/* Convert logical into physicalcoordinates (Dep. on LCDConf.h) */

#if LCD_SWAP_XY | LCD_MIRROR_X|LCD_MIRROR_Y

int xPhys = LOG2PHYS_X(x, y);

int yPhys = LOG2PHYS_Y(x, y);

#else

#define xPhys x

#define yPhys y

#endif

/* Write into hardware ... Adapt toyour system */

{

Display_SetPixel(x, y, (unsignedshort)PixelIndex);

}

}

LCD_L0_GetPixelIndex()修改后的代码如下:

unsigned int LCD_L0_GetPixelIndex(int x, int y) {

LCD_PIXELINDEX PixelIndex;

GUI_USE_PARA(x);

GUI_USE_PARA(y);

/* Convert logical into physicalcoordinates (Dep. on LCDConf.h) */

#if LCD_SWAP_XY | LCD_MIRROR_X|LCD_MIRROR_Y

int xPhys = LOG2PHYS_X(x, y);

int yPhys = LOG2PHYS_Y(x, y);

#else

#define xPhys x

#define yPhys y

#endif

/* Read from hardware ... Adapt toyour system */

{

PixelIndex= (LCD_PIXELINDEX)(Display_GetPixel(x, y));

}

return PixelIndex;

}

3.3. GUI_X目录

GUI启动前,除了LCD可能还有其它需初始化的硬件设备,例如uCGUI要用到LCD以及触摸屏,那么在GUI使用前就应先初始化这些设备,这部分在GUI_X_Init()函数中处理,在GUI_X_Init()函数中实现如下:

void GUI_X_Init(void)

{

#if GUI_SUPPORT_TOUCH

TP_Init();// 使用uCGUI时先初始化触摸屏

#endif

}

GUI_X_Touch.c为uCGUI触摸屏访问接口,只要实现GUI_TOUCH_X_MeasureX()和GUI_TOUCH_X_MeasureY()即可。这两个函数分别与电容屏驱动获得第一个触摸点x,y位置的底层函数TP_GetPoint1_X()与TP_GetPoint1_Y()对应。

int  GUI_TOUCH_X_MeasureX(void) {

return TP_GetPoint1_X();

}

int  GUI_TOUCH_X_MeasureY(void) {

return TP_GetPoint1_Y();

}

4. uCGUI  Demo应用

应用程序中调用相应的uCGUI的例程Demo,其效果如下:

5. 附录

S5PV210_uCGUI.rar,uCGUI在IAR下的移植工程,包括S5PV210 Bootloader、uCGUI源码、以及相应的RGB、TP、I2C、Timer驱动。

http://pan.baidu.com/s/1sj1F2W1

时间: 2024-08-24 21:28:17

S5PV210开发系列四_uCGUI的移植的相关文章

S5PV210开发系列八_Yaffs的移植

S5PV210开发系列八 Yaffs的移植 象棋小子    1048272975 Nand作为市面上最基本的非易失性闪存技术之中的一个,应用在各种固态大容量存储解决方式中.因为Nand flash自身的特点,Nand存储器往往须要一款专用的Nand文件系统进行管理.开源的Yaffs文件系统因为其优异的性能,在Nand flash中受到广泛的应用,笔者此处就Yaffs的移植作一个简单的介绍. 1. Yaffs概述 Yaffs是由Aleph One公司所发展出来的Nand flash文件系统,专门为

S5PV210开发系列六_Fatfs的移植

S5PV210开发系列六 Fatfs的移植 象棋小子    1048272975 对于固态存储器,其存储容量可以很大,往往需要一款文件系统对存储器用户数据进行组织文件的管理.它对文件存储器空间进行组织和分配,负责文件的存储并对存入的文件进行保护和检索.在嵌入式系统中,往往需要采用windows兼容的文件系统,像相机的照片.视频监控.语音产品等,很多都需要从windows计算机上提取资源或在windows计算机上进一步处理.Fatfs由于其开源免费,支持fat32,受到了广泛的应用,笔者此处就S5

S5PV210开发系列一_开发环境以及启动模式

S5PV210开发系列一 开发环境以及启动模式 象棋小子          1048272975 ARM核以其高性能.低功耗.低成本广泛应用在各个领域,包括ARM7.ARM9.ARM11.Cortex-M.Cortex-A等这几个系列.众多的半导体商如NXP.Freescale.Atmel.Samsung.TI等都设计了基于ARM核的自家通用处理器,ARM核从低成本控制处理器到高性能应用处理器,已经深入到我们生活的方方面面.笔者此处就Samsung的Cortex-A8处理器S5PV210作一个简

S5PV210开发系列七_Nand驱动实现

S5PV210开发系列七 Nand驱动实现 象棋小子    1048272975 Nand flash具有大容量.改写速度快.接口简单等优点,适用于大量数据的存储,为固态大容量存储提供了廉价有效的解决方案.各种电子产品中如手机存储器.sd卡.u盘等均采用Nand flash存储,笔者此处就Nand驱动实现作一个简单的介绍. 1.  Nand flash概述 东芝公司在1989年最先发表Nand flash结构,强调降低每比特的成本,更高的性能,并且像磁盘一样可以通过接口轻松升级.随着Nand技术

S5PV210开发系列三_简易Bootloader的实现

S5PV210开发系列三 简易Bootloader的实现 象棋小子          1048272975 Bootloader是嵌入式系统上电后第一段执行的代码.对于功能简单的处理器,可能并没有Bootloader的概念,但对于应用处理器,有不同的启动方式,不同的存储设备(Nand flash.sd/mmc.DDR2.SRAM等),不同的操作系统等,往往需要一个Bootloader先初始化CPU和相关的硬件,建立内存空间映射,把内核或应用程序加载到相应的内存执行位置,最后调用内核或应用程序,释

S5PV210开发系列五_sd卡驱动实现

S5PV210开发系列五 sd卡驱动实现 象棋小子    1048272975 SD卡(Secure Digital Memory Card)具有体积小.容量大.数据传输快.可插拔.安全性好等优点,被广泛应用于便携式设备上.例如作为数码相机的存储卡,作为手机.平板多媒体扩展卡用的TF卡(micro sd).笔者此处就S5PV210的 sd卡驱动实现作一个简单的介绍. 1. sd卡概述 sd卡技术是在MMC卡的基础上发展起来的,其尺寸与MMC卡一样,只是比MMC卡厚了0.7mm,因此sd设备可以识

BizTalk 开发系列(四十一) BizTalk 2010 BAM 安装手记

使用64位系统可以支持更大的内存,现在服务器基本上都使用64位系统.微软从Windows Server 2008 R2开始服务器版的操作系统也只支持64位了,不过对于像BizTalk这种“繁杂的东西”在64位系统下确实增添了不少麻烦. 微软于9月底正式发布了面向企业SOA解决方案的最新产品BizTalk Server 2010.最新想搭一个最新的环境.本为装了BizTalk不下百遍的我,应该可以很快就搞起来.但是这次安装太纠结了.特别是在BAM方面,竟然耗了近 两天(白天上班)才搞定.是不是技术

BizTalk 开发系列(四十二) 为BizTalk应用程序打包不同的环境Binding

我们在使用微软或者其他公司提供的BizTalk应用程序MSI包的时候经常会有一个目标环境的选择选项.该选项可以在不同的环境下使用不同的绑定(BizTalk应用程序配置)感觉很高级. 其实这个非常的简单,只需要两个步骤: 第一, 针对不同环境配置不同的Binding文件,具体你可以先把BizTalk应用程序配置为开发环境(比如相应的路径.数据库连接等).然后导出Binding文件.然后再发为生产环境的配置再导出成Binding文件. 第二, 点击BizTalk Application的Resour

BizTalk 开发系列(四十) BizTalk WCF-SQL Adapter读取SQL Service Broker消息

SQL Service Broker 是在SQL Server 2005中新增的功能.Service Broker 为 SQL Server 提供队列和可靠的消息传递,可以可用来建立以异步消息为基础的应用.当然从题目大家可能也看出来了.我们本文主要不是为了讲SQL Service Broker(SSB),而是讲一下如何使用BizTalk WCF-SQL Adapter来访问SSB的数据. SQL Service Broker(SSB) 为要便于大家更好的接下来的示例,我们还是概况的讲一下SSB的