移植uCGUI 3.98 到 LINUX

ucgui的可移植性很高,只需要做很少的改动就可以移植到各个平台,移植到Linux下也一样。

首先编辑GUIConf.h这个文件:

#ifndef GUICONF_H
#define GUICONF_H

#define GUI_OS    (1)                                          /* Compile with multitasking support */
#define GUI_SUPPORT_TOUCH     (0)                 /* Support a touch screen (req. win-manager), for linux */
#define GUI_SUPPORT_UNICODE     (1)              /* Support mixed ASCII/UNICODE strings, for linux */

#define GUI_DEFAULT_FONT     &GUI_Font6x8
#define GUI_ALLOC_SIZE     25*1024                  /* Size of dynamic memory */

#define GUI_SUPPORT_CURSOR     (1)              /* for linux*/
         

#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 */

     接着修改LCDConf.h文件,因为我们直接使用framebuffer设备,所以只需要修改LCDConf.h文件的前面部分即可:

#define LCD_XSIZE (720)                                    /* X-resolution of LCD, Logical coor. for linux */
#define LCD_YSIZE (576)                                    /* Y-resolution of LCD, Logical coor. for linux */

#define LCD_BITSPERPIXEL (16)                        /* for linux */

#define LCD_SWAP_RB (1)                                 /* for linux, actually 1555 format */
#define LCD_FIXEDPALETTE (555)                    /* for linux, actually 1555 format */
#define LCD_CONTROLLER (-1)                         /* for linux */

       接下来修改LCDDummy.c,添加对framebuffer的支持:

/* for linux framebuffer */

#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#include <sys/ioctl.h>

static struct fb_var_screeninfo vinfo;
static struct fb_fix_screeninfo finfo;
static char *pFrameBuffer = NULL;

........................................................

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

{
      /* Convert logical into physical coordinates (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

      int location = 0; 
      location = (x + vinfo.xoffset) * (vinfo.bits_per_pixel >> 3) + (y+vinfo.yoffset) * finfo.line_length;
      *(short*)(pFrameBuffer + location) = (short)PixelIndex; /* 16bpp */

      return; 
}

unsigned int LCD_L0_GetPixelIndex(int x, int y)

{
      LCD_PIXELINDEX PixelIndex;
      /* Convert logical into physical coordinates (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 to your system */
     {
          int location = 0; 
          location = (x + vinfo.xoffset) * (vinfo.bits_per_pixel >> 3) + (y+vinfo.yoffset) * finfo.line_length;
          PixelIndex = *(short*)(pFrameBuffer + location); /* 16bpp */
      }
      return PixelIndex;
}

....................................................

int LCD_L0_Init(void) 
{
     int f_fbDev;
     int ScreenSize;
     static struct fb_bitfield g_r16 = {10, 5, 0};
     static struct fb_bitfield g_g16 = {5, 5, 0};
     static struct fb_bitfield g_b16 = {0, 5, 0};
     static struct fb_bitfield g_a16 = {15, 1, 0};

     f_fbDev = open("/dev/fb0", O_RDWR);
     if (f_fbDev <= 0) 
     {
           printf("Error: cannot open framebuffer device.\n");
           return (-1);
     }

     if (ioctl(f_fbDev, FBIOGET_VSCREENINFO, &vinfo) < 0) 
    {
          printf("Error reading variable information.\n");
          close(f_fbDev);
          return (-1);
    }
    vinfo.xres = vinfo.xres_virtual = 720;
    vinfo.yres = 576;
     vinfo.yres_virtual = 576*2;

     vinfo.transp= g_a16;
     vinfo.red = g_r16;
     vinfo.green = g_g16;
     vinfo.blue = g_b16;
     vinfo.bits_per_pixel = 16;
     if (ioctl(f_fbDev, FBIOPUT_VSCREENINFO, &vinfo) < 0)
     {
            printf("Put variable screen info failed!\n");
            close(f_fbDev);
            return -1;
     }

     if (ioctl(f_fbDev, FBIOGET_FSCREENINFO, &finfo)) 
     {
           printf("Error reading fixed information.\n");
           return -1;
     }

     printf("xres is %d\n, yres is %d\n", vinfo.xres, vinfo.yres);
     ScreenSize = vinfo.xres * vinfo.yres * (vinfo.bits_per_pixel >> 3);

     pFrameBuffer =(char *)mmap(0, ScreenSize, PROT_READ | PROT_WRITE, MAP_SHARED,f_fbDev, 0);
     if ((long)pFrameBuffer == -1) 
    {
           printf("Error: failed to map framebuffer device to memory.\n");
           close(f_fbDev);
           return (-1);
    }

    return 0; 
}

     至此,LCDDummy.c修改完毕。

     接下来添加鼠标支持,新建一个GUI_MOUSE_DriverLinux.c代替原来的GUI_MOUSE_DriverPS2.c,这里的思路是用一个线程来读取鼠标设备:

