Download presentation
Presentation is loading. Please wait.
1
Frame Buffer
2
Frame Buffer를 이용한 Programming / Frame Buffer란
frame buffer란 linux system에서 그래픽을 표현할 수 있는 hardware를 말함. PC라면 그래픽 카드, Rebis같으면 LCD controller를 frame buffer 장치라고 함. frame buffer를 user level application이 제어할 수 있도록 만들어진 device driver를 frame buffer driver라고 함 The frame buffer device provides an abstraction for the graphic hardware. It represents the frame buffer of some video hardware and allows application software to access the graphics hardware through a well-defined interface, so the software doesn’t need to know anything about the low-level (hardware register) stuff. The device is accessed through special device nodes, usually located in the /dev directory, i.e. /dev/fb* The frame buffer devices are also normal memory devices, this means, you can read and write their contents. You can, for example, make a screen snapshot by cp /dev/fb0 myfile
3
LCD에 출력하는 원리 LCD에 출력하는 원리
User level에서 전송한 frame buffer data를 LCD driver가 수신하여 LCD controller가 TFT-LCD에 출력한다. User level과 driver간에 “/dev/fb0”라는 node를 통하여 data를 전송하며, driver가 할당한 memory를 user application에서도 사용할 수 있도록 memory mapping을 한다. User application TFT-LCD LCD driver (frame buffer driver) LCD controller (frame buffer) Frame buffer data 프레임버퍼 메모리에 해당정보를 써넣으면 클럭에 맞추어 LCD의 reflash에 DMA에 의해 행당 정보가 LCD로 전송되어 그림, 도형등을 표시한다.
4
LCD 정보 얻어오기 LCD 정보 얻어오기(1)
실습보드에 있는 TFT-LCD의 해상도와 할당된 메모리의 크기 등 lcd에 관한 정보를 얻어보자. 위의 정보들은 <linux/fb.h>에 정의 되어 있는fb_var_screeninfo 와 fb_fix_screeninfo라는구조체에 들어 있다. 알고자 하는 lcd 정보 x-resolution y-resolution x-resolution(virtual) y-resolution(virtual) bpp (bit per pixel) length of frame buffer memory
5
length of frame buffer memory에
LCD 정보 얻어오기 LCD 정보 얻어오기(2) #include<stdio.h> #include<stdlib.h> /*for exit*/ #include<unistd.h>/*for open/close..*/ #include<fcntl.h> /*for O_RDWR*/ #include<sys/ioctl.h> /*for ioctl*/ #include<linux/fb.h>/*for fb_var_screeninfo, FBIOGET_VSCREENINFO*/ #define FBDEVFILE "/dev/fb" int main(){ int fbfd; int ret; struct fb_var_screeninfo fbvar; struct fb_fix_screeninfo fbfix; x-resolution, y-resolution, x-resolution(virtual), y-resolution(virtual), bpp (bit per pixel) 에 대한 정보가 들어 있는 구조체 length of frame buffer memory에 대한 정보가 들어있는 구조체
6
LCD 정보 얻어오기 LCD 정보 얻어오기(3) fb_var_screeninfo 구조체
__u32 는 asm/type.h에 unsigned int로 정의 되어 있음.
7
LCD 정보 얻어오기 LCD 정보 얻어오기(4) fb_fix_screeninfo
8
LCD 정보 얻어오기 LCD 정보 얻어오기(5)
fbfd = open(FBDEVFILE, O_RDWR); //frame buffer의 node인 /dev/fb 를 open if(fbfd<0){ perror("fbdev open"); exit(1); } ret = ioctl(fbfd, FBIOGET_VSCREENINFO, &fbvar); if(ret < 0){ perror("fbdev ioctl(FSCREENINFO)"); ret = ioctl(fbfd, FBIOGET_FSCREENINFO, &fbfix); Kernel로 부터 fb_var_screeninfo 정보를 가져올 때 쓰는 옵션, fbvar에 저장한다. Kernel로 부터 fb_fix_screeninfo정보를 가져올 때 쓰는 옵션, fbfix에 저장한다. FBIOGET_VSCREENINFO와 FBIOGET_FSCREENINFO는 linux/fb.h에 정의 되어 있음.
9
LCD 정보 얻어오기 LCD 정보 얻어오기(6) // x-resolution
printf("x-resolutionnn: %d\n", fbvar.xres); //y-resolution printf("y-resolution: %d\n", fbvar.yres); //virtual x-resolution printf("x-resolution(virtual): %d\n", fbvar.xres_virtual); //virtual y-resolution printf("y-resolution(virtual): %d\n", fbvar.yres_virtual); //bpp (bit per pixel) printf("bpp: %d\n", fbvar.bits_per_pixel); //the size of frame buffer memory printf("length of frame buffer memory: %d\n", fbfix.smem_len); close(fbfd); exit(0); return 0; }
10
LCD 정보 얻어오기 LCD 정보 얻어오기(7)
Host에서 위에서 배운 source를 fbinfo.c로 저장한 뒤에 아래와 같이 compile 한다. minicom이나 NFS 방식을 이용하여 target으로 fbinfo라는 실행 파일을 download한다.
11
TFT - LCD LCD에 점 찍기 LCD에 점 찍기(1) TFT-LCD 해상도 : 240 * 320 240 320 (0,0)
(239,0) TFT - LCD (0,319) (230,319)
12
LCD에 점 찍기 LCD에 점 찍기(2) 보드의 LCD는 16bpp를 지원한다.
즉, 한 pixel를 표현하기 위해 16bit의 색 정보가 필요하다 MSB에서 LSB 쪽으로 R,G,B 순이다. 참고로 R=0,G=0,B=0은 black이며, R=255, G=255, B=255는 white이다. RED (5 bit) Green (6 bit) Blue (5 bit)
13
LCD에 점 찍기 LCD에 점 찍기(3) makepixel() 함수는 r,g,b 3개의 byte(0~255) 값을 받아서 16bit pixel 값을 만들어 내는 함수이다. unsigned short makepixel(ubyte r, ubyte g, ubyte b) { return (unsigned short)(((r>>3)<<11)|((g>>2)<<5)|(b>>3)); } 각 색별로 아래 3bit는 버린다. lseek() 함수를 사용하여 offset을 계산하여 점을 찍는다. offset=ypos*한줄의 바이트수 + xpos*한 픽셀당 바이트수 한픽셀당 바이트수=16/8(16bpp이므로.) 한줄의 바이트수=한줄의 픽셀 수 * 한픽셀당 바이트수=xres*(16/8) 결국 offset=ypos*xres*(16/8)+xpos*(16/8) (MSB)15 ~ 11 10 ~ 5 4 ~ 0(LSB)
14
LCD에 점 찍기 LCD에 점 찍기(4) lseek() : 파일 포인터 이동할 때 쓰는 함수
include <sys/type.h> include <unistd.h> 위 2 header file을 include해야 함. off_t lseek(int fildes, off_t offset, int start_flag); fildes : 읽고 쓰기 위한 파일 지시자 offset : 시작 위치에서 더할 바이트 수 start_flag : 시작지점 지정 off_t : typedef long off_t; start_flag SEEK_SET : 파일 포인터가 어디 있든지 맨 앞으로 옮긴다. SEEK_CUR : 현재의 파일 포인터를 유지한다. 즉, 현재의 파일 포인터에서부터 읽고 쓴다. SEEK_END : 파일 포인터를 맨 끝으로 옮긴다.
15
lseek (fd, (off_t)+100, SEEK_CUR)
LCD에 점 찍기 LCD에 점 찍기(5) lseek (fd, (off_t)+100, SEEK_CUR) 현재의 위치 -100 +100 SEEK_SET SEEK_CUR SEEK_END
16
LCD에 점 찍기 LCD에 점 찍기(6) #include <stdio.h>
#include <stdlib.h> /* for exit */ #include <unistd.h> /* for open/close.. */ #include <fcntl.h> /* for O_RDONLY */ #include <sys/ioctl.h> /* for ioctl */ #include <sys/type.h> /* for lseek() */ #include <linux/fb.h> /*for fb_var_screeninfo, FBIOGET_VSCREENINFO*/ #define FBDEVFILE "/dev/fb" typedef unsigned char ubyte; //색 정보를 16bit로 변환 해주는 함수 unsigned short makepixel(ubyte r, ubyte g, ubyte b){ return (unsigned short)(((r>>3)<<11)|((g>>2)<<5)|(b>>3)); }
17
LCD에 점 찍기 LCD에 점 찍기(7) int main(){ int fbfd; int ret;
struct fb_var_screeninfo fbvar; unsigned short pixel; int offset; //frame buffer driver file point를 얻는다. fbfd = open(FBDEVFILE, O_RDWR); if(fbfd < 0){ perror("fbdev open"); exit(1); } // 커널로부터 lcd에 관한 정보를 fbvar에 저장한다. ret = ioctl(fbfd, FBIOGET_VSCREENINFO, &fbvar); if(ret < 0){ perror("fbdev ioctl");
18
LCD에 점 찍기 LCD에 점 찍기(8) if(fbvar.bits_per_pixel!=16){ //bpp가 16bit인지 check fprintf(stderr, "bpp is not 16\n"); exit(1); } //red 점을 (0,0)에 찍는다. if(lseek(fbfd, 0, SEEK_SET) < 0){ //file point를 맨 앞으로 옮김 perror("fbdev lseek"); exit(1); } pixel = makepixel(&fbvar, 255, 0, 0); /*red pixel*/ write(fbfd, &pixel, 2); /*write 2byte(16bit)*/ //green점을 (100,50)에 찍는다. offset = 50*fbvar.xres*(16/8)+100*(16/8); if(lseek(fbfd, offset, SEEK_SET) < 0){ //file point를 맨 앞에서 offset만큼 옮김 exit(1); } pixel = makepixel(&fbvar, 0, 255, 0); /*green pixel */
19
LCD에 점 찍기 LCD에 점 찍기(9) //blue점을 (50,100)에 찍는다.
offset = 100*fbvar.xres*(16/8)+50*(16/8); if(lseek(fbfd, offset, SEEK_SET)<0){ //file point를 맨앞에서 offset만큼 옮김 perror("fbdev lseek"); exit(1); } pixel = makepixel(&fbvar,0,0,255); /*blue pixel */ write(fbfd, &pixel, 2);/*write 2byte(16bit)*/ //white점을 (100,100)에 찍는다. offset = 100*fbvar.xres*(16/8)+100*(16/8); if(lseek(fbfd, offset, SEEK_SET) < 0){ //file point를 맨앞에서 offset만큼 옮김 exit(1); } pixel = makepixel(&fbvar, 255, 255, 255); /*white pixel */ write(fbfd, &pixel, 2); /*write 2byte(16 bit)*/ close(fbfd); exit(0); return 0; }
20
LCD에 점 찍기 LCD에 점 찍기(10) Host에서 위에서 배운 소스를 fbpixel.c로 저장한 후 아래와 같이 compile한다. minicom이나 NFS 방식을 이용하여 target으로 fbpixel이라는 실행 파일을 download한다. target에서 실행하여 결과를 확인한다. % ./fbpixel
Similar presentations