【技术分享】Lubuntu分辨率自适应
本帖最后由 hongyin 于 2016-6-17 17:20 编辑好久没发帖了,近期工作太忙,所以自适应(基于VGA)的整理迟迟没有更新,今天先来无事,所以把之前的研究成果拿出来供大家参考,如有问题,可以发我邮箱(iamphy@qq.com)进行交流,废话少说,谈正事。
首先,请先下载附件,该文件并非压缩包,下载后直接将后缀名改成.c即可,并将该文件cp到相应目录:kernel/drivers/video/rockchip/lcdc下,该文件修复了1440x900和1366x768两种分辨率的异常(兼容性有待考证),还有就是RGB颜色问题;准备工作做好之后,自行编译内核进行烧写;
然后,下面的代码便是自动适配分辨率的,这是一个单独的程序,需要各位网友自行cp进行编译,编译完成之后,只需要将执行路径添加到/etc/rc.local文件即可;若网友发现有问题,请邮件相互交流。
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/fb.h>
#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 = {0};
char line2 = {0};
fgets(line1, sizeof(line1), fp);
fgets(line2, sizeof(line2), fp);
sscanf(line1, "xres:%d\n", &xres);
sscanf(line2, "yres:%d\n", &yres);
fclose(fp);
DEBUG_P("read x:%d, y:%d\n", 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;
info.reserved = 0;
info.reserved = 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 = %s\n"
"xres = %d px\n"
"yres = %d px\n"
"xres_virtual = %d px\n"
"yres_virtual = %d px\n"
"bpp = %d\n"
"r = %2u:%u\n"
"g = %2u:%u\n"
"b = %2u:%u\n"
"format = %d\n",
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 Hz\n",
info.width,xdpi,
info.height, ydpi,
fps);
int videodata;
videodata = videodata = finfo.smem_start;
ioctl(fd, 0x5002, videodata);
close(fd);
return 0;
}
文件已经损坏了,可以重新上传吗,谢谢 牛人,赞一个 blackholeII 发表于 2016-6-21 10:37
文件已经损坏了,可以重新上传吗,谢谢
附件并非压缩包,你下载后将后缀名改成.c就可以直接使用了 好贴,已设置精华 只能基于VGA? 这个显示的问题可以帮忙看一下吗?
http://developer.t-firefly.com/thread-10933-1-1.html 顶大神!!!!11 这个帖子真是精华 强烈的感谢楼主!这个帖子真是精华
页:
[1]
2