ucgui移植

来源:互联网 发布:linux mplayer 命令 编辑:程序博客网 时间:2024/06/10 02:52

             关于ucgui的移植,网上多是stm32上的或者是带fb设备的板卡上的移植,由于我用的板卡不支持fb,所以整个移植是建立在v4l2的基础上的,由于不懂驱动什么的,纠结了快一个月,磕磕巴巴地终于在昨天成功移植,真的是很感谢热情如火的大神,所以在这里也分享一下自己的移植心得,希望有一天也能帮到某个需要的人。


硬件平台:SEET-DVS6467

UCGUI版本:3.90

 

下载ucgui源码

----Sample                                                                  

----Start         

----Tool                                                                   

在做移植的时候,把Sample中的GUI_X中的GUI_X.c、Start中的GUI和Config拷出来放在一个文件夹下。

由于板卡没有framebuffer硬件,所以需要通过v4l2提供显示接口,由此,需要将v4l2和ucgui的LCD驱动接口相连。

需要修改的有四个地方:

1、首先是配置文件,Config中的GUIConf.h和LCDConf.h,

GUIConf主要是图形化界面的相关配置,主要修改如下:

#defineGUI_OS                    (1)  /* Compile with multitasking support */

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

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

#defineGUI_DEFAULT_FONT         &GUI_Font6x8

#defineGUI_ALLOC_SIZE          25*1024 /* Size of dynamic memory ... For WM and memory devices*/

#defineGUI_WINSUPPORT            1  /* Window manager package available */

#defineGUI_SUPPORT_MEMDEV        1  /* Memory devices available */

#defineGUI_SUPPORT_AA            1  /* Anti aliasing available */

LCDConf主要是显示器的相关配置,主要修改如下:

#defineLCD_XSIZE      (720)   /* X-resolution of LCD, Logical coor. */

#defineLCD_YSIZE      (576)  /* Y-resolution of LCD, Logical coor. */

#defineLCD_BITSPERPIXEL (8)

#defineLCD_CONTROLLER (-1)

 

2、其次是GUI_X.c中初始化部分,在初始化过程中最关键是要实现v4l2的初始化,申请缓存区,映射到用户空间,将缓存区加入缓存队列(在initDisplay中实现),获得缓存区地址赋给全局变量video_buffer,然后打开流,具体实现如下:

void GUI_X_Init(void) {

int                             i= 0,ret = 0;

struct v4l2_format        display_fmt;

int                                      display_numbuffers= MAX_BUFFER;

char                                    dev[40];

AddrObj                            *display_buff;

sprintf(dev,"/dev/video%d",2);

/* open display channel */

ret = initDisplay(&display_fd,dev,&display_numbuffers,"COMPOSITE", "PAL",&display_fmt);

if(ret < 0) {

printf("Error in opening display device\n");

return ret;

                              }

ret = startDisplay(&display_fd);

if(ret < 0) {

printf("Error in starting display\n");

return ret;

                              }

                    }

 

static int initDisplay(int *display_fd, char *devname, int*numbuffers, char *outputname,char *stdname, struct v4l2_format *fmt)

{

                    int mode =O_RDWR, j;

                    structv4l2_buffer buf;

                    int ret,i=0;

                    structv4l2_requestbuffers reqbuf;

                    charcommand[80];

                    video_buffer=(char*)malloc(sizeof(char)*576*720);

                   

                    strcpy(command,"echo ");

                    strcat(command,outputname);

                    strcat(command," > ");

                    strcat(command,OUTPUTPATH);

                    if(system(command)){

printf("Cannot set the output\n");

return -1;

                    }

                    /* Set modewhich is same as the one detected in the capture */

strcpy(command, "echo ");

strcat(command, stdname);

strcat(command, " >");

strcat(command, STDPATH);

if(system(command)) {

            printf("Cannotset the output\n");

            return -1;

}

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

            display_buff_info[i].start= NULL;

}

