This is an old revision of the document!
Souce Code는 다음과 같다.
#include <stdio.h> #include <string.h> /* for memset */ #include <unistd.h> /* for open/close .. */ #include <fcntl.h> /* for O_RDWR */ #include <sys/ioctl.h> /* for ioctl */ #include <sys/mman.h> /* for mmap */ #include <linux/fb.h> /* for fb_var_screeninfo, FBIOGET_VSCREENINFO */ #define DEFAULT_FRAME_BUFFER_FILE "/dev/fb0" typedef struct { int Device; void * pFrameBuffer; struct fb_var_screeninfo var; struct fb_fix_screeninfo fix; } FrameBufferContext_t; void draw_pixel( FrameBufferContext_t *pFrameBufferContext, unsigned long X, unsigned long Y, unsigned long Color) { void * pFrameBuffer; pFrameBuffer = pFrameBufferContext->pFrameBuffer; if (pFrameBufferContext->var.bits_per_pixel == 8) { unsigned char * p; pFrameBuffer += pFrameBufferContext->fix.line_length * Y; p = pFrameBuffer; p += X; *p = (unsigned char)Color; } else if (pFrameBufferContext->var.bits_per_pixel == 16) { unsigned short * p; pFrameBuffer += pFrameBufferContext->fix.line_length * Y; p = pFrameBuffer; p += X; *p = (unsigned short)(((((Color >> 16) & 0xff) * 32 / 256) << 11) | ((((Color >> 8) & 0xff) * 64 / 256) << 5) | ((((Color >> 0) & 0xff) * 32 / 256) << 0)); } else if (pFrameBufferContext->var.bits_per_pixel == 24) { unsigned char * p; p = (unsigned char *)pFrameBuffer + pFrameBufferContext->fix.line_length * Y + 3 * X; *p++ = (unsigned char)Color; *p++ = (unsigned char)(Color >> 8); *p = (unsigned char)(Color >> 16); } else { unsigned long * p; pFrameBuffer += pFrameBufferContext->fix.line_length * Y; p = pFrameBuffer; p += X; *p = Color; } } void fill_screen(FrameBufferContext_t *pFrameBufferContext) { unsigned long x; unsigned long y; unsigned long h; unsigned long w; h = pFrameBufferContext->var.yres; w = pFrameBufferContext->var.xres; for (y = 0; y < h; y++) { for (x = 0; x < w; x++) { if (x < 20 && y < 20) { draw_pixel(pFrameBufferContext, x, y, 0xffffff); } else if (x < 20 && (y > 20 && y < h - 20)) { draw_pixel(pFrameBufferContext, x, y, 0xff); } else if (y < 20 && (x > 20 && x < w - 20)) { draw_pixel(pFrameBufferContext, x, y, 0xff00); } else if (x > w - 20 && (y > 20 && y < h - 20)) { draw_pixel(pFrameBufferContext, x, y, 0xff0000); } else if (y > h - 20 && (x > 20 && x < w - 20)) { draw_pixel(pFrameBufferContext, x, y, 0xffff00); } else if (x == 20 || x == w - 20 || y == 20 || y == h - 20) { draw_pixel(pFrameBufferContext, x, y, 0xffffff); } else if (x == y || w - x == h - y) { draw_pixel(pFrameBufferContext, x, y, 0xff00ff); } else if (w - x == y || x == h - y) { draw_pixel(pFrameBufferContext, x, y, 0x00ffff); } else if (x > 20 && y > 20 && x < w - 20 && y < h - 20) { int t = x * 3 / w; unsigned r = 0, g = 0, b = 0; unsigned c; if (pFrameBufferContext->var.bits_per_pixel == 16) { if (t == 0) { b = (y % 32) * 256 / 32; } else if (t == 1) { g = (y % 64) * 256 / 64; } else if (t == 2) { r = (y % 32) * 256 / 32; } } else { if (t == 0) { b = (y % 256); } else if (t == 1) { g = (y % 256); } else if (t == 2) { r = (y % 256); } } c = (b << 16) | (g << 8) | (r << 0); draw_pixel(pFrameBufferContext, x, y, c); } else { draw_pixel(pFrameBufferContext, x, y, 0); } } } } void clear_area( FrameBufferContext_t *pFrameBufferContext, unsigned long X, unsigned long Y, unsigned long W, unsigned long H) { unsigned long AddressOffsetForH; unsigned long CountForH; unsigned char * pFrameBuffer; pFrameBuffer = (unsigned char *)pFrameBufferContext->pFrameBuffer; for (CountForH = 0; CountForH < H; CountForH++) { AddressOffsetForH = (X + pFrameBufferContext->var.xoffset) * (pFrameBufferContext->var.bits_per_pixel / 8) + (Y + CountForH + pFrameBufferContext->var.yoffset) * pFrameBufferContext->fix.line_length; memset(pFrameBuffer + AddressOffsetForH, 0, W * pFrameBufferContext->var.bits_per_pixel / 8); } } int device_open_mode(FrameBufferContext_t *pFrameBufferContext, int BitPerPixel) { pFrameBufferContext->Device = open(DEFAULT_FRAME_BUFFER_FILE, O_RDWR); if(pFrameBufferContext->Device < 0) { printf("Faile to open : %s \n", DEFAULT_FRAME_BUFFER_FILE); return -1; } if(ioctl(pFrameBufferContext->Device, FBIOGET_VSCREENINFO, &pFrameBufferContext->var) < 0) { printf("fbdev ioctl(VSCREENINFO)\n"); close(pFrameBufferContext->Device); return -1; } if(ioctl(pFrameBufferContext->Device, FBIOGET_FSCREENINFO, &pFrameBufferContext->fix) < 0) { printf("fbdev ioctl(FSCREENINFO)\n"); close(pFrameBufferContext->Device); return -1; } if(pFrameBufferContext->var.bits_per_pixel != BitPerPixel) { pFrameBufferContext->var.bits_per_pixel = BitPerPixel; if(ioctl(pFrameBufferContext->Device, FBIOPUT_VSCREENINFO, &pFrameBufferContext->var) < 0) { printf("fbdev ioctl(PUT)\n"); close(pFrameBufferContext->Device); return -1; } } return 0; } int device_open(FrameBufferContext_t *pFrameBufferContext) { if(device_open_mode(pFrameBufferContext, 8) != 0) { printf("Faile to open with 8bit: %s \n", DEFAULT_FRAME_BUFFER_FILE); return -1; } close(pFrameBufferContext->Device); if(device_open_mode(pFrameBufferContext, 24) != 0) { printf("Faile to open with 24bit: %s \n", DEFAULT_FRAME_BUFFER_FILE); return -1; } printf("x-resolution : %d\n", pFrameBufferContext->var.xres); printf("y-resolution : %d\n", pFrameBufferContext->var.yres); printf("x-resolution(virtual) : %d\n", pFrameBufferContext->var.xres_virtual); printf("y-resolution(virtual) : %d\n", pFrameBufferContext->var.yres_virtual); printf("bpp : %d\n", pFrameBufferContext->var.bits_per_pixel); printf("length of frame buffer memory : %d\n", pFrameBufferContext->fix.smem_len); return 0; } int main() { FrameBufferContext_t FrameBufferContext; int Error; printf("Opening frame buffer device `%s'\n", DEFAULT_FRAME_BUFFER_FILE); if(device_open(&FrameBufferContext) != 0) { printf("Fail to Device Open\n"); return 0; } FrameBufferContext.pFrameBuffer = mmap(0, FrameBufferContext.var.yres_virtual * FrameBufferContext.fix.line_length, PROT_WRITE | PROT_READ, MAP_SHARED, FrameBufferContext.Device, 0); if(FrameBufferContext.pFrameBuffer == MAP_FAILED) { printf("Frame buffer MAP fail !\n"); close(FrameBufferContext.Device); return 0; } /* Display pattern to screen */ fill_screen(&FrameBufferContext); /* End of... */ munmap( FrameBufferContext.pFrameBuffer, FrameBufferContext.var.yres_virtual * FrameBufferContext.fix.line_length); close(FrameBufferContext.Device); return 0; }
아래와 같이 컴파일 한다.
stephanos@stephanos-VirtualBox:~/VI/App$ /home/stephanos/VI/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc -o test test.c
NFS에 위에서 만들어진 test를 복사한다. Target Board를 NFS로 부팅한다.
로그인 후 아래와 같이 실행한다.