Module 9: Framebuffer programming ESP30076 임베디드시스템프로그래밍 (Embedded System Programming) 조윤석 전산전자공학부
주차별목표 프레임버퍼알아보기 프레임버퍼이해하기 프레임버퍼제어하기 간단한프레임버퍼프로그래밍 프레임버퍼라이브러리만들기 프레임버퍼라이브러리용기본함수만들기 프레임버퍼에 BMP 이미지출력하기 2
프레임버퍼 (Frame buffer) Frame buffer (FB) 는그래픽하드웨어를추상화 (abstraction) 해줌 일반적으로 FB 는비디오하드웨어에있는 frame buffer 를표현함 FB 를사용하면응용소프트웨어에서는미리정의되어진인터페이스를통해그래픽하드웨어에손쉽게 access 하여그래픽요소를표현할수있음 따라서소프트웨어개발자는하드웨어레지스터나컨트롤러등의저수준특성에대한지식이없어도됨. Frame buffer driver User level application 에서손쉽게 frame buffer 를사용할수있도록지원하는 device driver 3
프레임버퍼 (Frame buffer) LCD 에데이터를출력하는과정 4
프레임버퍼 (Frame buffer) 제어 프레임버퍼구조체 Frame buffer 와관련된헤더파일은 linux/fb.h 에정의되어있음 fb_fix_screeninfo Frame buffer 의총메모리에대한정보등을가지고있음 프레임버퍼와관련된고정된 (fix) 정보를관리 fb_var_screeninfo Resolution, bpp (bit per pixel) 등에대한정보를가지고있음 프레임버퍼와관련된가변정보들을가지고있음 5
프레임버퍼 (Frame buffer) 제어 프레임버퍼구조체 6 fb_fix_screeninfo struct fb_fix_screeninfo { char id[16];/* identification string eg "TT Builtin" */ unsigned long smem_start; /* Start of frame buffer mem */ /* (physical address) */ u32 smem_len; /* Length of frame buffer mem */ u32 type;/* see FB_TYPE_* */ u32 type_aux; /* Interleave for interleaved Planes */ u32 visual; /* see FB_VISUAL_* */ u16 xpanstep; /* zero if no hardware panning */ u16 ypanstep; /* zero if no hardware panning */ u16 ywrapstep; /* zero if no hardware ywrap */ u32 line_length; /* length of a line in bytes */ unsigned long mmio_start; /* Start of Memory Mapped I/O */ ; /* (physical address) */ u32 mmio_len; /* Length of Memory Mapped I/O */ u32 accel; /* Type of acceleration available */ u16 reserved[3]; /* Reserved for future compatibility */
프레임버퍼 (Frame buffer) 제어 프레임버퍼구조체 fb_var_screeninfo struct fb_var_screeninfo { u32 xres; /* visible resolution */ u32 yres; u32 xres_virtual; /* virtual resolution */ u32 yres_virtual; u32 xoffset; /* offset from virtual to visible */ */ u32 yoffset; /* resolution */ u32 bits_per_pixel; /* guess what */ u32 grayscale; /*!= 0 Graylevels instead of colors */ struct fb_bitfield red; /* bitfield in fbmem if true color, */ struct fb_bitfield green; /* else only length is significant struct fb_bitfield blue; struct fb_bitfieldtransp; /* transparency */ 7
프레임버퍼 (Frame buffer) 제어 프레임버퍼구조체 fb_var_screeninfo ; u32 nonstd; /*!= 0 Non standard pixel format */ u32 activate; /* see FB_ACTIVATE_* */ u32 height; /* height of picture in mm */ u32 width; /* width of picture in mm */ u32 accel_flags; /* acceleration flags (hints) */ /* Timing: All values in pixclocks, except pixclock (of course) */ u32 pixclock; /* pixel clock in ps (pico seconds) */ u32 left_margin; /* time from sync to picture */ u32 right_margin; /* time from picture to sync */ u32 upper_margin; /* time from sync to picture */ u32 lower_margin; u32 hsync_len; /* length of horizontal sync */ u32 vsync_len; /* length of vertical sync */ u32 sync;/* see FB_SYNC_* */ u32 vmode; /* see FB_VMODE_* */ u32 reserved[6]; /* Reserved for future compatibility */ 8
프레임버퍼 (Frame buffer) 제어 프레임버퍼구조체 프레임버퍼구조체의값들을변경할수도있음 프레임버퍼장치의기본정보는시스템콜 ioctl() 을사용하여읽어오거나변경할수있음 ioctl() 함수의옵션들은 linux/fb.h 헤더파일내에선언되어있음 9 /* ioctls 0x46 is 'F'*/ #define FBIOGET_VSCREENINFO #define FBIOPUT_VSCREENINFO #define FBIOGET_FSCREENINFO #define FBIOGETCMAP 0x4604 #define FBIOPUTCMAP 0x4605 #define FBIOPAN_DISPLAY 0x4606...( 생략 ) #define FBIOPUT_MODEINFO 0x4617 #define FBIOGET_DISPINFO 0x4618 0x4600 0x4601 0x4602
프레임버퍼 (Frame buffer) 제어 프레임버퍼구조체 ioctl() 함수를이용하여시스템콜을통해커널이관리하고있는프레임버퍼정보를가지고오거나프레임버퍼설정을변경하는내용을적용하는예시 ioctl_ret = ioctl(fb_fd, FBIOGET_VSCREENINFO, &fbvar); ioctl_ret = ioctl(fb_fd, FBIOGET_FSCREENINFO, &fbfix); fbvar.bits_per_pixel = 8; ioctl_ret = ioctl(fb_fd, FBIOPUT_VSCREENINFO, &fbvar); 10
LCD 정보를읽어오는프로그램작성 LCD 정보읽어오기 프레임버퍼드라이버로부터설정된 LCD 정보를읽어오거나변경하려면 ioctl() 을사용 ioctl() 을사용하여 LCD 정보를읽어오고, 일부내용을변경하여적용하는프로그램을작성해보기 드라이버에접근하여스크린과관련된고정정보와가변정보를읽어온다음, 해상도와컬러색상수 (bits per pixel; bpp) 그리고프레임버퍼메모리의크기를화면에출력 컬러색상수를변경하여드라이버에변경된내용을반영해보기 11
LCD 정보를읽어오는프로그램작성 LCD 정보읽어오기 프로그램작성하기 root@esp:~# mkdir /root/work/fb root@esp:~# mkdir /root/work/fb/fb_information root@esp:~# cd /root/work/fb/fb_information root@esp:~/work/fb/fb_information# vi fbinfo.c 12
LCD 정보를읽어오는프로그램작성 LCD 정보읽어오기 fbinfo.c /* Framebuffer information display FILE : fbinfo.c */ #include <stdio.h> #include <fcntl.h> /* for O_RDWR */ #include <sys/ioctl.h> /* for ioctl */ #include <linux/fb.h> /* frame buffer header */ #define FBDEVFILE "/dev/fb0" int main(int argc, char* argv) { int fb_fd; int ioctl_ret; struct fb_var_screeninfo fbvar; struct fb_fix_screeninfo fbfix; fb_fd = open(fbdevfile, O_RDWR); // open the device node for frame buffer 13
LCD 정보를읽어오는프로그램작성 LCD 정보읽어오기 fbinfo.c if(fb_fd<0){ perror(fbdevfile); return -1; ioctl_ret = ioctl(fb_fd, FBIOGET_VSCREENINFO, &fbvar); if(ioctl_ret< 0 ){ perror("fb dev ioctl(vscreeninfo GET)"); return -1; ioctl_ret = ioctl(fb_fd, FBIOGET_FSCREENINFO, &fbfix); if(ioctl_ret< 0 ){ perror("error: fbdevioctl(fscreeninfo GET)"); return -1; 14
LCD 정보를읽어오는프로그램작성 LCD 정보읽어오기 fbinfo.c 15 // x-resolution and y-resolution printf("resolution: X = %d, Y = %d\n", fbvar.xres, fbvar.yres); //virtual x-resolution and y-resolution printf("virtual resolution: VX = %d, VY=%d\n", fbvar.xres_virtual, fbvar.yres_virtual); // color bits per pixel printf("original BPP = %d\n", fbvar.bits_per_pixel); //the size of total frame buffer memory printf("length of frame buffer memory = %d\n", fbfix.smem_len); // set bpp value to 16 (Hardware Dependent) fbvar.bits_per_pixel = 16; ioctl_ret = ioctl(fb_fd, FBIOPUT_VSCREENINFO, &fbvar); // write to driver if(ioctl_ret< 0 ){ perror("fbdevioctl(vscreeninfo PUT)"); return -1;
LCD 정보를읽어오는프로그램작성 LCD 정보읽어오기 fbinfo.c 16 /* get new information for fbvar */ ioctl_ret = ioctl(fb_fd, FBIOGET_VSCREENINFO, &fbvar); if(ioctl_ret< 0 ){ perror("fbdevioctl(vscreeninfo GET)"); return -1; printf("changed BPP = %d\n", fbvar.bits_per_pixel); // set the value of BPP to 32 fbvar.bits_per_pixel = 32; ioctl_ret = ioctl(fb_fd, FBIOPUT_VSCREENINFO, &fbvar); // write to driver if(ioctl_ret< 0 ){ perror("fbdevioctl(vscreeninfo PUT)"); return -1; close(fb_fd); return 0; /* end of main() */
LCD 정보를읽어오는프로그램작성 LCD 정보읽어오기 호스트컴퓨터에서크로스컴파일러를사용하여타겟용으로컴파일 root@esp:~/work/fb/fb_information# arm-linux-gcc o fb_info fbinfo.c 호스트컴퓨터와타겟보드끼리 NFS 연결후타겟보드에서프로그램실행하기 17
프레임버퍼를사용하여 LCD 화면제어 LCD 화면에가장기본적인데이터를출력해보자 점찍기, 선그리기, 삼각형그리기, 원그리기등 이를위해서는다음의내용을알아야함 사용하는 LCD의해상도 (resolution) 위치에대한좌표계산방법 BPP 정보와픽셀에쓸데이터만드는방법 데이터를 FB에 writing하는방법등 18
프레임버퍼를사용하여 LCD 화면제어 RGB-565 데이터구조 RBG-565 의경우색상표현을쉽게하기위하여각각바이트로표현된 R, G, B 값을받아들인다음, 가중치가낮은 LSB 쪽의값을각각 3, 2, 3 비트버려서총 16 비트의컬러를생성 get_color16() 함수는바이트로표현된 R, G, B 의값을받아들여 16 비트의컬러를생성한다. unsigned short get_color16(unsigned char r, unsigned char g, unsigned char b) { return (unsigned short)(((r>>3)<<11) ((g>>2)<<5) (b>>3)); 19
프레임버퍼를사용하여 LCD 화면제어 Achro-210T 보드의 TFT-LCD(800 480 해상도 ) 800 480 해상도에서의픽셀좌표정보 20
프레임버퍼를사용하여 LCD 화면제어 RGB-888 데이터구조 RGB-888 구조에서사용되는픽셀의색상정보를쉽게생성할수있도록 get_color24() 함수를설계하기 함수는각각바이트로선언된 r, g, b 값을받아들여위구조체의색상필드에위치하도록하고, 최상위 8 비트는 0 으로설정한 함수에서반환되는최종값은 r, g, b 값으로구성된 24 비트의값 unsigned int get_color24 (unsigned char r, unsigned char g, unsigned char b) { return (unsigned int)((0x00000000) (r<<16) (g<<8) b)); 21
프레임버퍼를사용하여 LCD 화면제어 Achro-210T 보드의 TFT-LCD 화면해상도 22
프레임버퍼를사용하여 LCD 화면제어 LCD 화면에서의픽셀좌표표시예 23
프레임버퍼를사용하여 LCD 화면제어 프레임버퍼메모리위치환산 24
프레임버퍼를사용하여 LCD 화면제어 주어진좌표 (xp, yp) 로부터프레임버퍼메모리의위치를계산하는함수 fb_memloc() 을설계하기 long fb_memloc(unsigned int xp, unsigned int yp) { if ((xp > fbvar.xres) (yp > fbvar.yres) ) { printf("the coordinate (%d, %d) is out of range!!!\n", xp, yp); exit(1); return((offset_t)(fbvar.xres * yp + xp) * (fbvar.bits_per_pixel/8) ); 25
프레임버퍼를사용하여 LCD 화면제어 프레임버퍼사용하기 프레임버퍼메모리접근은 /dev/fb 파일을열어서생성된파일기술자 (file descriptor) 를통해서접근 파일기술자는 int 형태로표현되며, 입력및출력처리에대한저수준의인터페이스를제공 파일기술자를사용하여메모리또는파일내의위치를변경할때사용하는함수는 lseek() 함수형식 : off_t lseek(int fd, off_t offset, int start_flag); typedef long off_t; 26
프레임버퍼제어 파일기술자위치이동하기 파일기술자위치이동예 lseek (fd, (off_t)100, SEEK_CUR) lseek (fd, offset, SEEK_SET) 27
간단한프레임버퍼프로그래밍 -LCD 화면에점찍는프로그램작성 LCD 화면에점찍기 LCD 화면에 4 개의점을찍는프로그램을만들어보기 좌표 (10, 10) 에빨간색점, 좌표 (100, 50) 에는초록색점, 좌표 (50, 100) 에는파란색점, 좌표 (100, 100) 에는흰색점을표시 데이터타입을일목요연하게보이게하기위해몇개의타입을 typedef 를사용하여재정의 typedef unsigned char u8; typedef unsigned int u32; typedef long offset_t; 28
간단한프레임버퍼프로그래밍 -LCD 화면에점찍는프로그램작성 LCD 화면에점찍기 프로그램작성하기 root@esp-desktop:~# cd ~/work/fb/ 프레임버퍼관련은 ~/work/fb 에서수행 root@esp-desktop:~/work/fb# vi drawdot.c 29
간단한프레임버퍼프로그래밍 -LCD 화면에점찍는프로그램작성 LCD 화면에점찍기 drawdot.c /* Drawing dots filename: drawdot.c */ #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/ioctl.h> #include <linux/fb.h> #define FBDEVFILE "/dev/fb 30
간단한프레임버퍼프로그래밍 -LCD 화면에점찍는프로그램작성 LCD 화면에점찍기 drawdot.c typedef unsigned char u8; typedef unsigned int u32; typedef long offset_t; u32 get_color32(u8 a, u8 r, u8 g, u8 b); offset_t fb_memloc(u32 xp, u32 yp); void drawdot(u32 xp, u32 yp, u32 color); int fb_fd; // file descriptor struct fb_var_screeninfo fbvar; struct fb_fix_screeninfo fbfix; 31
간단한프레임버퍼프로그래밍 -LCD 화면에점찍는프로그램작성 LCD 화면에점찍기 drawdot.c 32 /* make pixel color from a, r, g, b (BPP=32-bit)*/ u32 get_color32(u8 a, u8 r, u8 g, u8 b) { return ((u32) ( (a<<24) (r<<16) (g<<8) b)); /* get the location of framebuffer memory from the coordinate */ offset_t fb_memloc(u32 xp, u32 yp) { if ((xp > fbvar.xres) (yp > fbvar.yres) ) { printf("the coordinate (%d, %d) is out of range!!!\n", xp, yp); exit(1); return((offset_t)(fbvar.xres * yp + xp) * (fbvar.bits_per_pixel/8));
간단한프레임버퍼프로그래밍 -LCD 화면에점찍는프로그램작성 LCD 화면에점찍기 drawdot.c /* Put the pixel color data on (xp, yp) */ void drawdot(u32 xp, u32 yp, u32 color) { offset_t offset_value; offset_value = fb_memloc(xp, yp); if( lseek(fb_fd, offset_value, SEEK_SET) < 0 ) { perror("lseek error in fbdev...\n"); exit(1); write(fb_fd, &color, sizeof(fbvar.bits_per_pixel)); 33
간단한프레임버퍼프로그래밍 -LCD 화면에점찍는프로그램작성 LCD 화면에점찍기 drawdot.c int main(int argc, char *argv[]) { int ioctl_ret; u32 pixel_data; // open the device for frame buffer fb_fd = open(fbdevfile, O_RDWR); if (fb_fd < 0 ) { perror("framebuffer device open error.."); return -1; // get current screen information ioctl_ret = ioctl(fb_fd, FBIOGET_VSCREENINFO, &fbvar); 34
간단한프레임버퍼프로그래밍 -LCD 화면에점찍는프로그램작성 LCD 화면에점찍기 drawdot.c if(ioctl_ret < 0) { perror("error: fb dev ioctl(vscreeninfo GET)"); return -1; ioctl_ret = ioctl(fb_fd, FBIOGET_FSCREENINFO, &fbfix); if(ioctl_ret < 0) { perror("error: fb dev ioctl(fscreeninfo GET)"); return -1; if (fbvar.bits_per_pixel!= 32 ) { // check if bpp is 32 printf("bpp is not 32...\n"); return -1; 35
간단한프레임버퍼프로그래밍 -LCD 화면에점찍는프로그램작성 LCD 화면에점찍기 drawdot.c drawdot(10, 10, get_color32(0, 255, 0, 0)); // Put red point on (0,0) drawdot(100, 50, get_color32(0, 0, 255, 0)); // Green point on (100,50) drawdot(50, 100, get_color32(0, 0, 0, 255)); // Blue point on (50, 100) drawdot(100, 100, get_color32(0, 255, 255, 255)); // White point on (100,100) close(fb_fd); return 0; 36
간단한프레임버퍼프로그래밍 -LCD 화면에점찍는프로그램작성 LCD 화면에점찍기 컴파일하기 root@esp-desktop:~/work/fb# arm-linux-gcc -o drawdot drawdot.c 타겟보드에서실행하기 root@achro210t:~# cd nfs/work/fb root@achro210t:~/nfs/work/fb#./drawdot 실행화면 37
간단한프레임버퍼프로그래밍 -LCD 화면에선그리는프로그램작성 LCD 화면에선그리기 LCD 화면에선을그리는프로그램을작성하기 간단히프로그램을하기위해 drawline() 함수를설계 drawline() 함수는두개의좌표를받아들이고두좌표사이에선을그리는함수 프로그램작성하기 root@esp-desktop:~/work/fb# vi drawline.c 38
간단한프레임버퍼프로그래밍 -LCD 화면에선그리는프로그램작성 LCD 화면에선그리기 drawline.c /* Drawing lines filename: drawline.c */ #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/ioctl.h> #include <linux/fb.h> #define FBDEVFILE "/dev/fb" #define MIN(X, Y) ((X) < (Y)? (X):(Y)) #define MAX(X, Y) ((X) > (Y)? (X):(Y)) typedef unsigned char u8; typedef unsigned int u32; typedef long offset_t; 39
간단한프레임버퍼프로그래밍 -LCD 화면에선그리는프로그램작성 LCD 화면에선그리기 drawline.c u32 get_color32(u8 a, u8 r, u8 g, u8 b); offset_t fb_memloc(u32 xp, u32 yp); void drawdot(u32 xp, u32 yp, u32 color); void drawline(u32 x1, u32 y1, u32 x2, u32 y2); int fb_fd; // file descriptor struct fb_var_screeninfo fbvar; struct fb_fix_screeninfo fbfix; /* make pixel color data from a, r, g, b (BPP=32-bit) */ u32 get_color32(u8 a, u8 r, u8 g, u8 b) { return ((u32) ( (a<<24) (r<<16) (g<<8) b)); 40
간단한프레임버퍼프로그래밍 -LCD 화면에선그리는프로그램작성 LCD 화면에선그리기 drawline.c /* get the location of framebuffer memory from the coordinate */ offset_t fb_memloc(u32 xp, u32 yp) { if ((xp > fbvar.xres) (yp > fbvar.yres) ) { printf("the coordinate (%d, %d) is out of range!!!\n", xp, yp); exit(1); return((offset_t)(fbvar.xres * yp + xp) * (fbvar.bits_per_pixel/8) ); 41
간단한프레임버퍼프로그래밍 -LCD 화면에선그리는프로그램작성 LCD 화면에선그리기 drawline.c /* Put the pixel color data on (xp, yp) */ void drawdot(u32 xp, u32 yp, u32 color) { offset_t offset_value; offset_value = fb_memloc(xp, yp); if ( lseek(fb_fd, offset_value, SEEK_SET) < 0 ) { perror("lseek error in fbdev...\n"); exit(1); write(fb_fd, &color, sizeof(fbvar.bits_per_pixel)); 42
간단한프레임버퍼프로그래밍 -LCD 화면에선그리는프로그램작성 LCD 화면에선그리기 drawline.c /* Put the pixel data from (x1, y1) to (x2, y2) */ void drawline(u32 x1, u32 y1, u32 x2, u32 y2) { int dx, dy; int xstart, xend, ystart, yend; u32 i, j; dx = x2 - x1; dy = y2 - y1; xstart = MIN(x1, x2); xend = MAX(x1, x2); ystart = MIN(y1, y2); yend = MAX(y1, y2); if ( xstart < 0 ystart < 0 xend > fbvar.xres yend > fbvar.yres ) { printf("out of Range!!! (xstart=%d, ystart=%d, xend=%d, yend=%d\n", xstart, ystart, xend, yend); return; 43
간단한프레임버퍼프로그래밍 -LCD 화면에선그리는프로그램작성 LCD 화면에선그리기 drawline.c 44 if ( dx == 0 ) { // vertical line for ( i=ystart; i<=yend; i++) { drawdot(x1, i, get_color32(0, 255, 255, 255)); else if ( dy == 0 ) { // horizontal line for ( i=xstart; i<=xend; i++ ) { drawdot(i, y1, get_color32(0, 255, 255, 255)); else if ( dx > 0 ) { // negative slope (-1) for ( i=x1, j=y1; i<=x2; i++, j++) { drawdot(i, j, get_color32(0, 255, 255, 255)); else if ( dx < 0 ) { //positive slope (+1) for ( i=x1, j=y1; j<=y2; i--, j++) { drawdot(i, j, get_color32(0, 255, 255, 255)); /* end of drawline() */
간단한프레임버퍼프로그래밍 -LCD 화면에선그리는프로그램작성 LCD 화면에선그리기 drawline.c int main(int argc, char *argv[]) { int ioctl_ret, x, y; offset_t offset_value; u32 pixel_data; // open the device for frame buffer fb_fd = open(fbdevfile, O_RDWR); if (fb_fd < 0 ) { perror("framebuffer device open error.."); return -1; // get current screen information ioctl_ret = ioctl(fb_fd, FBIOGET_VSCREENINFO, &fbvar); if(ioctl_ret < 0) { perror("error: fb dev ioctl(vscreeninfo GET)"); return -1; 45
간단한프레임버퍼프로그래밍 -LCD 화면에선그리는프로그램작성 LCD 화면에선그리기 drawline.c ioctl_ret = ioctl(fb_fd, FBIOGET_FSCREENINFO, &fbfix); if(ioctl_ret < 0) { perror("error: fb dev ioctl(fscreeninfo GET)"); return -1; if (fbvar.bits_per_pixel!= 32 ) { // check if bpp is 32 printf("bpp is not 32...\n"); return -1; /* clearing LCD with black color */ for ( x=0; x < fbvar.xres; x++ ) { for ( y=0; y < fbvar.yres; y++ ) { drawdot(x, y, get_color32(0,0,0,0)); 46
간단한프레임버퍼프로그래밍 -LCD 화면에선그리는프로그램작성 LCD 화면에선그리기 drawline.c // draw the white line of width 10 on the top of LCD for ( y=0; y < 10; y++ ) { for ( x=0; x < fbvar.xres; x++ ) { drawdot(x, y, get_color32(0,255,255,255)); // draw the white line of width on the bottom of LCD for ( y=fbvar.yres-10; y < fbvar.yres; y++ ) { for ( x=0; x < fbvar.xres; x++ ) { drawdot(x, y, get_color32(0,255,255,255)); 47
간단한프레임버퍼프로그래밍 -LCD 화면에선그리는프로그램작성 LCD 화면에선그리기 drawline.c // draw rectangular drawline(100,100,100,200); /* left vertical line( ) */ drawline(100,100,200,100); /* upper horizontal line( ) */ drawline(200,100,200,200); /* right vertical line( ) */ drawline(200,200,100,200); /* lower horizontal line(_) */ drawline(100,100,200,200); /* \ */ drawline(200,100,100,200); /* / */ close(fb_fd); return 0; 48
간단한프레임버퍼프로그래밍 -LCD 화면에선그리는프로그램작성 LCD 화면에선그리기 컴파일하기 root@esp-desktop:~/work/fb# arm-linux-gcc -o drawline drawline.c 타겟보드에서실행하기 root@achro210t:~/nfs/fb#./drawline 실행화면 49
간단한프레임버퍼프로그래밍 -LCD 화면을지우는프로그램작성 화면지우기 LCD 전체화면을지울필요가있는데, 전체화면을지우는방법은특정색상으로화면의모든픽셀들을채우는것 이를위해서 fb_clear() 함수를설계하기 프로그램작성 root@esp-desktop:~/work/fb# vi fb_clear.c 50
간단한프레임버퍼프로그래밍 -LCD 화면을지우는프로그램작성 화면지우기 fb_clear.c /* Clearing LCD filename: fb_clear.c */ #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <sys/ioctl.h> #include <linux/fb.h> #define FBDEVFILE "/dev/fb typedef unsigned char u8; typedef unsigned int u32; typedef unsigned long offset_t; 51
간단한프레임버퍼프로그래밍 -LCD 화면을지우는프로그램작성 화면지우기 fb_clear.c u32 get_color32(u8 a, u8 r, u8 g, u8 b); offset_t fb_memloc(u32 xp, u32 yp); void drawdot(u32 xp, u32 yp, u32 color); void fb_clear(u32 color); int fb_fd; // file descriptor struct fb_var_screeninfo fbvar; struct fb_fix_screeninfo fbfix; /* make pixel color data from a, r, g, b (BPP=32-bit) */ u32 get_color32(u8 a, u8 r, u8 g, u8 b) { return ((u32) ( (a<<24) (r<<16) (g <<8) b)); 52
간단한프레임버퍼프로그래밍 -LCD 화면을지우는프로그램작성 화면지우기 fb_clear.c /* get the location of framebuffer memory from the coordinate */ offset_t fb_memloc(u32 xp, u32 yp) { if ((xp > fbvar.xres) (yp > fbvar.yres) ) { printf("the coordinate (%d, %d) is out of range!!!\n", xp, yp); exit(1); return ((offset_t)(fbvar.xres*yp+xp) * (fbvar.bits_per_pixel/8)); 53
간단한프레임버퍼프로그래밍 -LCD 화면을지우는프로그램작성 화면지우기 fb_clear.c /* Put the pixel color data on (xp, yp) */ void drawdot(u32 xp, u32 yp, u32 color) { offset_t offset_value; offset_value = fb_memloc(xp, yp); if ( lseek(fb_fd, offset_value, SEEK_SET) < 0 ) { perror("lseek error in fbdev...\n"); exit(1); write(fb_fd, &color, sizeof(fbvar.bits_per_pixel)); 54
간단한프레임버퍼프로그래밍 -LCD 화면을지우는프로그램작성 화면지우기 fb_clear.c /* clear LCD using drawdot function */ void fb_clear(u32 color) { int x, y; for(x = 0; x < fbvar.xres; x++){ for(y = 0; y < fbvar.yres; y++){ drawdot(x, y, color); 55
간단한프레임버퍼프로그래밍 -LCD 화면을지우는프로그램작성 화면지우기 fb_clear.c int main(int argc, char *argv[]) { int ioctl_ret; // return value //open the device for frame buffer fb_fd = open (FBDEVFILE, O_RDWR); if(fb_fd < 0) { perror("framebuffer device open error.."); return -1; // get current screen information ioctl_ret = ioctl(fb_fd, FBIOGET_VSCREENINFO, &fbvar); if(ioctl_ret <0) { perror("error : fb dev ioctl(vscreeninfo GET)"); return -1; 56
간단한프레임버퍼프로그래밍 -LCD 화면을지우는프로그램작성 화면지우기 fb_clear.c ioctl_ret = ioctl(fb_fd, FBIOGET_FSCREENINFO, &fbfix); if(ioctl_ret <0) { perror("error : fb dev ioctl(fscreeninfo GET)"); return -1; if(fbvar.bits_per_pixel!= 32 ) { // check if bpp is 32 printf("bpp is not 32!!!\n"); return -1; // clearing LCD with black color fb_clear(get_color32(0, 0, 0, 0)); close(fb_fd); return 0; 57
간단한프레임버퍼프로그래밍 -LCD 화면을지우는프로그램작성 화면지우기 컴파일하기 root@esp-desktop:~/work/fb# arm-linux-gcc -o fb_clear fb_clear.c 타겟보드에서실행하기 root@achro210t:~/nfs/fb#./fb_clear 실행화면 58
프레임버퍼라이브러리용기본함수만들기 LCD 정보읽어오기 (get_fbinfo) /* get frame buffer information */ int get_fbinfo(int fb_fd) { int ioctl_ret; // return value // get current screen information ioctl_ret = ioctl(fb_fd, FBIOGET_VSCREENINFO, &fbvar); if(ioctl_ret < 0) { perror("error : fb dev ioctl(vscreeninfo GET)"); return -1; ioctl_ret = ioctl(fb_fd, FBIOGET_FSCREENINFO, &fbfix); if(ioctl_ret < 0) { perror("error : fb dev ioctl(fscreeninfo GET)"); return -1; if(fbvar.bits_per_pixel!= 32) { // check if bpp is 32 printf("bpp is not 32!!! \n"); exit(1); return ioctl_ret; 59
프레임버퍼라이브러리용기본함수만들기 점 (fb_dot) /* Put the pixel color data on (xp, yp) with width */ void fb_dot(u32 xp, u32 yp, u32 width, u32 color) { offset_t offset_value; int i, j; for(i = 0; i < width; i++){ for(j = 0; j < width; j++){ offset_value = fb_memloc(xp+i, yp+j); if(lseek(fb_fd, offset_value, SEEK_SET) < 0){ perror("lseek error in fbdev...\n"); return ; write(fb_fd, &color, sizeof(fbvar.bits_per_pixel)); 60
프레임버퍼라이브러리용기본함수만들기 전체화면색칠하기 (fb_clear) /* clear LCD using fb_dot function */ void fb_clear(u32 color) { int x, y; for(x = 0; x < fbvar.xres; x++){ for(y = 0; y < fbvar.yres; y++){ fb_dot(x, y, 1, color); 61
프레임버퍼라이브러리용기본함수만들기 직선 (fb_line) fb_line 함수에서의각인자와의관계 62
프레임버퍼라이브러리용기본함수만들기 직선 (fb_line) /* draw either horizontal or vertical line from (x1, y1) to (x2, y2) */ void fb_line(u32 x1, u32 y1, u32 x2, u32 y2, u32 width, u32 color) { int x, y; int iter, i; if(y1 == y2){ /* horizontal line */ iter = ceil((x2 - x1) / (float)width); for(x=x1, i = 0; i < iter; i++){ fb_dot(x, y1, width, color); x += width; if( (x+width) > x2){ x = x2 - width; 63
프레임버퍼라이브러리용기본함수만들기 사각형 (fb_rect) fb_rect 함수와 fb_rect2 함수인자와의관계 64
프레임버퍼라이브러리용기본함수만들기 사각형 (fb_rect) /* draw rectangular with the top-left and the bottom-right coordinates */ void fb_rect(u32 x1, u32 y1, u32 x2, u32 y2, u32 width, u32 color) { fb_line(x1, y1, x2, y1, width, color); /* upper horizontal line( ) */ fb_line(x1, y2-width, x2, y2-width, width, color); /* lower horizontal line(_) */ fb_line(x1, y1, x1, y2, width, color); /* left vertical line( ) */ fb_line(x2-width, y1, x2-width, y2, width, color); /* right vertical line( ) */ /* draw rectangular with the top-left coordinate and both lengths of it */ void fb_rect2(u32 x, u32 y, u32 h_len, u32 v_len, u32 width, u32 color) { fb_line(x, y, x+h_len, y, width, color); /* upper horizontal line( ) */ fb_line(x, y+v_len-width, x+h_len, y+v_len-width, width, color); /* lower horizontal line(_) */ fb_line(x, y, x, y+v_len, width, color); /* left vertical line( ) */ fb_line(x+h_len-width, y, x+h_len-width, y+v_len, width, color); /* right vertical line( ) */ 65
프레임버퍼라이브러리용기본함수만들기 삼각형 (fb_triangle) fb_triangle 함수인자와의관계 66
프레임버퍼라이브러리용기본함수만들기 삼각형 (fb_triangle) /* draw triangle with the top coordinate and height */ void fb_triangle(u32 x, u32 y, u32 width, u32 height, u32 color) { int i; for(i = 0; i <= height; i++){ fb_dot(x-i, y+i, width, color); fb_dot(x+i, y+i, width, color); for(i = 0; i < (2*height); i += width){ fb_dot(x-height+i, y+height, width, color); 67
프레임버퍼라이브러리용기본함수만들기 원 (fb_circle) fb_circle 함수인자와의관계 68
프레임버퍼라이브러리용기본함수만들기 원 (fb_circle) /* draw circle with the center and radius */ void fb_circle(u32 xp, u32 yp, u32 r, u32 color) { int i, j; offset_t offset_value; for(i = 0; i < 2*r + 2; i++){ for(j = 0; j < 2*r + 2; j++){ if(r*r > ( (i-r)*(i-r) + (j-r)*(j-r))){ offset_value = fb_memloc(i+xp, j+yp); if ( lseek(fb_fd, offset_value, SEEK_SET) < 0) { perror("lseek error in fbdev...\n"); return; write(fb_fd, &color, sizeof(fbvar.bits_per_pixel)); 69
프레임버퍼용라이브러리만들기 프레임버퍼용헤더파일 (fb_header.h) fb_header.h 헤더파일은프레임버퍼용라이브러리에포함되는함수들의함수원형 (function prototype) 선언과필요한데이터타입들과헤더파일등의정보로구성 프레임버퍼용라이브러리생성및테스트는루트홈디렉토리 (/root) 하위의 mylib 에서하는것으로가정 헤더파일만들기 root@esp-desktop:~# mkdir /root/mylib root@esp-desktop:~# cd /root/mylib root@esp-desktop:~/mylib# vi fb_header.h 70
프레임버퍼용라이브러리만들기 프레임버퍼용헤더파일 (fb_header.h) fb_header.h #include <linux/fb.h> #include <math.h> #define FBDEVFILE "/dev/fb typedef unsigned char u8; typedef unsigned int u32; typedef unsigned long offset_t; int get_fbinfo(int fb_fd); u32 get_color32(u8 a, u8 r, u8 g, u8 b); offset_t fb_memloc(u32 xp, u32 yp); void fb_dot(u32 xp, u32 yp, u32 width, u32 color); void fb_clear(u32 color); void fb_line(u32 x1, u32 y1, u32 x2, u32 y2, u32 width, u32 color); void fb_rect(u32 x1, u32 y1, u32 x2, u32 y2, u32 width, u32 color); void fb_rect2(u32 x, u32 y, u32 h_len, u32 v_len, u32 width, u32 color); void fb_triangle(u32 x, u32 y, u32 width, u32 height, u32 color); void fb_circle(u32 xp, u32 yp, u32 size, u32 color); 71 int fb_fd; // file descriptor struct fb_var_screeninfo fbvar; struct fb_fix_screeninfo fbfix;
프레임버퍼용라이브러리만들기 프레임버퍼용라이브러리파일 (fb_mlib.c) 앞에서설계한점, 선, 사각형, 삼각형, 원등의프레임버퍼용기본함수들을라이브러리로만들어보기 fb_mlib.c 파일만들기 root@esp-desktop:~/mylib# vi fb_mlib.c 72
프레임버퍼용라이브러리만들기 프레임버퍼용라이브러리파일 (fb_mlib.c) fb_mlib.c 73 #include "./fb_header.h" /* get frame buffer information */ int get_fbinfo(int fb_fd) { int ioctl_ret; // return value // get current screen information ioctl_ret = ioctl(fb_fd, FBIOGET_VSCREENINFO, &fbvar); if(ioctl_ret < 0) { perror("error : fb dev ioctl(vscreeninfo GET)"); return -1; ioctl_ret = ioctl(fb_fd, FBIOGET_FSCREENINFO, &fbfix); if(ioctl_ret < 0) { perror("error : fb dev ioctl(fscreeninfo GET)"); return -1; if(fbvar.bits_per_pixel!= 32) { // check if bpp is 32 printf("bpp is not 32!!! \n"); exit(1); return ioctl_ret;
프레임버퍼용라이브러리만들기 프레임버퍼용라이브러리파일 (fb_mlib.c) fb_mlib.c /* make pixel color data from a, r, g, b (BPP=32-bit) */ u32 get_color32(u8 a, u8 r, u8 g, u8 b) { return ((u32) ( (a<<24) (r<<16) (g <<8) b)); /* get the location of framebuffer memory from the coordinate */ offset_t fb_memloc(u32 xp, u32 yp) { if ((xp > fbvar.xres) (yp > fbvar.yres) ) { printf("the coordinate (%d, %d) is out of range!!!\n", xp, yp); exit(1); return ((offset_t)(fbvar.xres*yp+xp) * (fbvar.bits_per_pixel/8)); 74
프레임버퍼용라이브러리만들기 프레임버퍼용라이브러리파일 (fb_mlib.c) fb_mlib.c /* Put the pixel color data on (xp, yp) with width */ void fb_dot(u32 xp, u32 yp, u32 width, u32 color) { offset_t offset_value; int i, j; for(i = 0; i < width; i++){ for(j = 0; j < width; j++){ offset_value = fb_memloc(xp+i, yp+j); if(lseek(fb_fd, offset_value, SEEK_SET) < 0){ perror("lseek error in fbdev...\n"); return ; write(fb_fd, &color, sizeof(fbvar.bits_per_pixel)); 75
프레임버퍼용라이브러리만들기 프레임버퍼용라이브러리파일 (fb_mlib.c) fb_mlib.c /* clear LCD using fb_dot function */ void fb_clear(u32 color) { int x, y; for(x = 0; x < fbvar.xres; x++){ for(y = 0; y < fbvar.yres; y++){ fb_dot(x, y, 1, color); 76
프레임버퍼용라이브러리만들기 프레임버퍼용라이브러리파일 (fb_mlib.c) fb_mlib.c /* draw either horizontal or vertical line from (x1, y1) to (x2, y2) */ void fb_line(u32 x1, u32 y1, u32 x2, u32 y2, u32 width, u32 color) { int x, y; int iter, i; if(y1 == y2){ /* horizontal line */ iter = ceil((x2 - x1) / (float)width); for(x=x1, i = 0; i < iter; i++){ fb_dot(x, y1, width, color); x += width; if( (x+width) > x2){ x = x2 - width; 77
프레임버퍼용라이브러리만들기 프레임버퍼용라이브러리파일 (fb_mlib.c) fb_mlib.c if(x1 == x2){ /* vertical line */ iter = ceil((y2 - y1) / (float)width); for(y=y1,i = 0; i < iter; i++){ fb_dot(x1, y, width, color); y += width; if( (y+width) > y2){ y = y2 - width; /* draw rectangular with the top-left and the bottom-right coordinates */ void fb_rect(u32 x1, u32 y1, u32 x2, u32 y2, u32 width, u32 color) { fb_line(x1, y1, x2, y1, width, color); /* upper horizontal line( ) */ fb_line(x1, y2-width, x2, y2-width, width, color); /* lower horizontal line(_) */ fb_line(x1, y1, x1, y2, width, color); /* left vertical line( ) */ fb_line(x2-width, y1, x2-width, y2, width, color); /* right vertical line( ) */ 78
프레임버퍼용라이브러리만들기 프레임버퍼용라이브러리파일 (fb_mlib.c) fb_mlib.c 79 /* draw rectangular with the left-top coordinate and both lengths of it */ void fb_rect2(u32 x, u32 y, u32 h_len, u32 v_len, u32 width, u32 color) { fb_line(x, y, x+h_len, y, width, color); /* upper horizontal line( ) */ fb_line(x, y+v_len-width, x+h_len, y+v_len-width, width, color); /* lower horizontal line(_) */ fb_line(x, y, x, y+v_len, width, color); /* left vertical line( ) */ fb_line(x+h_len-width, y, x+h_len-width, y+v_len, width, color); /* right vertical line( ) */ /* draw triangle with the top coordinate and height */ void fb_triangle(u32 x, u32 y, u32 height, u32 width, u32 color) { int i; for(i = 0; i <= height; i++){ fb_dot(x-i, y+i, width, color); fb_dot(x+i, y+i, width, color); for(i = 0; i < (2*height); i += width){ fb_dot(x-height+i, y+height, width, color);
프레임버퍼용라이브러리만들기 프레임버퍼용라이브러리파일 (fb_mlib.c) fb_mlib.c /* draw circle with the center and radius */ void fb_circle(u32 xp, u32 yp, u32 r, u32 color) { int i, j; offset_t offset_value; for(i = 0; i < 2*r + 2; i++){ for(j = 0; j < 2*r + 2; j++){ if(r*r > ( (i-r)*(i-r) + (j-r)*(j-r))){ offset_value = fb_memloc(i+xp, j+yp); if ( lseek(fb_fd, offset_value, SEEK_SET) < 0) { perror("lseek error in fbdev...\n"); return; write(fb_fd, &color, sizeof(fbvar.bits_per_pixel)); 80
프레임버퍼용라이브러리만들기 프레임버퍼용라이브러리만들기 라이브러리로만들고자하는소스파일을옵션 c를사용하여바이너리파일 (.o) 로컴파일하기 root@esp-desktop:~/mylib# arm-linux-gcc -c fb_mlib.c root@esp-desktop:~/mylib# ls 합계 16 4 fb_header.h* 4 fb_mlib.c* 8 fb_mlib.o 아카이브라이브러리파일생성 root@esp-desktop:~/mylib# ar -r /root/work/mylib/libmyfb.a /root/work/mylib/fb_mlib.o ar: creating /root/mylib/libmyfb.a 라이브러리내에인덱스만들기 root@esp-desktop:~/mylib# ranlib /root/mylib/libmyfb.a 81
프레임버퍼용라이브러리만들기 프레임버퍼라이브러리를이용하여도형그리기 생성된라이브러리 (libmyfb.a) 와헤더파일 (fb_header.h) 을사용하면, 프레임버퍼에여러가지도형들을손쉽게출력가능 라이브러리를사용하여 LCD 에여러가지도형출력하기 테스트파일명은 fblib_test.c 파일생성하기 root@esp-desktop:~/mylib# vi fblib_test.c 82
프레임버퍼용라이브러리만들기 프레임버퍼라이브러리를이용하여도형그리기 fblib_test.c #include "./fb_header.h" int main(int argc, char *argv[]) { int ioctl_ret, x, y; // return value offset_t offset_value; u32 pixel_data; //open the device node for frame buffer fb_fd = open (FBDEVFILE, O_RDWR); if(fb_fd < 0) { perror("framebuffer device open error.."); return -1; /* get current screen information */ ioctl_ret = get_fbinfo(fb_fd); // clearing LCD with black color fb_clear(get_color32(0, 0, 0, 0)); // draw a white boundary line of width 10 fb_line(0, 0, fbvar.xres-10, 0, 10, get_color32(0, 255, 255, 255)); fb_line(0, fbvar.yres-10, fbvar.xres-10, fbvar.yres-10, 10, get_color32(0, 255, 255, 255)); /* - */ 83
프레임버퍼용라이브러리만들기 프레임버퍼라이브러리를이용하여도형그리기 fblib_test.c 84 fb_line(0, 0, 0, fbvar.yres, 10, get_color32(0, 255, 255, 255)); /* */ fb_line(fbvar.xres-10, 0, fbvar.xres-10, fbvar.yres, 10, get_color32(0, 255, 255, 255)); /* */ // draw Rectangular with the left-top and the right-bottom coordinates fb_rect(50, 50, 150, 150, 10, get_color32(0, 255, 255, 255)); // draw Rectangular with (xp, yp) and both lengths of it fb_rect2(200, 50, 100, 200, 10, get_color32(0, 128, 128, 128)); // draw Triangle with one coordinate and height fb_triangle(150, 250, 100, 20, get_color32(0, 255, 255, 255)); // draw horizontal lines fb_line(450, 50, 750, 50, 10, get_color32(0, 255, 0, 0)); fb_line(450, 100, 750, 100, 20, get_color32(0, 0, 255, 0)); fb_line(450, 150, 750, 150, 30, get_color32(0, 0, 0, 255)); // draw vertical lines fb_line(450, 240, 450, 400, 10, get_color32(0, 255, 0, 0)); fb_line(550, 240, 550, 400, 20, get_color32(0, 0, 255, 0)); fb_line(650, 240, 650, 400, 30, get_color32(0, 0, 0, 255)); // draw Circle with a center and radius fb_circle(300, 300, 30, get_color32(0, 255, 255, 255)); close(fb_fd); return 0;
프레임버퍼용라이브러리만들기 프레임버퍼라이브러리를이용하여도형그리기 컴파일하기 root@esp-desktop:~/mylib# arm-linux-gcc -o fblib_test fblib_test.c -L/root/work/mylib -lmyfb -lm root@esp-desktop:~/mylib# ls 합계 44 4 fb_header.h* 4 fb_mlib.c* 8 fb_mlib.o 16 fblib_test* 4 fblib_test.c* 8 libmyfb.a 타겟보드에서실행하기 root@achro210t:~# cd nfs/mylib/ root@achro210t:~/nfs/mylib#./fblib_test 85
프레임버퍼용라이브러리만들기 프레임버퍼라이브러리를이용하여도형그리기 결과화면 86
BMP Header BMP 헤더 BMP 헤더 파일정보를가지고있는헤더인 BITMAPFILEHEADER 이미지의정보를가지고있는 BITMAPINFOHEADER BITMAPFILEHEADER bftype : 비트맵타입을나타냄 'BM' nfsize : 해당이미지파일의크기 bfreserved1 : 예약된공간 bfreserved2 : 예약된공간 bfoffbit : 실제픽셀정보공간까지의거리 87
BMP Header BMP 헤더 BITMAPINFOHEADER bisize : 이구조체를저장하기위한바이트수 (Default : 40Byte, 확장형 DIB 사용시변동 ) biwidth : 비트맵의가로크기 ( 픽셀단위 ) biheight : 비트맵의세로크기 ( 픽셀단위 ) biplane : 디스플레이시필요한플레인수 (Always : 1) bibitcount : 한픽셀을표현하기위한비트수 bicompression : 압축유형 (Default : BI_RGB - 비압축 ) bisizeimage : 픽셀데이터를저장하기위한공간 bixpelspermeter : 가로해상도 biypelspermeter : 세로해상도 bicirused : 실제사용되는색상수 (Default 0 : bibitcount 에서지정한모든색상사용 ) biclrimportant : 화면에표현하기위한색상의인덱스 (Default 0 : 모든색상 ) 88
BMP Header BMP 헤더 비트맵파일헤더 (BITMAPFILEHEADER) 89
BMP Header BMP 헤더 비트맵정보헤더 (BITMAPINFOHEADER) 90
BMP Header BMP 헤더 비트맵파일헤더구조체 typedef struct tagbitmapfileheader{ short bftype; int bfsize; short bfreserved1; short bfreserved2; int bfoffbits; attribute (( packed )) BITMAPFILEHEADER; 91
BMP Header BMP 헤더 비트맵정보헤더구조체 typedef struct tagbitmapinfoheader{ int bisize; long biwidth; long biheight; short biplanes; short bibitcount; int bicompression; int bisizeimage; long bixpelspermeter; long biypelspermeter; int biclrused; int biclrimportant; attribute (( packed )) BITMAPINFOHEADER; 92
BMP 정보출력프로그램작성 BMP 헤더의정보를이용하여 bmp 파일의정보를읽어출력하는프로그램을작성하기 Bmp 헤더파일생성하기 root@esp:~/work/fb# mkdir BMP root@esp:~/work/fb# cd BMP root@esp:~/work/fb/bmp# vi bmp_header.h 93
BMP 정보출력프로그램작성 bmp_header.h /* Bmp File display to Frame-buffer example * FILE : bmp_header.h */ #ifndef _BMPINFO_ #define _BMPINFO_ // display area size #define WIDTH 800 #define HEIGHT 480 // make type definition - windows type typedef unsigned short U16; typedef unsigned short WORD; typedef unsigned int DWORD; typedef unsigned int LONG; typedef unsigned char BYTE; 94
BMP 정보출력프로그램작성 bmp_header.h // make type definition - bmp file header typedef struct tagbitmapfileheader{ WORD bftype; DWORD bfsize; WORD bfreserved1; WORD bfreserved2; DWORD bfoffbits; attribute((packed))bitmapfileheader; 95
BMP 정보출력프로그램작성 bmp_header.h 96 // make type definition - bmp image infomation header typedef struct tagbitmapinfoheader{ DWORD bisize; LONG biwidth; LONG biheight; WORD biplanes; WORD bibitcount; DWORD bicompression; DWORD bisizeimage; LONG bixpelspermeter; LONG biypelspermeter; DWORD biclrused; DWORD biclrimportant; attribute((packed)) BITMAPINFOHEADER; /* other mathod : Group Attribute Packed Mathod #pragma pack(1) or pragma pack() */ #endif
BMP 정보출력프로그램작성 정보출력프로그램작성하기 root@esp:~/work/fb/bmp# vi bmp_info.c bmp_info.c 97 /* Bmp File display to Frame-buffer example * FILE : bmp_info.c */ #include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <string.h> #include <sys/ioctl.h> #include <sys/types.h> #include <linux/fb.h> #include "bmp_header.h" int main(int argc, char **argv) { BITMAPFILEHEADER BmpFileHd; BITMAPINFOHEADER BmpInfoHd; size_t retval;
BMP 정보출력프로그램작성 bmp_info.c int fb_fd; // Framebuffer discriptor struct fb_var_screeninfo fvs; FILE *read_fp=null; if(argc!=2){ // Argument check printf("usage : %s [FileName]\n",argv[0]); return -1; if ((read_fp = fopen(argv[1],"rb")) == NULL) { // File Open printf("file Open Error\n"); exit(1); // File Read - Bmp File Header fread(&bmpfilehd, sizeof(bitmapfileheader), 1, read_fp); if(bmpfilehd.bftype!=0x4d42) { printf("not Bitmap file or Unsupport Bitmap file\n"); exit(1); 98
BMP 정보출력프로그램작성 bmp_info.c printf("* BMP File Header - \n"); printf(" Type : 0x%04X\n", BmpFileHd.bfType); printf(" Size : %d\n", BmpFileHd.bfSize); printf(" Offbits : %d\n", BmpFileHd.bfOffBits); // File Read - Bmp Image infomation header fread(&bmpinfohd, sizeof(bitmapinfoheader), 1, read_fp); 99
BMP 정보출력프로그램작성 bmp_info.c printf("* BMP Info Header - \n"); printf(" FIleName : %s\n",argv[1]); printf(" Infosize : %d\n", BmpInfoHd.biSize); printf(" Width : %d\n", BmpInfoHd.biWidth); printf(" Height : %d\n", BmpInfoHd.biHeight); printf(" Planes : %d\n", BmpInfoHd.biplanes); printf(" Bitcount : %d\n", BmpInfoHd.biBitCount); printf(" Compressin : %d\n", BmpInfoHd.biCompression); printf(" Sizeimage : %d\n", BmpInfoHd.biSizeImage); printf(" XPelsPerMeter : %d\n", BmpInfoHd.biXPelsPerMeter); printf(" YPelsPerMeter : %d\n", BmpInfoHd.biYPelsPerMeter); printf(" ClrUsed : %d\n", BmpInfoHd.biClrUsed); printf(" ClrImportant : %d\n", BmpInfoHd.biClrImportant); fclose(read_fp); return 0; 100
BMP 정보출력프로그램작성 컴파일하기 root@esp:~/work/fb/bmp# arm-linux-gcc -o bmp_info bmp_info.c bmp 파일이미지정보출력 101