瑞芯微Rockchip开发者社区
直播中

罗星

8年用户 1612经验值
擅长:模拟技术
私信 关注
[经验]

基于VGA的Lubuntu分辨率自适应技术分享

首先,请先下载附件,该文件并非压缩包,下载后直接将后缀名改成.c即可,并将该文件cp到相应目录:kernel/drivers/video/rockchip/lcdc下,该文件修复了1440x900和1366x768两种分辨率的异常(兼容性有待考证),还有就是RGB颜色问题;准备工作做好之后,自行编译内核进行烧写;
然后,下面的代码便是自动适配分辨率的,这是一个单独的程序,需要各位网友自行cp进行编译,编译完成之后,只需要将执行路径添加到/etc/rc.local文件即可;若网友发现有问题,请相互交流。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define NUM_BUFFERS                 2
#define RK_FBIOSET_CLEAR_FB         0x4633
#if 0
#define DEBUG_P(format, ...) printf(format, ##__VA_ARGS__)
#else
#define DEBUG_P(format, ...)
#endif
int main(int argc, char *argv[])
{
        FILE *fp = fopen("/sys/class/graphics/fb0/screen_info", "r");
        if(fp == NULL)
        {
                perror("fopen err:");
                return -1;
        }
        int xres = 0;
        int yres = 0;
        char line1[64] = {0};
        char line2[64] = {0};
        fgets(line1, sizeof(line1), fp);
        fgets(line2, sizeof(line2), fp);
        sscanf(line1, "xres:%dn", &xres);
        sscanf(line2, "yres:%dn", &yres);
        fclose(fp);
        DEBUG_P("read x:%d, y:%dn", xres, yres);
        int fd = open("/dev/fb0", O_RDWR, 0);
        if (fd < 0)
        {
                fprintf(stderr, "No fb devices found!n");
                return -errno;
        }
        struct fb_fix_screeninfo finfo;
        if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
        {
                close(fd);
                return -errno;
        }
        struct fb_var_screeninfo info;
        if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
        {
                close(fd);
                return -errno;
        }
        info.reserved[0] = 0;
        info.reserved[1] = 0;
        info.reserved[2] = 0;
        info.xoffset = 0;
        info.yoffset = 0;
        info.width = xres;
        info.height = yres;
        info.xres = xres;
        info.yres = yres;
        info.xres_virtual = info.xres;
        info.yres_virtual = info.yres * NUM_BUFFERS;
        info.activate = FB_ACTIVATE_NOW | FB_ACTIVATE_FORCE;
        info.bits_per_pixel = 32;
        info.red.offset     = 16;
        info.red.length     = 8;
        info.green.offset   = 8;
        info.green.length   = 8;
        info.blue.offset    = 0;
        info.blue.length    = 8;
        info.transp.offset  = 0;
        info.transp.length  = 0;
        info.grayscale            &= 0xff;
        info.grayscale            |= (info.xres<<8) + (info.yres<<20);
        info.nonstd             &= 0xffffff00;
        info.nonstd             |= 2;//HAL_PIXEL_FORMAT_RGBX_8888;
        ioctl(fd, RK_FBIOSET_CLEAR_FB, NULL);
        if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1)
        {
                perror("FBIOPUT_VSCREENINFO failed");
                close(fd);
                return -errno;
        }
        if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
        {
                fprintf(stderr, "FBIOGET_VSCREENINFO failed.n");
                close(fd);
                return -errno;
        }
        int refreshRate = 0;
        if ( info.pixclock > 0 )
        {
                refreshRate = 1000000000000000LLU / ((uint64_t)
                        (info.upper_margin + info.lower_margin + info.yres + info.hsync_len ) *
                        (info.left_margin  + info.right_margin + info.xres + info.vsync_len ) *
                        info.pixclock);
                if (refreshRate == 0)
                {
                        refreshRate = 60*1000;  // 60 Hz
                }
        }
        if ((int)(info.width) <= 0 || (int)(info.height) <= 0)
        {
                // the driver doesn't return that information
                // default to 160 dpi
                info.width  = ((info.xres * 25.4f)/160.0f + 0.5f);
                info.height = ((info.yres * 25.4f)/160.0f + 0.5f);
        }
        float xdpi = (info.xres * 25.4f) / info.width;
        float ydpi = (info.yres * 25.4f) / info.height;
        float fps  = refreshRate / 1000.0f;
        DEBUG_P("using (fd=%d)n"
             "id           = %sn"
             "xres         = %d pxn"
             "yres         = %d pxn"
             "xres_virtual = %d pxn"
             "yres_virtual = %d pxn"
             "bpp          = %dn"
             "r            = %2u:%un"
             "g            = %2u:%un"
             "b            = %2u:%un"
             "format       = %dn",
             fd,
             finfo.id,
             info.xres,
             info.yres,
             info.xres_virtual,
             info.yres_virtual,
             info.bits_per_pixel,
             info.red.offset, info.red.length,
             info.green.offset, info.green.length,
             info.blue.offset, info.blue.length,
             info.nonstd);
        DEBUG_P("width      = %d mm (%f dpi)n"
             "height       = %d mm (%f dpi)n"
             "refresh rate = %.2f Hzn",
             info.width,  xdpi,
             info.height, ydpi,
             fps);
        int videodata[2];
        videodata[1] = videodata[0] = finfo.smem_start;
        ioctl(fd, 0x5002, videodata);
        close(fd);
        return 0;
}

原作者:hongyin

更多回帖

发帖
×
20
完善资料,
赚取积分