ucgui移植(基于windml)

最近比较闲,就把ucgui移植到vxworks的windml上了。Ucugi本身如果直接移植到硬件的话会更有效率,但移植到windml上也有它的优势,比如移植过程比较简单,可以绕过各种硬件,直接在ugl提供的接口函数上操作,从而省去繁琐的硬件调试,而硬件调试恰恰是最容易出错的地方。还有就是使得ucgui能运行在任何支持windml的硬件环境上面,比如simpc、pentium机等,这对于缩短产品开发周期大有好处。至于效率方面,由于我们只需要使用windml最简单的ugl画图功能,所以只要CPU不是太差(比如桌面PC机就可以),那么多出一层windml导致的效率损失是完全可以忽略不计的。
 
首先总体介绍一下,我使用的是Tornado2.2+vxworks5.5+windml3.0+ugl3.4,硬件使用风河自带的simpc。色彩转换采用ugl和ucgui都支持的RGB565编码。
 
下面正式介绍移植过程:
 
LCD显示屏的移植
Ucgui中,对显示屏的支持只需要填写有限的几个函数即可:
LCD_L0_Init
LCD_L0_ReInit
LCD_L0_Off
LCD_L0_On
LCD_L0_DrawBitmap
LCD_L0_DrawHLine
LCD_L0_DrawVLine
LCD_L0_FillRect
LCD_L0_SetPixelIndex
LCD_L0_XorPixel
 
LCD_L0_Init中实现的是显示屏的初始化,移植时在这里填入ugl的初始化函数即可,另外我把ugl input的初始化操作也放在里面。
int LCD_L0_Init(void)
{
    int x,y;
 
    /* Initialize UGL */
    if (uglInitialize() == UGL_STATUS_ERROR)
        return;
 
    /* Obtain display device identifier */
    g_uglDevId = (UGL_DEVICE_ID)uglRegistryFind (UGL_DISPLAY_TYPE, 0, 0,0)->id;   
 
    /* obtain the input service identifier. */
    g_uglInputServiceId = (UGL_INPUT_SERVICE_ID)uglRegistryFind (UGL_INPUT_SERVICE_TYPE, 0, 0,0)->id;
 
    g_uglGc = uglGcCreate(g_uglDevId);
   
    for (y = 0; y < LCD_YSIZE; y++)
    {
        LCD_L0_DrawHLine(0, LCD_XSIZE-1, BKCOLORINDEX);
    }
 
    return 0;
}
 
ReInit我没有用到,所以这里是空的。
 
On和Off函数同样也没有用到。
 
DrawBitMap函数中不涉及硬件操作,最终它会调用SetPixelIndex函数,所以直接把demo中的函数实现复制过来即可。
 
DrawVLine和DrawHLine函数,ugl中与之对应的是uglLine,所以直接映射过去即可。
void LCD_L0_DrawHLine (int x0, int y, int x1)
{
    if (GUI_Context.DrawMode & LCD_DRAWMODE_XOR)
    {
        for (;x0 <= x1; x0++)
        {
            LCD_L0_XorPixel(x0, y);
        }
    }
    else
    {
        uglForegroundColorSet(g_uglGc, LCD_GetColorIndex());
        uglLine(g_uglGc, x0, y, x1, y);
    }
}
 
FillRect函数最终也是映射到DrawVLine或DrawHLine操作。
 
SetPixelIndex,这是最基本的绘图函数,这里因为我使用RGB565编码,所以直接把Index值传到ugl函数即可。
void LCD_L0_SetPixelIndex(int x, int y, int Index)
{
    uglPixelSet(g_uglGc, x, y, Index&0xffff);
}
 
XorPixel,对指定点的色彩进行异或操作,我的实现方法是这样:
void LCD_L0_XorPixel(int x, int y)
{
 unsigned int Index = COLO2INDEX LCD_L0_GetPixelIndex(x,y) ;
 
 LCD_L0_SetPixelIndex(x, y, ~Index);
}
 
色彩转换
Ucugi本身支持RGB565色彩转换,但它的RGB位图与ugl中RGB位图相反,这有点像Big Endian和Little Endian的区别。所以要将ucugi中rgb565的实现重写一遍,所幸比较简单,没花多长时间。
另外有一点我比较奇怪,ugl中SetPixelIndex使用的参数是RGB565格式,但GetPixelIndex得到的颜色是RGB绝对数值,这一点需要特别注意。
 
GUI_X.c文件
为了支持多任务,我们需要修改ucgui中的gui_x.c文件,这个文件的修改同样非常简单。
int GUI_X_GetTime(void)
{
    return tickGet();
}
 
void GUI_X_Delay(int Period)
{
    taskDelay(Period);
}
 
void GUI_X_ExecIdle(void) {
    taskDelay(1);
}
 
static SEM_ID g_bOSSem;
 
U32 GUI_X_GetTaskId(void)
{
    return (U32)taskIdSelf();
}
 
void GUI_X_InitOS(void)   
{
    g_bOSSem = semBCreate(SEM_Q_PRIORITY, SEM_FULL);
}
 
void GUI_X_Init(void) {}
 
void GUI_X_Unlock(void)
{
    semGive(g_bOSSem);
}
 
void GUI_X_Lock(void)
{
    semTake(g_bOSSem, WAIT_FOREVER);
}
 
void GUI_X_Log(const char *s){}
 
void GUI_X_Warn(const char *s){}
 
void GUI_X_ErrorOut(const char *s){}
 
鼠标键盘的支持
Ugl中已经替我们实现了鼠标键盘,只需调用uglInputMsgGet即可,得到ugl提供的鼠标键盘后,再调用GUI_StoreKeyMsg和GUI_PID_StoreState把鼠标键盘值传到ucgui中,最后别忘了调用WM_Exec。
    while(1)
    {
        timer = GUI_GetTime();
        status = uglInputMsgGet (g_uglInputServiceId, &msg, 200);
        if (status == UGL_STATUS_OK)
        {
            if (msg.type == MSG_KEYBOARD)
           {
                if (msg.data.keyboard.modifiers & UGL_KBD_KEYDOWN)
                {
                    key = msg.data.keyboard.key;
                    GUI_StoreKeyMsg(key, 1);
                    WM_Exec();
                    timer = GUI_GetTime();
                }
            }
            else if (msg.type == MSG_POINTER)
            {
                state.x = msg.data.pointer.position.x;
                state.y = msg.data.pointer.position.y;
                state.Pressed = msg.data.pointer.buttonState;
                GUI_PID_StoreState(&state);
                WM_Exec();
                timer = GUI_GetTime();
            }
        }
        if (GUI_GetTime() - timer >= 5)
        {
            WM_Exec();
        }
     }
 
附件是我移植时修改的文件,供参考。

 

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值