.................................................

void *ThreadReamMouse(void)
{
     int ret;
     int fd;
     fd_set readfs; 
     int maxfd = 0;
     char temp[3];

      fd = open ("/dev/mouse0",O_RDWR);
      if (fd < 0) 
      {
             printf ("%s open failed\n", "/dev/mouse0");
             return NULL;
       }
       printf("open %s success, fd is %d\n", "/dev/mouse0", fd);

       maxfd = fd + 1;  
       for (; ;)
      {
              FD_ZERO(&readfs); 
              FD_SET(fd, &readfs); 
              ret = select(maxfd, &readfs, NULL, NULL, NULL);
              if (ret < 0)
             {
                    printf("select failure!\n");
                    return NULL;
             }

            if (FD_ISSET(fd, &readfs))
            {  
                       /*
                        * 读取鼠标
                        */
                      _NumBytesInBuffer = read(fd, _abInBuffer, sizeof(_abInBuffer));
                     if ((_NumBytesInBuffer == 3) && ((_abInBuffer[0] & 0x0c) == 0x08))
                     {
                             _EvaPacket();
                             //printf("Get mouse data!\n");
                      }
              } 
     }
}


void GUI_MOUSE_DRIVER_PS2_Init(void) 
{
           pthread_t pidReadMouse; 

           _NumBytesInBuffer = 0; 

           pthread_create(&pidReadMouse, NULL, (void *)ThreadReamMouse, NULL);
           printf("Create thread sucess!\n");
}

     GUI_MOUSE_DRIVER_PS2_Init()函数需要在哪里调用呢?不调用的话,鼠标没法用啊。增加GUI_X_Linux.c文件:

.............................................................

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

..............................................................


void GUI_X_ExecIdle(void)
{
       usleep(1000);
       return;
}


int GUI_X_GetTime(void)
{
       struct timeval tv;
        int tm;
        gettimeofday(&tv, NULL);
        tm = tv.tv_sec*1024 + tv.tv_usec/1024;
   

       return tm;
}


void GUI_X_Delay(int Period)
{
       while(Period--)
      {
               usleep(1000);
       }
       return;
}


void GUI_X_Unlock(void)
{
        pthread_mutex_unlock(&mutex);
        return;
}
void GUI_X_Lock(void)
{
       pthread_mutex_lock(&mutex); 
       return;
}
U32 GUI_X_GetTaskId(void)
{
       pthread_t id;

       id = pthread_self();
       printf("GUI_X_GetTaskId %d \n", (U32)id);
       return ((U32)id);
}
void GUI_X_InitOS(void)
{
       printf("GUI_X_InitOS\n");
       GUI_MOUSE_DRIVER_PS2_Init();                              /* create read mouse thread for linux */
       return;
}
.....................................................

      至此,该修改的文件都修改完毕了,可以开始编译了。但是ucgui的工程一般是在windows下编译的,在Linux下交叉编译需要写Makefile,按照Linux的惯例,在每个文件夹下增加Makefile,如下:

CC = arm-linux-gcc
CFLAGS=-I../Core -I../../Config/ -I../WM/

#all c files at current directory
SRCS:=$(wildcard *.c)

#replace .c to .o in SRCS
OBJS:=$(SRCS:%.c=%.o)

all:$(OBJS)

%.o : %.c
         $(CC) $(CFLAGS) -c $< -o $@

.PHONY : clean

clean:
         rm *.o

     再增加一个编译gui库的Makefile:


