有做过linux下framebuffer驱动的吗,请教个问题?!在TQ2440中实现。。。
在framebuffer里面有个结构体是 fb_var_screeninfo() 在这个里面定义了 可视区域大小和虚拟区域大小,我如何能够修改这个 虚拟区域的大小?!用(ioctl(fp,FBIOGET_FSCREENINFO,&finfo)能够获取结构体信息,但是我用ioctl如何能设置虚拟区域的大小呢?!我打算在TQ2440里面实现,他的硬件能支持这种修改?! 自己顶一下!MS搞这个东西的越来越少了,
那如何在TQ2440里面显示一个比屏幕大的图片,当然屏幕只能显示部分,
然后通过控制可以设置显示的区域?!
在linux+TQ2440下有别的技术可以实现吗? #include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <string.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <linux/fb.h>
int main ()
{
int fp=0;
int fb_mem;
struct fb_var_screeninfo vinfo;
struct fb_fix_screeninfo finfo;
fp = open ("/dev/fb0",O_RDWR);
if (fp < 0)
{
printf("Error : Can not open framebuffer device\n");
exit(1);
}
if (ioctl(fp,FBIOGET_FSCREENINFO,&finfo))
{
printf("Error reading fixed information\n");
exit(2);
}
if (ioctl(fp,FBIOGET_VSCREENINFO,&vinfo))
{
printf("Error reading variable information\n");
exit(3);
}
printf("The mem is :%d\n",finfo.smem_len);
printf("The line_length is :%d\n",finfo.line_length);
printf("The xpanstep is :%d\n",finfo.xpanstep);
printf("The xres is :%d\n",vinfo.xres);
printf("The yres is :%d\n",vinfo.yres);
printf("bits_per_pixel is :%d\n",vinfo.bits_per_pixel);
printf("The xresvirtual is :%d\n",vinfo.xres_virtual);
printf("The yresvirtual is :%d\n",vinfo.yres_virtual);
printf("The xoffset is :%d\n",vinfo.xoffset);
printf("The yoffset is :%d\n",vinfo.yoffset);
// printf("The height is :%d\n",vinfo.height);
// printf("The width is :%d\n",vinfo.width);
// printf("The hsync_len is :%d\n",vinfo.hsync_len);
// printf("The vsync_len is :%d\n",vinfo.vsync_len);
printf("\nCHANGE VIRTUAL\n");
vinfo.xres=320;
vinfo.yres=240;
vinfo.xres_virtual=640;
vinfo.yres_virtual=480;
vinfo.yoffset=20;
if (ioctl(fp,FBIOPUT_VSCREENINFO,&vinfo)==-1)
{
printf("Error setting variable information\n");
exit(3);
}
printf("\nREGET\n");
if (ioctl(fp,FBIOGET_VSCREENINFO,&vinfo))
{
printf("Error reading variable information\n");
exit(3);
}
printf("The xres is :%d\n",vinfo.xres);
printf("The yres is :%d\n",vinfo.yres);
printf("bits_per_pixel is :%d\n",vinfo.bits_per_pixel);
printf("The xresvirtual is :%d\n",vinfo.xres_virtual);
printf("The yresvirtual is :%d\n",vinfo.yres_virtual);
printf("The xoffset is :%d\n",vinfo.xoffset);
printf("The yoffset is :%d\n",vinfo.yoffset);
close (fp);
return 0;
} 我用的TQ2440 对于fb_var_screeninfo里面的值一直修改不成功,有人是显卡不支持,我怎么才能判断呢?! static int s1d15605fb_resize_framebuffer(struct s1d15605fb_info *sinfo)
{
struct fb_info *info = sinfo->info;
struct fb_fix_screeninfo *fix = &info->fix;
struct fb_var_screeninfo *var = &info->var;
unsigned int new_size;
void *new_vaddr;
new_size = ((var->xres_virtual * var->yres_virtual * var->bits_per_pixel) / 8);
MSG("%s: x (%d) y (%d) bpp (%d): new size 0x%08x\n", __FUNCTION__,
var->xres_virtual, var->yres_virtual, var->bits_per_pixel, new_size);
if (new_size == fix->smem_len)
return 0;
if (fix->smem_len) {
kfree(info->screen_base);
}
new_vaddr = kmalloc(new_size, GFP_KERNEL);
if (!new_vaddr) {
fix->smem_len = 0;
return -ENOMEM;
}
info->screen_base = new_vaddr;
fix->smem_start = (unsigned)new_vaddr;
fix->smem_len = new_size;
fix->line_length = (var->xres_virtual * var->bits_per_pixel) / 8;
dev_info(info->device,
"%luKiB frame buffer at %08lx (mapped at %p)\n",
(unsigned long)info->fix.smem_len / 1024,
(unsigned long)info->fix.smem_start,
info->screen_base);
return 0;
} 这个是s1d15605fb 调整大小的源码。我对这个也只是一知半解。读了一下这个驱动源码,道是没有想像中的那么难,最近没时间搞那天试试看能不能搞定。 虚拟的大小从源码来看就是修改var变量中的成员。我的理解就是把这个结构中的函数实现就差不多了:
static struct fb_ops s1d15605fb_ops = {
.owner = THIS_MODULE,
.fb_check_var = s1d15605_check_var,
.fb_set_par = s1d15605_set_par,
.fb_setcolreg = s1d15605_setcolreg,
.fb_blank = s1d15605_blank,
// .fb_pan_display = s1d15605_pan_display,
.fb_fillrect = s1d15605_fillrect,
.fb_copyarea = s1d15605_copyarea,
.fb_imageblit = s1d15605_imageblit,
.fb_write = s1d15605_write,
#ifdef USE_PRIVATE_VMA_FXS
.fb_mmap = s1d15605_mmap,
#endif
};
s1d15605_set_par 这个函数就是调整显示像素或属性时被调用的。它又调用上面发的函数实现的。(我的理解是这样) s1d15605_check_var:实现变量是否正确
s1d15605_setcolreg: 像素中RGB定义
s1d15605_pan_display: 用于显示刷新系统定时调用
s1d15605_blank: 用于背景灯设置
s1d15605_fillrect:填允矩形,上层已经做好不用写
s1d15605_copyarea:复制指定区域,上层已经做好不用写
s1d15605_imageblit:绘制位图,上层已经做好不用写
s1d15605_mmap:将系统显存导入用户区
这是我的理解,多交流. 回复【7楼】liguangqang
-----------------------------------------------------------------------
我也是才接触这个认为还是应该用ioctl能够实现,我得出结论 可能显示设备不支持吧!还得继续弄!我看内核提供的那部分驱动,觉得调用的没错,可就是写不进去!还在搞呵呵。。。 回复【7楼】liguangqang
-----------------------------------------------------------------------
最终我觉得可能TQ2440这板子 并不支持虚拟屏比物理屏大。。。还得继续搞搞。。。
页:
[1]