This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
test_application [2017/08/23 15:48] 1.241.172.144 |
test_application [2017/09/12 21:23] (current) 1.241.172.144 |
||
---|---|---|---|
Line 2: | Line 2: | ||
===== LCD Test Application ===== | ===== LCD Test Application ===== | ||
- | Souce Code는 다음과 같다. | + | [[DirectFB App]] |
- | #include <stdio.h> | + | [[SDL App]] |
- | #include <stdint.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 */ | + | |
- | + | ||
- | #include "drm.h" /* /home/stephanos/VI/gcc-linaro-6.3.1-2017.05-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/include/drm -> check Makefile */ | + | |
- | #include "drm_mode.h" | + | |
- | + | ||
- | #define DEFAULT_FRAME_BUFFER_FILE "/dev/fb0" | + | |
- | #define DEV_LCD_DRM "/dev/dri/card0" | + | |
- | + | ||
- | + | ||
- | #define MAXIMUM_NUMBER_OF_CONNECTORS 10 | + | |
- | #define MAXIMUM_NUMBER_OF_CONNECTOR_RESOURCE_BUFFER 20 | + | |
- | + | ||
- | typedef struct | + | |
- | { | + | |
- | void * pBuffer; | + | |
- | uint32_t ByteSizeOfBuffer; | + | |
- | uint32_t ScreenWidth; | + | |
- | uint32_t ScreenHeight; | + | |
- | } FrameBuffer_t; | + | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | typedef struct | + | |
- | { | + | |
- | uint64_t pFB_ID[MAXIMUM_NUMBER_OF_CONNECTORS]; | + | |
- | uint64_t pCRTC_ID[MAXIMUM_NUMBER_OF_CONNECTORS]; | + | |
- | uint64_t pCONNECTOR_ID[MAXIMUM_NUMBER_OF_CONNECTORS]; | + | |
- | uint64_t pENCODER_ID[MAXIMUM_NUMBER_OF_CONNECTORS]; | + | |
- | } DRMResourceBuffer_t; | + | |
- | + | ||
- | typedef struct | + | |
- | { | + | |
- | struct drm_mode_modeinfo pMode[MAXIMUM_NUMBER_OF_CONNECTOR_RESOURCE_BUFFER]; | + | |
- | uint64_t pProps[MAXIMUM_NUMBER_OF_CONNECTOR_RESOURCE_BUFFER]; | + | |
- | uint64_t PPropValue[MAXIMUM_NUMBER_OF_CONNECTOR_RESOURCE_BUFFER]; | + | |
- | uint64_t pEncoder[MAXIMUM_NUMBER_OF_CONNECTOR_RESOURCE_BUFFER]; | + | |
- | } DRMConnectorResourceBuffer_t; | + | |
- | + | ||
- | typedef struct | + | |
- | { | + | |
- | struct drm_mode_create_dumb Create; | + | |
- | struct drm_mode_map_dumb Map; | + | |
- | struct drm_mode_fb_cmd Cmd; | + | |
- | } DRMdumbBuffer_t; | + | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | typedef struct | + | |
- | { | + | |
- | int Device; | + | |
- | + | ||
- | void * pFrameBuffer; | + | |
- | + | ||
- | struct fb_var_screeninfo var; | + | |
- | struct fb_fix_screeninfo fix; | + | |
- | } FrameBufferContext_t; | + | |
- | + | ||
- | + | ||
- | + | ||
- | void drm_draw_pixel( FrameBuffer_t *pFrameBuffer, | + | |
- | uint32_t X, | + | |
- | uint32_t Y, | + | |
- | uint32_t Color/*(b << 16) | (g << 8) | (r << 0)*/) | + | |
- | { | + | |
- | if ( pFrameBuffer != (FrameBuffer_t *)0 ) | + | |
- | { | + | |
- | if ((pFrameBuffer->ScreenWidth > X) | + | |
- | && (pFrameBuffer->ScreenHeight > Y)) | + | |
- | { | + | |
- | *(((uint32_t*)pFrameBuffer->pBuffer ) + Y * pFrameBuffer->ScreenWidth + X) = Color; | + | |
- | } | + | |
- | } | + | |
- | } | + | |
- | + | ||
- | void drm_draw_test_pattern(FrameBuffer_t *pFrameBuffer) | + | |
- | { | + | |
- | uint32_t x; | + | |
- | uint32_t y; | + | |
- | uint32_t h; | + | |
- | uint32_t w; | + | |
- | + | ||
- | h = pFrameBuffer->ScreenHeight; | + | |
- | w = pFrameBuffer->ScreenWidth; | + | |
- | for (y = 0; y < h; y++) | + | |
- | { | + | |
- | for (x = 0; x < w; x++) | + | |
- | { | + | |
- | if (x < 20 && y < 20) | + | |
- | { | + | |
- | drm_draw_pixel(pFrameBuffer, x, y, 0xffffff); | + | |
- | } | + | |
- | else if (x < 20 && (y > 20 && y < h - 20)) | + | |
- | { | + | |
- | drm_draw_pixel(pFrameBuffer, x, y, 0xff); | + | |
- | } | + | |
- | else if (y < 20 && (x > 20 && x < w - 20)) | + | |
- | { | + | |
- | drm_draw_pixel(pFrameBuffer, x, y, 0xff00); | + | |
- | } | + | |
- | else if (x > w - 20 && (y > 20 && y < h - 20)) | + | |
- | { | + | |
- | drm_draw_pixel(pFrameBuffer, x, y, 0xff0000); | + | |
- | } | + | |
- | else if (y > h - 20 && (x > 20 && x < w - 20)) | + | |
- | { | + | |
- | drm_draw_pixel(pFrameBuffer, x, y, 0xffff00); | + | |
- | } | + | |
- | else if (x == 20 || x == w - 20 || | + | |
- | y == 20 || y == h - 20) | + | |
- | { | + | |
- | drm_draw_pixel(pFrameBuffer, x, y, 0xffffff); | + | |
- | } | + | |
- | else if (x == y || w - x == h - y) | + | |
- | { | + | |
- | drm_draw_pixel(pFrameBuffer, x, y, 0xff00ff); | + | |
- | } | + | |
- | else if (w - x == y || x == h - y) | + | |
- | { | + | |
- | drm_draw_pixel(pFrameBuffer, 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 (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); | + | |
- | drm_draw_pixel(pFrameBuffer, x, y, c); | + | |
- | } | + | |
- | else | + | |
- | { | + | |
- | drm_draw_pixel(pFrameBuffer, x, y, 0); | + | |
- | } | + | |
- | } | + | |
- | } | + | |
- | } | + | |
- | + | ||
- | void drm_fill_screen(FrameBuffer_t *pFrameBuffer, | + | |
- | uint32_t Color/*(b << 16) | (g << 8) | (r << 0)*/) | + | |
- | { | + | |
- | uint32_t X; | + | |
- | uint32_t Y; | + | |
- | + | ||
- | if ( pFrameBuffer != (FrameBuffer_t *)0 ) | + | |
- | { | + | |
- | for (Y = 0; Y < pFrameBuffer->ScreenHeight; Y++) | + | |
- | { | + | |
- | for (X = 0; X < pFrameBuffer->ScreenWidth; X++) | + | |
- | { | + | |
- | *(((uint32_t*)pFrameBuffer->pBuffer ) + Y * pFrameBuffer->ScreenWidth + X) = Color; | + | |
- | } | + | |
- | } | + | |
- | } | + | |
- | } | + | |
- | + | ||
- | + | ||
- | void fb_draw_pixel( FrameBufferContext_t *pFrameBufferContext, | + | |
- | uint32_t X, | + | |
- | uint32_t Y, | + | |
- | uint32_t 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 | + | |
- | { | + | |
- | uint32_t * p; | + | |
- | + | ||
- | pFrameBuffer += pFrameBufferContext->fix.line_length * Y; | + | |
- | p = pFrameBuffer; | + | |
- | p += X; | + | |
- | + | ||
- | *p = Color; | + | |
- | } | + | |
- | } | + | |
- | + | ||
- | + | ||
- | void fill_screen(FrameBufferContext_t *pFrameBufferContext) | + | |
- | { | + | |
- | uint32_t x; | + | |
- | uint32_t y; | + | |
- | uint32_t h; | + | |
- | uint32_t 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) | + | |
- | { | + | |
- | fb_draw_pixel(pFrameBufferContext, x, y, 0xffffff); | + | |
- | } | + | |
- | else if (x < 20 && (y > 20 && y < h - 20)) | + | |
- | { | + | |
- | fb_draw_pixel(pFrameBufferContext, x, y, 0xff); | + | |
- | } | + | |
- | else if (y < 20 && (x > 20 && x < w - 20)) | + | |
- | { | + | |
- | fb_draw_pixel(pFrameBufferContext, x, y, 0xff00); | + | |
- | } | + | |
- | else if (x > w - 20 && (y > 20 && y < h - 20)) | + | |
- | { | + | |
- | fb_draw_pixel(pFrameBufferContext, x, y, 0xff0000); | + | |
- | } | + | |
- | else if (y > h - 20 && (x > 20 && x < w - 20)) | + | |
- | { | + | |
- | fb_draw_pixel(pFrameBufferContext, x, y, 0xffff00); | + | |
- | } | + | |
- | else if (x == 20 || x == w - 20 || | + | |
- | y == 20 || y == h - 20) | + | |
- | { | + | |
- | fb_draw_pixel(pFrameBufferContext, x, y, 0xffffff); | + | |
- | } | + | |
- | else if (x == y || w - x == h - y) | + | |
- | { | + | |
- | fb_draw_pixel(pFrameBufferContext, x, y, 0xff00ff); | + | |
- | } | + | |
- | else if (w - x == y || x == h - y) | + | |
- | { | + | |
- | fb_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); | + | |
- | fb_draw_pixel(pFrameBufferContext, x, y, c); | + | |
- | } | + | |
- | else | + | |
- | { | + | |
- | fb_draw_pixel(pFrameBufferContext, x, y, 0); | + | |
- | } | + | |
- | } | + | |
- | } | + | |
- | } | + | |
- | + | ||
- | + | ||
- | void clear_area( FrameBufferContext_t *pFrameBufferContext, | + | |
- | uint32_t X, | + | |
- | uint32_t Y, | + | |
- | uint32_t W, | + | |
- | uint32_t H) | + | |
- | { | + | |
- | uint32_t AddressOffsetForH; | + | |
- | uint32_t 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; | + | |
- | } | + | |
- | + | ||
- | static int test_simple_fb_style(void) | + | |
- | { | + | |
- | 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; | + | |
- | } | + | |
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | + | ||
- | static int drm_open(void) | + | |
- | { | + | |
- | int Device; | + | |
- | int Flags; | + | |
- | uint64_t HasDumbBuffer; | + | |
- | + | ||
- | Device = -1; | + | |
- | if ( access(DEV_LCD_DRM, F_OK) ) | + | |
- | { | + | |
- | printf("no device - %s\n", DEV_LCD_DRM); | + | |
- | return 0; | + | |
- | } | + | |
- | + | ||
- | if ( (Device = open(DEV_LCD_DRM, O_RDWR)) <= 0 ) | + | |
- | { | + | |
- | printf("Faile to open : %s \n", DEV_LCD_DRM); | + | |
- | return 0; | + | |
- | } | + | |
- | + | ||
- | // set FD_CLOEXEC flag | + | |
- | Flags = fcntl(Device, F_GETFD); | + | |
- | if (Flags < 0) | + | |
- | { | + | |
- | printf("Faile to read Flags \n"); | + | |
- | close(Device); | + | |
- | return 0; | + | |
- | } | + | |
- | if ( fcntl(Device, F_SETFD, Flags | FD_CLOEXEC) < 0 ) | + | |
- | { | + | |
- | printf("Faile to set Falsgs FD_CLOEXEC \n"); | + | |
- | close(Device); | + | |
- | return 0; | + | |
- | } | + | |
- | + | ||
- | return Device; | + | |
- | } | + | |
- | + | ||
- | + | ||
- | static int drm_get_frame_buffer(FrameBuffer_t *pFrameBuffer, | + | |
- | int Device, | + | |
- | uint64_t * pConnectorID) | + | |
- | { | + | |
- | struct drm_mode_get_connector ConnectorResource = {0}; | + | |
- | DRMConnectorResourceBuffer_t DRMConnectorResourceBuffer = {0}; | + | |
- | DRMdumbBuffer_t DRMdumbBuffer = {0}; | + | |
- | struct drm_mode_get_encoder Encoder = {0}; | + | |
- | struct drm_mode_crtc CRTC = {0}; | + | |
- | + | ||
- | if ((pFrameBuffer != (FrameBuffer_t *)0) | + | |
- | && (pConnectorID != (uint64_t * )0) ) | + | |
- | { | + | |
- | // get connector resource counts | + | |
- | ConnectorResource.connector_id = *pConnectorID; | + | |
- | ioctl(Device, DRM_IOCTL_MODE_GETCONNECTOR, &ConnectorResource); | + | |
- | + | ||
- | // get connector resources | + | |
- | ConnectorResource.modes_ptr = (uint64_t)DRMConnectorResourceBuffer.pMode; | + | |
- | ConnectorResource.props_ptr = (uint64_t)DRMConnectorResourceBuffer.pProps; | + | |
- | ConnectorResource.prop_values_ptr = (uint64_t)DRMConnectorResourceBuffer.PPropValue; | + | |
- | ConnectorResource.encoders_ptr = (uint64_t)DRMConnectorResourceBuffer.pEncoder; | + | |
- | ioctl(Device, DRM_IOCTL_MODE_GETCONNECTOR, &ConnectorResource); | + | |
- | + | ||
- | // Check if the connector is OK to use (connected to something) | + | |
- | if ((ConnectorResource.count_encoders > 0) | + | |
- | && (ConnectorResource.count_modes > 0) | + | |
- | && (ConnectorResource.encoder_id != 0) | + | |
- | && (ConnectorResource.connection != 0) ) | + | |
- | { | + | |
- | // Creating a dumb buffer | + | |
- | // If we create the buffer later, we can get the size of the screen first. | + | |
- | // This must be a valid mode, so it's probably best to do this after we find a valid crtc with modes. | + | |
- | DRMdumbBuffer.Create.width = DRMConnectorResourceBuffer.pMode[0].hdisplay; | + | |
- | DRMdumbBuffer.Create.height = DRMConnectorResourceBuffer.pMode[0].vdisplay; | + | |
- | DRMdumbBuffer.Create.bpp = 32; | + | |
- | DRMdumbBuffer.Create.flags = 0; /* must be zero */ | + | |
- | DRMdumbBuffer.Create.pitch = 0; | + | |
- | DRMdumbBuffer.Create.size = 0; | + | |
- | DRMdumbBuffer.Create.handle = 0; | + | |
- | if(ioctl(Device, DRM_IOCTL_MODE_CREATE_DUMB, &DRMdumbBuffer.Create) < 0) | + | |
- | { | + | |
- | printf("Fail to create dumb buffer\n"); | + | |
- | }; | + | |
- | + | ||
- | DRMdumbBuffer.Cmd.width=DRMdumbBuffer.Create.width; | + | |
- | DRMdumbBuffer.Cmd.height=DRMdumbBuffer.Create.height; | + | |
- | DRMdumbBuffer.Cmd.bpp=DRMdumbBuffer.Create.bpp; | + | |
- | DRMdumbBuffer.Cmd.pitch=DRMdumbBuffer.Create.pitch; | + | |
- | DRMdumbBuffer.Cmd.depth=24; | + | |
- | DRMdumbBuffer.Cmd.handle=DRMdumbBuffer.Create.handle; | + | |
- | ioctl(Device,DRM_IOCTL_MODE_ADDFB,&DRMdumbBuffer.Cmd); | + | |
- | + | ||
- | DRMdumbBuffer.Map.handle=DRMdumbBuffer.Create.handle; | + | |
- | ioctl(Device,DRM_IOCTL_MODE_MAP_DUMB,&DRMdumbBuffer.Map); | + | |
- | + | ||
- | pFrameBuffer->pBuffer = mmap(0, DRMdumbBuffer.Create.size, PROT_READ | PROT_WRITE, MAP_SHARED, Device, DRMdumbBuffer.Map.offset); | + | |
- | pFrameBuffer->ByteSizeOfBuffer = DRMdumbBuffer.Create.size; | + | |
- | pFrameBuffer->ScreenWidth = DRMdumbBuffer.Create.width; | + | |
- | pFrameBuffer->ScreenHeight = DRMdumbBuffer.Create.height; | + | |
- | + | ||
- | // drmIoctl(fd, DRM_IOCTL_MODE_DESTROY_DUMB, &dreq); | + | |
- | + | ||
- | // Kernel Mode Setting (KMS) | + | |
- | printf("Connection %d : mode: %d, prop: %d, enc: %d\n", | + | |
- | ConnectorResource.connection, | + | |
- | ConnectorResource.count_modes, | + | |
- | ConnectorResource.count_props, | + | |
- | ConnectorResource.count_encoders); | + | |
- | printf("modes: %dx%d Frame Buffer Address: 0x%X Frame Buffer Byte Size: 0x%X(%d) \n", | + | |
- | DRMConnectorResourceBuffer.pMode[0].hdisplay, | + | |
- | DRMConnectorResourceBuffer.pMode[0].vdisplay, | + | |
- | pFrameBuffer->pBuffer, | + | |
- | pFrameBuffer->ByteSizeOfBuffer, pFrameBuffer->ByteSizeOfBuffer); | + | |
- | + | ||
- | // get encoder | + | |
- | Encoder.encoder_id = ConnectorResource.encoder_id; | + | |
- | ioctl(Device, DRM_IOCTL_MODE_GETENCODER, &Encoder); | + | |
- | + | ||
- | CRTC.crtc_id = Encoder.crtc_id; | + | |
- | ioctl(Device, DRM_IOCTL_MODE_GETCRTC, &CRTC); | + | |
- | + | ||
- | CRTC.fb_id = DRMdumbBuffer.Cmd.fb_id; | + | |
- | CRTC.set_connectors_ptr = (uint64_t)pConnectorID; | + | |
- | CRTC.count_connectors = 1; | + | |
- | CRTC.mode = DRMConnectorResourceBuffer.pMode[0]; | + | |
- | CRTC.mode_valid = 1; | + | |
- | ioctl(Device, DRM_IOCTL_MODE_SETCRTC, &CRTC); | + | |
- | + | ||
- | return 0; | + | |
- | } | + | |
- | else | + | |
- | { | + | |
- | printf("Not connected\n"); | + | |
- | } | + | |
- | } | + | |
- | + | ||
- | return -1; | + | |
- | } | + | |
- | + | ||
- | + | ||
- | static int drm_free_frame_buffer(FrameBuffer_t *pFrameBuffer) | + | |
- | { | + | |
- | if (pFrameBuffer != (FrameBuffer_t *)0) | + | |
- | { | + | |
- | if (pFrameBuffer->ByteSizeOfBuffer != 0) | + | |
- | { | + | |
- | munmap( pFrameBuffer->pBuffer, pFrameBuffer->ByteSizeOfBuffer ); | + | |
- | printf("Free Frame Buffer\n"); | + | |
- | + | ||
- | return 0; | + | |
- | } | + | |
- | } | + | |
- | + | ||
- | return -1; | + | |
- | } | + | |
- | + | ||
- | + | ||
- | static int test_drm_style(void) | + | |
- | { | + | |
- | int Device; | + | |
- | uint32_t ConnectorIndex; | + | |
- | uint32_t Color; | + | |
- | struct drm_mode_card_res Resource = {0}; | + | |
- | DRMResourceBuffer_t DRMResourceBuffer = {0}; | + | |
- | + | ||
- | Device = drm_open(); | + | |
- | if ( Device != 0 ) | + | |
- | { | + | |
- | FrameBuffer_t pFrameBuffer[MAXIMUM_NUMBER_OF_CONNECTORS]; | + | |
- | + | ||
- | printf("DRM opened !\n"); | + | |
- | + | ||
- | // Kernel Mode Setting (KMS) | + | |
- | // Become the "master" of the DRI device | + | |
- | ioctl(Device, DRM_IOCTL_SET_MASTER, 0); | + | |
- | printf("DRM DRM_IOCTL_SET_MASTER\n"); | + | |
- | + | ||
- | // Get resource counts | + | |
- | ioctl(Device, DRM_IOCTL_MODE_GETRESOURCES, &Resource); | + | |
- | Resource.fb_id_ptr = (uint64_t)DRMResourceBuffer.pFB_ID; | + | |
- | Resource.crtc_id_ptr = (uint64_t)DRMResourceBuffer.pCRTC_ID; | + | |
- | Resource.connector_id_ptr = (uint64_t)DRMResourceBuffer.pCONNECTOR_ID; | + | |
- | Resource.encoder_id_ptr = (uint64_t)DRMResourceBuffer.pENCODER_ID; | + | |
- | + | ||
- | // Get resource IDs | + | |
- | ioctl(Device, DRM_IOCTL_MODE_GETRESOURCES, &Resource); | + | |
- | printf("Get Resource ID fb: %d, crtc: %d, conn: %d, enc: %d\n", | + | |
- | Resource.count_fbs, | + | |
- | Resource.count_crtcs, | + | |
- | Resource.count_connectors, | + | |
- | Resource.count_encoders); | + | |
- | + | ||
- | // Loop though all available connectors | + | |
- | for (ConnectorIndex = 0; ConnectorIndex < Resource.count_connectors; ConnectorIndex++) | + | |
- | { | + | |
- | drm_get_frame_buffer(&pFrameBuffer[ConnectorIndex], Device, &DRMResourceBuffer.pCONNECTOR_ID[ConnectorIndex]); | + | |
- | } | + | |
- | + | ||
- | // Stop being the "master" of the DRI device | + | |
- | ioctl(Device, DRM_IOCTL_DROP_MASTER, 0); | + | |
- | printf("DRM DRM_IOCTL_DROP_MASTER\n"); | + | |
- | + | ||
- | + | ||
- | int j; | + | |
- | for (j = 0; j < 100; j++) | + | |
- | { | + | |
- | for (ConnectorIndex = 0; ConnectorIndex < Resource.count_connectors; ConnectorIndex++) | + | |
- | { | + | |
- | drm_fill_screen(&pFrameBuffer[ConnectorIndex], 0x00000000); | + | |
- | usleep(100000); | + | |
- | Color = (rand() % 0x00ffffff) & 0x00ff00ff; | + | |
- | drm_fill_screen(&pFrameBuffer[ConnectorIndex], Color); | + | |
- | usleep(100000); | + | |
- | for (uint32_t k = 0; k <255; k++) | + | |
- | { | + | |
- | drm_fill_screen(&pFrameBuffer[ConnectorIndex], (Color | (k << 24))); | + | |
- | } | + | |
- | drm_draw_test_pattern(&pFrameBuffer[ConnectorIndex]); | + | |
- | usleep(100000); | + | |
- | } | + | |
- | } | + | |
- | + | ||
- | //DRM_IOCTL_MODE_DESTROY_DUMB | + | |
- | + | ||
- | for (ConnectorIndex = 0; ConnectorIndex < Resource.count_connectors; ConnectorIndex++) | + | |
- | { | + | |
- | drm_free_frame_buffer(&pFrameBuffer[ConnectorIndex]); | + | |
- | } | + | |
- | + | ||
- | close(Device); | + | |
- | printf("DRM closed !\n"); | + | |
- | } | + | |
- | + | ||
- | } | + | |
- | + | ||
- | + | ||
- | int main() | + | |
- | { | + | |
- | printf("Test Symple FB Style\n"); | + | |
- | test_simple_fb_style(); | + | |
- | + | ||
- | printf("Test DRM Style\n"); | + | |
- | test_drm_style(); | + | |
- | + | ||
- | return 0; | + | |
- | } | + | |
- | | + | |
- | {{wiki:atmel_sama5d42:test_app:test_app_002.zip}} | + | [[DRM or Simple FB App]] |
- | + | ||
- | 아래와 같이 컴파일 한다. | + | |
- | + | ||
- | 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 -I$/home/stephanos/VI/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/include/drm -o test test.c | + | |
- | + | ||
- | {{wiki:atmel_sama5d42:test_app:test_app_000.jpg}} | + | |
- | + | ||
- | NFS에 위에서 만들어진 test를 복사한다. | + | |
- | Target Board를 NFS로 부팅한다. | + | |
- | + | ||
- | 로그인 후 아래와 같이 실행한다. | + | |
- | + | ||
- | {{wiki:atmel_sama5d42:test_app:test_app_001.jpg}}\\ | + | |
- | {{wiki:atmel_sama5d42:test_app:test_app_003.jpg}} | + | |
+ | {{wiki:atmel_sama5d42:test_app:TestApp.tar}} | ||
+ | {{wiki:atmel_sama5d42:test_app:rootfs-2017-09-01.tar}} | ||
+ | [[MSR Test]] | ||