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로 부팅한다.
로그인 후 아래와 같이 실행한다.