上一章我們簡單介紹了LCD的一些基本原理。當然更深奧的還有,比如gamma,dither,HUE,satuation.OSD等等.
我們知道我們是用framebuffer來實作顯示的.
顯存:framebuffer.由DDRAM中劃去一部分記憶體供顯存使用.
進而操作lcd相當于操作顯存.
lcd控制器(s5pv210裡面有lcd控制器)會周期的擷取framebuffer中的資料。經過處理丢給 顯示屏的lcd 驅動器
lcd驅動器分析,解碼,将資料顯示到lcd上.
lcd驅動開發的工作:
配置lcd 控制器,讓lcd 控制器周期性的讀取顯存中的資料
然後按照一定的時序和格式講資料發送給lcd驅動器.驅動器會驅動lcd屏進行顯示.
1)申請顯存
framebuffer:導出lcd實體緩沖區(顯存)導入到使用者空間(0-3G)
使用者空間要顯示一幅圖檔到lcd,在使用者空間直接操作顯存,将要顯示的圖檔copy到
顯存中的相應位置上就可以了
這邊就先不多講了,因為時間太晚,太累。我們畫一個這樣的圖檔:
使用者空間代碼:
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <sys/mman.h>
#define _COLOR_RED 0x00ff0000
#define _COLOR_GREEN 0x0000ff00
#define _COLOR_BLUE 0x000000ff
static struct fb_fix_screeninfo fb_fix ={};
static struct fb_var_screeninfo fb_var ={};
long screen_size=;
int *fb32 =NULL;
int main()
{
int fd = -;
int x,y;
fd =open("/dev/fb0",O_RDWR);
if(fd < )
{
printf("open dev fb0 fail.\n");
return -;
}
//get lcd param
ioctl(fd,FBIOGET_FSCREENINFO,&fb_fix);
ioctl(fd,FBIOGET_VSCREENINFO,&fb_var);
screen_size = fb_var.xres*fb_var.yres*(fb_var.bits_per_pixel/);
fb32 =mmap(,screen_size,PROT_READ |PROT_WRITE,MAP_SHARED,fd,);
if(fb32 == NULL)
{
printf("mmap framebuffer fail.\n");
return -;
}
if(fb_var.bits_per_pixel == )
{
printf("8bpp framebuffer test.\n");
}
else if(fb_var.bits_per_pixel == )
{
printf("16bpp framebuffer test.\n");
}
else if(fb_var.bits_per_pixel == )
{
printf("24bpp framebuffer test.\n");
}
else if(fb_var.bits_per_pixel == )
{
printf("32bpp framebuffer test.\n");
}
for(y=;y< fb_var.yres/;y++)
{
for(x=;x< fb_var.xres;x++)
{
*(fb32 +y*fb_var.xres + x) = _COLOR_RED;
}
}
for(;y< fb_var.yres*/;y++)
{
for(x=;x< fb_var.xres;x++)
{
*(fb32 +y*fb_var.xres + x) = _COLOR_GREEN;
}
}
for(;y< fb_var.yres;y++)
{
for(x=;x< fb_var.xres;x++)
{
*(fb32 +y*fb_var.xres + x) = _COLOR_BLUE;
}
}
munmap(fb32,screen_size);
close(fd);
return ;
}
實驗效果:
可以看到,和我們預期的一樣。其中那邊有一個小黑框那是光标,我們不管。