/* Open the channel-2 displaydevice */

                    *display_fd= open((const char *)devname, mode);

                    if(*display_fd<= 0) {

                              printf("Cannotopen %s\n",devname);

                              return-1;

                    }

                    reqbuf.type= V4L2_BUF_TYPE_VIDEO_OUTPUT;

                    reqbuf.count= *numbuffers;

                    reqbuf.memory= V4L2_MEMORY_MMAP;

                    ret =ioctl(*display_fd, VIDIOC_REQBUFS, &reqbuf);

                    if (ret< 0) {

                              perror("cannotallocate memory\n");

                              return-1;

                    }

                    /* Storethe numbfer of buffers allocated */

                    *numbuffers= reqbuf.count;

                    /* It isbetter to zero all the members of buffer structure */

                    memset(&buf,0, sizeof(buf));

                    /* Mmap thebuffers

                     * To access driver allocated buffer inapplication space, they have

                     * to be mmapped in the application space usingmmap system call */

                    for(i = 0 ;i < reqbuf.count ; i ++) {

                              /*Query physical address of the buffers */

                              buf.index= i;

                              buf.type= V4L2_BUF_TYPE_VIDEO_OUTPUT;

                              buf.memory = V4L2_MEMORY_MMAP;

                              ret= ioctl(*display_fd, VIDIOC_QUERYBUF, &buf);

                              if(ret < 0) {

                                     perror("VIDIOC_QUERYCAP\n");

                                     return-1;

                              }

                              /*Mmap the buffers in application space */

                              display_buff_info[i].length= buf.length;

                              display_buff_info[i].index= i;

                              display_buff_info[i].start=

                                     mmap(NULL,buf.length, PROT_READ | PROT_WRITE,

                                   MAP_SHARED,*display_fd, buf.m.offset);

                              if((unsigned int) display_buff_info[i].

                                     start == MAP_SHARED) {

                                     printf("Cannotmmap = %d buffer\n", i);

                                     return-1;

                              }

                              display_buff_phy[i]=buf.m.offset;

                              /*It is better to zero buffers */

                              memset(display_buff_info[i].start,0x80,

                          display_buff_info[i].length);

printf("%d\n",display_buff_info[i].length);

                    }

                    video_buffer=display_buff_info[buf.index].start;

                    printf("phy=%x\n",display_buff_phy[buf.index]);

                    printf("vir=%x\n",video_buffer);

                    /* Enqueuebuffers

                     * Before starting streaming, all the buffersneeds to be en-queued

                     * in the driver incoming queue. */

                    /* Enqueuebuffers */

                    for (i = 0;i < reqbuf.count; i++) {

                              buf.type= V4L2_BUF_TYPE_VIDEO_OUTPUT;

                              buf.memory = V4L2_MEMORY_MMAP;

                              buf.index= i;

                              ret= ioctl(*display_fd, VIDIOC_QBUF, &buf);

                              if(ret < 0) {

                                     perror("VIDIOC_QBUF\n");

                                     return-1;

                              }

                    }

                    fmt->type= V4L2_BUF_TYPE_VIDEO_OUTPUT;

                    ret =ioctl(*display_fd, VIDIOC_G_FMT, fmt);

                    if(ret <0) {

                              perror("VIDIOC_G_FMT\n");

                              return-1;

                    }

                     printf("width=%d,heigth=%d\n",fmt->fmt.pix.width,fmt->fmt.pix.height);

                    return 0;

}

 

3、由于V4L2是输入输出实际就是在维护一个缓存区队列,所以在对缓存区进行修改后,需要放进队列中,并且在队列中获取新的一个缓存区,所以还需要修改GUI/Core/GUI_Exec.c,

           int GUI_Exec(void) {

                                         int r = 0;

                                         while (GUI_Exec1()) {

                                      r = 1;                  /* We have done something */

                                    }

                                     if(r==1)

                                    {

                                      AddrObj               *display_buff;

                                      int                 ret=0;

                                      ret = putDisplayBuffer(&display_fd, 3,video_buffer);

                             if(ret < 0) {

            printf("Error in put displaybuffer\n");

            return ret;

}

          display_buff=getDisplayBuffer(&display_fd);

          if(NULL == display_buff) {

              printf("Error in get displaybuffer\n");

              return ret;

}

          }

             return r;

       }

4、最后需要做的就是重写LCD驱动函数,其实需要重写的只有两个,分别是LCD_L0_GetPixelIndex和LCD_L0_SetPixelIndex,利用前面得到的用户空间地址video_buffer进行读写

LCD_L0_GetPixelIndex修改如下:

/* Read fromhardware ... Adapt to your system */

  {

PixelIndex = video_buffer[yPhys*720+xPhys];

  }

类似的,LCD_L0_SetPixelIndex的修改如下:

  /* Write into hardware ... Adapt to yoursystem */

  {

     video_buffer[yPhys*720+xPhys]=PixelIndex;

  }

 

至此,ucgui的移植修改全部结束。需要注意的是,video_buffer应该是char类型,因为我的显示器是8bpp,之前因为设的是int产生了横向的偏移。


0 0
原创粉丝点击