这是前些日子在使用uc/GUI的时候即下来的一些东西原来发布在EDACN的bbs上面。现在不知道沉到哪里去了。现在把它重新整理发布在这里。随后在明年过年的时候把后续的几个高级主题整理出来。
下面开始我的笔记!有兴趣的兄弟们可以来看看。
step1.
下载uC/GUI的代码。(废话没有源代码移植个鸟)
我下载的时uC/GUI3.32这是能得到的源代码中最全的一个版本。
看看里面都有些什么东西。由于这里的发间大小的限制的问题不能上传源代码。很是郁闷。有需要的同志可以联系我。Email:william7447@gmail.com
首先看看所有名叫Simulation的东西这是uC/GUI在VC中仿真的VC工程,他的仿真功能非常的实用可以在没有具体硬件的情况下先行开发软件,而丝毫不影响软件的兼容性。但是有一个问题比较郁闷,就是速度的问题。大家知道嵌入式系统的CPU运算能力有限,而电脑的cpu.........我的整个项目的gui是在电脑上完成的。拿到目标系统上面编译.......通过。
经过紧张的下载.....................
运行..........显示出了第一个画面,无比的兴奋。但测试发现极其郁闷而几乎无法解决的问题......目标系统的处理能力只有100mips而我的电脑的cpu是P4 3.0。速度的差别太大了。解决这个问题几乎成了我后半段工作的主题。
GUI文件夹存放全部uC/GUI源代码的地方
看看它的属性有多达390个文件,全部是.c和.h。可以看出GUI系统是一个庞大复杂的东西。我在调试系统的时候跟踪过完 整的消息循环再进入了60多个子函数调用后还没有看到希望,就彻底的放弃了跟踪的想法。下来会具体说明这里面都有些什么东西。
config文件夹uC/GUI的配置文件夹。里面存放的是uC/GUI的配置头文件。改动里面的相应的就可以改动uC/GUI的配置。
这个GUI功能十分强大。我也在探索之中。
这几天刚刚入门,只能说我自己的移植过程,以后陆续添上它的使用。有什么不对的地方大家请指出来。
uC/GUI移植之准备工作。
先来看看吧uC/GUI移植到NIOS II都要准备些什么东西。
首先就是要了解uC/GUI的源代码包括了一些什么东西。
前面提到了这个gui有两个文件夹一个GUI存放gui的核心文件,一个config为gui提供配置信息。
先看core里面有什么东西。
GUIAntiAlias 抗锯齿支持,看上去挺牛的。
根据对抗锯齿的使用发现,uC/GUI的抗锯齿的效果好坏主要取决于系统的发色数,即系统的色彩表现能力,例如系统仅有灰度显示能力的时候,uC/GUI在对一条直线进行处理的时候它是在直线的两侧添加颜色较浅的点来实现抗锯齿的。效果十分明显。
GUIConvertMono (b/w)和灰度显示的色彩转换支持。
GUIConvertColor 彩色显示的色彩转换支持
实际上就是色彩空间变换,为什么需要色彩转换呢?
在gui内部定义了一套调色板及色彩的数据格式,但是有的控制器的色彩数据格式和gui内部定义的并不一样,甚至色彩的数量(即lcd的发色数)也不同,这样就需要将两种不同的数据格式进行转换。这样才能在lcd上看到正常的颜色。
GUICore μC/GUI 核心文件,提供了GUI基本的功能,比如画点,画线,为图之类的东西。什么窗口,窗口控件都是基于这些基本功能的。
GUIFont 不用多说了
GUILCDDriver LCD控制器。下面会说这个东西。
GUIMemDev Memory device 支持。这个东西可用在很多情况下,但最主要的功能是防止在项目重叠时,防止屏幕的闪 烁。如果没有Memory device 的支持数据会直接写到控制器中去,这样当进行各种屏幕跟新的时候就会出现闪烁现象。如果有Memory device 支持,就会避免这种现象。具体的还没有测试,不过看说明是蛮牛的。关于这个东西会有一个较详细的测试。
GUITouch Touch-panel 支持。虽然说是支持,甚至连鼠标都支持,但是底层驱动程序的四个函数是空的需要用户自己添加内容,我们使用mxb7843这个四线电阻触摸屏控制器。班子还没有做好,做好就测试。
GUIWidget 窗体控件库,功能强大,提供诸如按钮,文本框之类的复杂的功能。
GUIWM 窗口库。
widget wm配合memory device使用功能强大。
下面看看CONFIG文件夹
三个文件:
GUIConf.h
GUITouchConf.h
LCDConf.h
看名字也知道干什么的了。
下面一个一个说。
#ifndef GUICONF_H
#define GUICONF_H
#define GUI_OS (1) /* 多任务支持,如果使用rtos就打开这个选项,除了自家的ucos,别的rtos也支持*/
#define GUI_SUPPORT_TOUCH (1) /* 支持触摸屏*/
#define GUI_SUPPORT_UNICODE (1) /*unicode字符串支持,能显示中文的哦,只要能把字库放进来,现在的问题我把字库放不进来,文件太大了,编译器限制,郁闷!*/
#define GUI_DEFAULT_FONT &GUI_Font6x8/*默认字体*/
#define GUI_ALLOC_SIZE 12500 /* WM 和 memory devices分配的动态内存*/
/*********************************************************************
*
* Configuration of available packages
*/
#define GUI_WINSUPPORT 1 /* Window manager package available */
#define GUI_SUPPORT_MEMDEV 1 /* Memory devices available */
#define GUI_SUPPORT_AA 1 /* Anti aliasing available */
这三个不用说了吧!
#endif /* Avoid multiple inclusion */
GUITouchConf.h这个文件........由于硬件不到位没有深入研究触摸这块还不太理解,日后补上。
LCDConf.h这个文件比较特别,随着控制器的不同,内容而不同。
如果针对的是硬件控制器,就会在这个文件里面定义控制器的基地址,所有的寄存器,显示内存的地址镜像关系,等等一系列硬件控制器的特征信息。当然了还会定义lcd的尺寸,调色板,等一些重要的信息。还有救治针对不同的lcd的设置,配置不同的控制器初始化代码。
还有一种就是MEM控制器。就是没有硬件控制器在内存里面申请一个和LCD物理象素点一一对应的内存区域作为显示缓冲区,然后由用户想办法把数据送到LCD上去。他给的例子里面是用定时中断来模拟LCD控制的控制时序,将数据流送到LCD上。在该模式下如果是一个很小lcd该方法很好节省了硬件成本。但是大量占用CPU刷新率低。如果lcd象素很高,那就是个问题了。但是在某些应用中不得不使用这种方式。在我的工程里面就使用了这种方式。
我的屏640*480*3bit。
这里有关硬件的控制器是一个大问题,即底层的驱动程序怎么办?uC/GUI提供了很多的芯片的驱动程序,但是如果选用的芯片没有怎么办?或者屏的参数比较奇怪怎么办?比如我用的屏640*480*3bit,就是8色的那种,一般的屏都是16色。我打算在过年的时候开一个有关驱动程序的专题,讨论这些问题。还有驱动程序的效率对整个gui的效率影响很大。
准备就这么多该说说移植了。
该移植了!
首先弄个NIOS II系统。
然后打开NIOS II IDE创建一个工程。
什么都可以!我使用的Hello World这个工程。使用例子的好处省心。
然后找到这个工程的在硬盘中的物理位置,将下载的代码中的两个文件夹GUI和config拷贝进去该软件工程的目录里面。
由于前一段的工作是基于Altera Fpga 的用的就是NIOS II处理器,后面我会专门针对arm来讨论相关的问题,最近的项目是基于arm9的。
图中就是copy好的目录。
然后回到NIOS II IDE refresh工程就能看到ide自动将这两个文件加添加进了工程,还有里面所有的文件。
但是不是所有的文件都是有用的,nios II的编译器会把所有的文件编译,这样在链接的时候就出问题了,因为有的文件是针对不同的配置写的。但是所有的都被编译了,这样子就导致大量的链接错误,无数重复定义。这就需要将无用的文件从工程中清除。一个地方就是LCDDrivers由于底层的绘图函数是在drivers里面定义的所以有多少个drivers就会有多少个同样名称的函数。这里就需要将无用的driver清除。还有一个地方就是gui/core里面GUI_DrawBMP.c和GUI_DrawBitmap.c着两个文件内容一模一样,一字不差!所以要清除一个!还有一个重要问题是文件的包含路径。nios ide不是自动添加文件包含路径的,用惯了ads的人特不习惯。而且在5.1包含路径设置位置比较难找!在这里添加四个路径:
E:FPGALcdsoftwarehello_world_0Config
E:FPGALcdsoftwarehello_world_0guiCore
E:FPGALcdsoftwarehello_world_0guiWM
E:FPGALcdsoftwarehello_world_0guiWidget
还有就是要在系统库中加上ucos。uC/GUIi默认打开多任务支持。
包含好了路径就可以编译了。
但是提示还有链接错误!
非常郁闷,怎么看也看不出来怎么回事。提示一个字体未定义!
关键还是默认字体!
经过仔细察看发现一个问题!!!!大家看看图就明白了!
NIOS II IDE使用java开发的,java大小写敏感!这点还是Windows作的好。
还有一个问题就是优化级别的问题,我发现在NIOS II系统里面most级别的优化和none的优化(就是不优化)执行速度能差2~3倍。特别是一些计算密集型的代码例如:crc和gui应用。
这回编译就没有错误了!GUI初步移植成功,下来测试一下!由于没有硬件支持只能看看软件的。调试工程用内存查看器,就看到了uC/GUI的运行的结果。
执行下面的语句:
int main() {
LCD_Part = 0;
alt_irq_register ( LCM_0_IRQ,
(void*)0,
LCD_isr);
alt_irq_enable(LCM_0_IRQ);
GUI_Init();
GUI_DispChar('A'); /*显示一个A*/
printf("Hello from Nios II! ");
while(1) {
}
return 0;
}
我用的是MEMC驱动程序,即把GUI执行的结果保存到内存中。这样子才有了直接察看内存来看结果BT方法。
可以在内存查看器中看到数据的变化(由于数据量巨大,只列出头几列的数据)
1f f0 00 ...
e0 0e 00 ...
e0 0e 00 ..
ff fe 00 ...
e0 0e 00 ..
e0 0e 00 ..
e0 0e 00 ..
00 00 00 ...
转化为二进制
000111111111000000
111000000000111000
111000000000111000
111111111111111000
111000000000111000
111000000000111000
111000000000111000
000000000000000000
我的屏是RGB三色屏共有8种颜色,0表示该点灭,1表示亮。3位表示一个彩色的象素点。能看出来由1组成了一个A吗?
GUI初步抑制成功,下面将探索它的各种功能。(这部分着在摸索,每天弄一点,跟新可能会很慢!)
使用MEMC是因为这种方式的移植最简单根本不牵扯硬件,而且因为项目经费紧张,不可能买一个独立的控制器,特别是体现不出来FPGA的优势。这里的控制器是一个自己写的小东西,实现的对LCD的控制,这部分正在测试,测试好了也会拿出来给大家共享的。
下来的几天主要测试uC/GUI的复杂应用。包括widget, wm这些东西。
uC/GUI Simulation的应用
uC/GUI提供了一格功能是强大的工具,即Simulation工具他可以在windows环境下模拟uC/GUI的运行结果,为GUI应用程序的开发体供了极大的方便,在模拟器上开发GUI应用程序代码可以几乎无修改的直接应用于目标硬件。
这个模拟器的原理是GUI程序运行后产生一个实时更新的BMP图片然后由gui模拟程序显示出来。这个功能作得太好了,这样子gui程序的开发简直是无敌了。
在下载的uC/GUI源代码中,解压后就能看到一个名叫Simulation的VC6Workspace和project。
在顶楼的图中可以清楚地看到这两个文件。这是uC/GUI的开发人员帮我们做好的。直接打开这个工程就可以在VC6中开发GUI应用程序,uC/GUI高度抽象,应用程序与底层很好的分离,这样为GUI应用程序的开发提供了极大的方便。
下面打开这工程看看里面有什么东西。我使用的VS.Net。没有什么区别,个人认为VS.Net的功能较VC6强大许多。是一个优秀的集成开发环境。
打开工程后我们看看里面都有些什么东西。
config和gui文件加我们前面都说过了,里面放的就是Gui的配置文件和gui的源代码。
这里面多了几个文件夹。
Application文件夹,用户存放应用程序文件的地方。
Simulation文件夹模拟器提供初始化和一些配置信息,我们根本不用改动这些东西。
System文件夹,大家知道每个C程序都有一个main函数,这里面就放了这一个东西。
还有一个地方,就是LCD_Driver这个文件夹里面放的是LCDWIN.c这样无论你怎么修改GUI的配置,模拟器都会使用这个驱动程序来实现GUI程序运行结果的正确的显示。
LCDWin.c就是基于windows模拟器的驱动程序,就是通过这个驱动生成模拟器里显示的bmp图片。
弄清楚这些东西,就可以开始uC/GUI编程了。
打开MainTask.c这个文件我们就在这里面编写我们的GUI应用程序。
#include "GUI.h"
extern const GUI_BITMAP bmMicriumLogo;
extern const GUI_BITMAP bmMicriumLogo_1bpp;
下面是自带的一段示例代码。
我们来看看她都干了些什么东西。
/*
*******************************************************************
*
* main()
*
*******************************************************************
*/
void MainTask(void) {
int Cnt =0;
int i,YPos;
int LCDXSize = LCD_GET_XSIZE();
int LCDYSize = LCD_GET_YSIZE(); /*取得lcd物理尺寸,这个参数是在lcdconf.h里面定义的*/
const GUI_BITMAP *pBitmap; /*一个指向预显示的位图的指针,在这里位图是在.c文件里面存储的ps:.c的体积大的吹牛*/
GUI_Init(); /*初始化GUI,这谁痘看得出来*/
/*这里面除了初始了在guiconf.h里面定义的时用的GUI的所有功能,包括widget,wm等功能的初始化,当然还有lcd的控制器的初始化*/
GUI_SetBkColor(GUI_RED); GUI_Clear(); /*设置背景颜色为RED,其结果如图*//*
/*说明一下这个模拟器的窗口,最大的那个窗口显示的就是GUI程序的运行结果。标题里显示的是当前LCD的配置参数,colors显示的当前gui系统能显示的所有的颜色,即调色板。log是gui的日志,这个功能会在后面说明*/
GUI_Delay(1000); /*延迟1000个时钟节拍,这里我们的gui是应用在ucos rtos上面,这里的时钟节拍就是ucos的时钟节拍*/
GUI_SetBkColor(GUI_BLUE); /*背景设为BLUE*/
GUI_Clear(); /*清除当前的window,没有窗口就清理整个屏幕*/
GUI_Delay(1000);
GUI_SetColor(GUI_WHITE);
for (i="0"; i<1000; i+=10) {
GUI_DrawHLine(i,0,100);
GUI_DispStringAt("Line ",0,i);
GUI_DispDecMin(i);
} /*这段代码的功能就是每隔10行显示文字line和一条直线。*/
GUI_Delay(1000);
GUI_SetColor(0x0); //设置显示颜色为黑色!?黑色对着呢!1时点亮0是熄灭你看看是不黑色。
GUI_SetBkColor(0xffffff);
for (i="0"; i<160; i++) {
int len = (i<80) ? i : 160-i;
GUI_DrawHLine(i,20,len+20);
} //显示一个三角形
GUI_Clear();
if (LCD_GET_YSIZE()>(100+bmMicriumLogo_1bpp.YSize)) {
pBitmap=&bmMicriumLogo; //设置要显示的位图为MicriumLogo
} else {
GUI_SetColor(GUI_BLUE);
pBitmap=&bmMicriumLogo_1bpp;
}
GUI_DrawBitmap(pBitmap,(LCDXSize-pBitmap->XSize)/2,10);
YPos="20"+pBitmap->YSize; //显示位图MicriumLogo
GUI_SetFont(&GUI_FontComic24B_1);
GUI_DispStringHCenterAt("www.micrium.com",LCDXSize/2,YPos); //在指定位置以FontComic24B_1字体显示文字www.micrium.com
GUI_Delay(1000);
GUI_SetColor(GUI_RED);
GUI_DispStringHCenterAt("?2002 ", LCDXSize/2,YPos+30);
GUI_SetFont(&GUI_Font10S_1);
GUI_DispStringHCenterAt("Micri祄 Inc.",LCDXSize/2,YPos+60);; //在指定位置以Font10S_1字体显示文字Micrium Inc
GUI_Delay(1000);
}
截图
一个完整的gui应用程序的例子就出来了。接下来将是gui应用程序的开发。
从最简单的文字到window到复杂的控件。
一步一步来,我也在学习。
在硬件控制器彻底搞定之前都将使用这个东西开发应用程序。
文章评论(0条评论)
登录后参与讨论