SUBDIRS=AntiAlias ConvertMono Font LCDDriver MemDev Widget ConvertColor Core JPEG MultiLayer WM
LIBOBJS=
LIBOBJS+=$(wildcard AntiAlias/*.o)
LIBOBJS+=$(wildcard ConvertMono/*.o)
LIBOBJS+=$(wildcard Font/*.o)
LIBOBJS+=$(wildcard LCDDriver/*.o)
LIBOBJS+=$(wildcard MemDev/*.o)
LIBOBJS+=$(wildcard ConvertColor/*.o)
LIBOBJS+=$(wildcard Core/*.o)
LIBOBJS+=$(wildcard JPEG/*.o)
LIBOBJS+=$(wildcard MultiLayer/*.o)
LIBOBJS+=$(wildcard WM/*.o)
LIBOBJS+=$(wildcard Widget/*.o)

all:
         for name in $(SUBDIRS); do (cd $$name && make && cd ../) done
         make guilib

.PHONY:guilib

guilib:
         arm-linux-ar rv libucgui.a $(LIBOBJS)


.PHONY:clean    

clean:
         @rm -f libucgui.a 
         @for name in $(SUBDIRS); do (cd $$name && make clean && cd ../) done

国庆长假又少了一天,不懂的东西还是很多,进展很慢呀,先把界面移植上来再折腾折腾linux吧,为明天而奋斗吧。
uC-GUI-V3-98-完整源码未删减版本,内容很全面。文件目录列表 ─uC-GUI ├─Doc ├─Sample │ ├─Application │ │ ├─Dashboard │ │ ├─NEC_BuildingManagem │ │ └─NEC_Pingpong │ ├─GUI │ │ ├─VSCREEN_MultiPage │ │ └─WIDGET_Checkbox │ ├─GUIDemo │ ├─GUI_X │ ├─LCDConf │ │ ├─LCD0323 │ │ ├─LCD07X1 │ │ ├─LCD1200 │ │ ├─LCD13701 │ │ ├─LCD1611 │ │ ├─LCD161620 │ │ ├─LCD1781 │ │ ├─LCD501 │ │ ├─LCD6331 │ │ ├─LCD66750 │ │ ├─LCD667XX │ │ ├─LCDColorOnMono │ │ ├─LCDFujitsu │ │ ├─LCDLin │ │ ├─LCDLin32 │ │ ├─LCDMem │ │ ├─LCDMemC │ │ ├─LCDPage1bpp │ │ ├─LCDPage4bpp │ │ ├─LCDSLin │ │ ├─LCDVesa │ │ └─LCDXylon │ ├─LCD_X │ └─MakeLib │ ├─8051_Keil │ ├─ARM_GNU │ ├─ARM_IAR │ ├─M16C_NC30 │ ├─M16C_TASKING │ ├─M32C_NC308 │ ├─MC80_IAR │ ├─MSP430_IAR │ ├─V850_GHS │ ├─WIN32_MSVC60 │ ├─WIN32_WATCOM │ └─X86_WC16 ├─Start │ ├─Application │ ├─Config │ ├─GUI │ │ ├─AntiAlias │ │ ├─ConvertColor │ │ ├─ConvertMono │ │ ├─Core │ │ ├─Font │ │ ├─LCDDriver │ │ ├─MemDev │ │ ├─MultiLayer │ │ ├─Widget │ │ └─WM │ └─System │ └─Simulation │ ├─Res │ ├─SIM_GUI │ │ └─Branding │ └─WinMain └─Tool
UCGUI 3.98 是一个非常有用的嵌入式图形用户界面库,它被广泛用于嵌入式系统的界面设计和开发中。移植UCGUI 3.98可以让我们在不同的硬件平台上使用它,并享受到它提供的各种功能。 首先,进行UCGUI 3.98移植前,我们需要考虑目标平台的硬件特性和操作系统的相关接口。因为UCGUI 3.98通常是在操作系统之上运行的,所以我们需要适配UCGUI 3.98与目标操作系统之间的接口。 其次,我们需要了解目标平台的显示驱动和输入设备驱动。UCGUI 3.98是一个图形用户界面库,它需要与硬件交互来实现图形的显示和用户输入的响应。因此,我们需要移植UCGUI 3.98的显示驱动和输入设备驱动,确保它们能够与目标平台兼容。 接着,我们需要把UCGUI 3.98的源码和头文件导入到我们的开发环境中。我们需要根据目标平台的编译器和代码组织规则,进行一些必要的修改和调整。我们还需要根据目标平台的内存和存储限制,对UCGUI 3.98的配置文件进行相应的修改。 然后,我们需要在目标平台上实现UCGUI 3.98所需的底层驱动和接口函数。这些包括显示驱动函数、输入设备驱动函数、内存管理函数等。这些驱动和接口函数的实现需要根据目标平台的硬件特性和操作系统的相关接口进行适配。 最后,我们需要对移植后的UCGUI 3.98进行一些测试和调试,确保它能够在目标平台上正常运行,并且能够满足我们的需求。 总之,移植UCGUI 3.98需要考虑目标平台的硬件特性、操作系统的相关接口、底层驱动的实现,以及对UCGUI 3.98源码和配置文件的修改。通过正确的移植和配置,我们可以在不同的嵌入式系统上使用UCGUI 3.98,并享受到它提供的强大功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值