| static struct s3c2410fb_display smdk2440_lcd_cfg __initdata = { .lcdcon5 = S3C2410_LCDCON5_FRM565 | S3C2410_LCDCON5_INVVLINE | S3C2410_LCDCON5_INVVFRAME | S3C2410_LCDCON5_PWREN | S3C2410_LCDCON5_HWSWP, .type = S3C2410_LCDCON1_TFT, .width = 320, .height = 240, .pixclock = 100000, //????/*HCLK 100MHZ divisor 3*/ .xres = 320, .yres = 240, .bpp = 16, .left_margin = 20, .right_margin = 38, .hsync_len = 30, .upper_margin = 12, .lower_margin = 15, .vsync_len = 3, }; 关于pixclock=1/VCLK,像素时钟,单位是皮秒。显示每个像素的时钟周期。 和cpu的HCLK有关。 16BPP模式的数据格式 以上参考: 2440LCD控制器详细配置 linux内核配置 Device drivers-> Graphics support ---> Support for frame buffer devices ---> S3C2410 LCD framebuffer support 测试程序
参考:linux framebuffer tutorial #include <stdio.h> #include <stdlib.h> #include <sys/ioctl.h> #include <unistd.h> #include <fcntl.h> #include <linux/fb.h> #include <sys/mman.h> int lcd_width; int lcd_height; int screen_size; int line_size; struct fb_var_screeninfo var_screeninfo; struct fb_fix_screeninfo fix_screeninfo; void get_screeninfo(int fb,struct fb_var_screeninfo *var,struct fb_fix_screeninfo *fix) { if(ioctl(fb,FBIOGET_VSCREENINFO,var)) { fprintf(stderr,"ioctl FBIOGET_VSCREENINFO.\n"); exit(1); } if(ioctl(fb,FBIOGET_FSCREENINFO,fix)) { fprintf(stderr,"ioctl FBIOGET_VSCREENINFO.\n"); exit(1); } lcd_width=var->width; lcd_height=var->height; screen_size=lcd_width*lcd_height*var->bits_per_pixel/8; line_size=fix->line_length; printf("var->width:%d\n",var->width); printf("var->height:%d\n",var->height); printf("var->bits_per_pixel:%d\n",var->bits_per_pixel); printf("var->xoffset:%d\n",var->xoffset); printf("var->yoffset:%d\n",var->yoffset); printf("fix->line_length:%d\n",fix->line_length); } void draw_rect(char *fbp,int x,int y,int w,int h,short color) { int i,j; for(i=0;i<w;i++) for(j=0;j<h;j++,j++) *(fbp+i*line_size +y+j)=color; } void draw_screen(char *fbp) { draw_rect(fbp,0,0,80,80,0xf800); draw_rect(fbp,80,80,80,80,0x07e0); draw_rect(fbp,160,160,80,80,0x001f); } int main() { int fb; int cmd; unsigned char *fb_mem; if((fb=open("/dev/fb0",O_RDWR))<0) { printf("cannot open /dev/fb0\n"); exit(0); } get_screeninfo(fb,&var_screeninfo,&fix_screeninfo); fb_mem=(unsigned char*)mmap(0,screen_size,PROT_READ|PROT_WRITE,MAP_SHARED,fb,0);//关键!!!把内核空间映射到用户空间 if ((int)fb_mem == -1) { printf("Error: failed to map framebuffer device to memory.\n"); exit(4); } printf("The framebuffer device was mapped to memory successfully.\n"); memset(fb_mem,0,screen_size); /*do something here use fb_mem*/ draw_screen(fb_mem); munmap(fb_mem, screen_size); close(fb); return 0; } 交叉编译:arm-linux-gcc lcdtest.c -o lcdtest | 测试结果:
系统启动加载framebuffer驱动: | 运行测试程序: | 问题:LCD一段时间后会自动关闭,解决方案参考:十分钟黑屏问题 |