http://blog.csdn.net/zanget/archive/2010/11/18/6019528.aspx
最近调试2D一忙就是2周,现在终于忙完了,要将之前的调试信息全部都写下来,可是不大可能的。
当然,主要还是要驱动程序和 应用程序结合调试才能达到效果。
最开始一直使用光栅(ROP),希望能达到想要的效果,结果却一直是出现颜色混合。。
后来发现自己居然只使用到了FB0。。至于FB1....默认是关闭的;
而2416上的关键色,要求是两个窗口叠加才能出现效果;这个主要是集中在处理OSD的时候,没能开启。汗一个先。。。
关于加速显示的测试程序,在网上找到了几篇,比如
http://apps.hi.baidu.com/share/detail/17513859
虽然貌似不上架,很难使用,但是基本上思路还有的。
根据需要,改成我自己驱动的情况:
00001: #include <stdlib.h>
00002: #include <stdio.h>
00003: #include <string.h>
00004: #include <unistd.h>
00005: #include <fcntl.h>
00006: #include <sys/ioctl.h>
00007: #include <sys/types.h>
00008: #include <sys/mman.h>
00010: #include <errno.h>
00012: #include <stdint.h> //uint32_t uint8_t
00013: #include "s3c_g2d.h"
00014: #include <linux/fb.h>
00015:
00016: #include <sys/stat.h>
00017: #include <unistd.h>
00018:
00019: #include <sys/time.h>
00020:
00021: #include "def.h"
00022:
00023: /***********************************************************
00024: * Global image file descriptor
00025: ***********************************************************/
00026: int g2d_fd;
00027:
00028: #ifdef FB0_OPERATION
00029: int fb0_fd;
00030: #endif
00031:
00032: int fb1_fd;
00033:
00034: struct fb_fix_screeninfo finfo;
00035: struct fb_var_screeninfo info;
00036:
00037: void printHex(char * p, unsigned char * data, int len)
00038: {
00039: int i;
00040: if(p)
00041: {
00042: printf("|%s|:[addr=%p][len=%d]:\n",p,data,len);
00043: }
00044: len = len>128 ? 128: len;
00045: for(i=0;i<len;i++)
00046: {
00047: printf("%02x,",data[i]);
00048: if((i+1)%16 ==0)
00049: printf("\n");
00050: }
00051: printf("|%s|\n\n",p);
00052: }
00053:
00054: /*********************************************
00055: * file operaton
00056: **********************************************/
00057: int open_file_image(char* file_name,int * file_fd,int * file_len)
00058: {
00059: int rv;
00060: struct stat buf;
00061:
00062: rv = stat (file_name,&buf);
00063: if(rv != 0 || buf.st_size < 1)
00064: {
00065: perror("stat");
00066: return -1;
00067: }
00068:
00069: *file_len = buf.st_size;
00070:
00071: *file_fd = open(file_name,O_RDWR);
00072: if((*file_fd) < 0)
00073: {
00074: perror("fopen");
00075: return -1;
00076: }
00078: return 0;
00079: } ? end open_file_image ?
00080:
00081:
00082: void fb_info()
00083: {
00084: printf("using (fd=%d)\n"
00085: "id = %s\n"
00086: "xres = %d px\n"
00087: "yres = %d px\n"
00088: "xres_virtual = %d px\n"
00089: "yres_virtual = %d px\n"
00090: "bpp = %d\n"
00091: "r = %2u:%u\n"
00092: "g = %2u:%u\n"
00093: "b = %2u:%u\n"
00094: "smem_start = 0x%lx\n",
00095: fb1_fd ,
00096: finfo .id,
00097: info .xres,
00098: info .yres,
00099: info .xres_virtual,
00100: info .yres_virtual,
00101: info .bits_per_pixel,
00102: info .red.offset, info .red.length,
00103: info .green.offset, info .green.length,
00104: info .blue.offset, info .blue.length,
00105: finfo .smem_start
00107: );
00108:
00109: } ? end fb_info ?
00110:
00111: /*********************************************************
00112: * g2d & fb init & mmap
00113: **********************************************************/
00114: unsigned int g2d_fb_init()
00115: {
00116: s3c_color_key_info_t ckey;
00117: s3c_color_val_info_t cvalue;
00118: // s3c_win_info_t osd; //set for win0,win1, SET_OSD_INFO
00119:
00120: int rv;
00121:
00122: ////////////////////////////////////////////////////////////////////////////////////
00123:
00124: g2d_fd = open(S3C_G2D_DEV_NAME, O_RDWR);//open g2d
00125: if(g2d_fd <0)
00126: {
00127: perror("open S3C_G2D_DEV_NAME:");
00128: return -1;
00129: }
00130:
00131: #ifdef G2D_CUSTOMED
00132: /*************************************************************
00133: * G2D: color key and alpha
00134: *************************************************************/
00135: // G2D_NO_ALPHA = 0,
00136: // G2D_PLANE_ALPHA,//fixed..
00137: // G2D_PIXEL_ALPHA // with fallback to plane alpha
00138: rv = ioctl(g2d_fd , S3C_G2D_SET_BLENDING, G2D_PIXEL_ALPHA); //光栅 先于 S3C_G2D_SET_RASTER_OP
00139: if (rv != 0)
00140: {
00141: DBG("S3C_G2D_SET_BLENDING failed rv = %d, %s \n",rv, strerror(errno));
00142: return -2;
00143: }
00144:
00145:
00146: //alpha = (ALPHA+1) / 256, blended: ALPHA_REG = 0xf
00147: //win 1 透明度 //max 0xff
00148: rv = ioctl(g2d_fd , S3C_G2D_SET_ALPHA_VAL, 0xf);
00149: if (rv != 0)
00150: {
00151: DBG("set color key info error rv = %d, %s \n",rv, strerror(errno));
00152: return rv;
00153: }
00154:
00155: // #define G2D_ROP_SRC_ONLY (0xf0)
00156: // #define G2D_ROP_3RD_OPRND_ONLY (0xaa) //make the screen black
00157: // #define G2D_ROP_DST_ONLY (0xcc) //nothing.
00158: // #define G2D_ROP_SRC_OR_DST (0xfc) //覆盖 以前的画面
00159: // #define G2D_ROP_SRC_OR_3RD_OPRND (0xfa) // same as G2D_ROP_SRC_ONLY
00160: // #define G2D_ROP_SRC_AND_DST (0xc0) //覆盖 以前的画面,但是更透明
00161: // #define G2D_ROP_SRC_AND_3RD_OPRND (0xa0) //黑屏
00162: // #define G2D_ROP_SRC_XOR_3RD_OPRND (0x5a) // same as G2D_ROP_SRC_ONLY
00163: // #define G2D_ROP_DST_OR_3RD_OPRND (0xee) // nothing ?? same as G2D_ROP_SRC_ONLY ?
00163: ?
00164:
00165: //G2D_ROP_SRC_OR_DST
00166: //G2D_ROP_SRC_AND_DST
00167:
00168: rv = ioctl(g2d_fd , S3C_G2D_SET_RASTER_OP, G2D_ROP_SRC_ONLY);//rop
00169: if (rv != 0)
00170: {
00171: DBG("S3C_G2D_SET_RASTER_OP failed rv = %d, %s \n",rv, strerror(errno));
00172: return -2;
00173: }
00174: #ifdef G2D_SET_TRANSFORM_90
00175: rv = ioctl(g2d_fd , S3C_G2D_SET_TRANSFORM, G2D_ROT_90);
00176: if (rv != 0)
00177: {
00178: DBG("g2d TRANSFORM error rv = %d, %s \n",rv, strerror(errno));
00179: return -1;
00180: }
00181: #endif //G2D_SET_TRANSFORM_90
00182:
00183: #endif //G2D_CUSTOMED
00184:
00185: ////////////////////////////////////////////////////////////////////////////////////
00186:
00187:
00188: #ifdef FB0_OPERATION
00189: /*************************************************
00190: * fb0 info
00191: *************************************************/
00192: fb0_fd = open(S3C_FB0_DEV_NAME, O_RDWR);//open fb0
00193: if(fb0_fd <0)
00194: {
00195: DBG("open framebuffer device %s \n", strerror(errno));
00196: return -1;
00197: }
00198: #endif //FB0_OPERATION
00199:
00200: ////////////////////////////////////////////////////////////////////////////////////
00201:
00202: /*************************************************
00203: * fb1 info
00204: *************************************************/
00205: fb1_fd = open(S3C_FB1_DEV_NAME, O_RDWR);//open fb1
00206: if(fb1_fd <0)
00207: {
00208: DBG("open framebuffer device %s \n", strerror(errno));
00209: return -1;
00210: }
00211: rv = ioctl(fb1_fd , FBIOGET_FSCREENINFO, &finfo );
00212: if (rv != 0)
00213: {
00214: DBG("%s get fix info error rv = %d, %s \n",__FUNCTION__,rv, strerror(errno));
00215: return -1;
00216: }
00217: rv = ioctl(fb1_fd , FBIOGET_VSCREENINFO, &info );
00218: if (rv != 0)
00219: {
00220: DBG("get var info error rv = %d, %s \n",rv, strerror(errno));
00221: return -1;
00222: }
00223:
00224: #ifdef FB1_CUSTOMED
00225: /*************************************************
00226: * OSD for fb1
00227: *************************************************/
00228:
00229: rv = ioctl(fb1_fd , SET_OSD_START);
00230: if (rv != 0)
00231: {
00232: DBG("set OSD Start error rv = %d, %s \n",rv, strerror(errno));
00233: return rv;
00234: }
00235:
00236:
00237: /***********************************************************
00238: * configure the color key to black and bg display
00239: ************************************************************/
00240:
00241: /**
00242: * set the blending mode and alpha1_R/G/B
00243: */
00244: //0 Plane Blending & 1 Pixel Blending & chroma(color) key
00245: rv = ioctl(fb1_fd , SET_COLOR_ALPHA_MODE, 1);//Pixel Blending & chroma(color) key
00246: if (rv != 0)
00247: {
00248: DBG("set color alpha mode error rv = %d, %s \n",rv, strerror(errno));
00249: return rv;
00250: }
00251:
00252: //color for win 1
00253: cvalue.colval_red = 0;
00254: cvalue.colval_green = 0;
00255: cvalue.colval_blue = 0;
00256: rv = ioctl(fb1_fd , SET_COLOR_ALPHA0_VALUE, &cvalue);
00256: //Pixel Blending & chroma(color) key
00257: if (rv != 0)
00258: {
00259: DBG("set color alpha mode error rv = %d, %s \n",rv, strerror(errno));
00260: return rv;
00261: }
00262:
00263: //color for win 0
00264: cvalue.colval_red = 0xf;
00265: cvalue.colval_green = 0xf;
00266: cvalue.colval_blue = 0xf;
00267: rv = ioctl(fb1_fd , SET_COLOR_ALPHA1_VALUE, &cvalue);
00267: //Pixel Blending & chroma(color) key
00268: if (rv != 0)
00269: {
00270: DBG("set color alpha mode error rv = %d, %s \n",rv, strerror(errno));
00271: return rv;
00272: }
00273:
00274: // direction = 0 means win1 is breen compared with color value
00275: ckey.direction = COLOR_KEY_DIR_FG_DISPLAY;
00275: //COLOR_KEY_DIR_BG_DISPLAY COLOR_KEY_DIR_FG_DISPLAY
00276: //each bit is set to 0 means that each bit in colval is been compared
00277: ckey.compkey_red = 0;
00278: ckey.compkey_green = 0;
00279: ckey.compkey_blue = 0;
00280: //set color key info to be compared in color value
00281: rv = ioctl(fb1_fd , SET_COLOR_KEY_INFO, &ckey);
00282: if (rv != 0)
00283: {
00284: DBG("set color key info error rv = %d, %s \n",rv, strerror(errno));
00285: return rv;
00286: }
00287:
00288: cvalue.colval_red = 0;
00289: cvalue.colval_green = 0;
00290: cvalue.colval_blue = 0;
00291: //set color value
00292: rv = ioctl(fb1_fd , SET_COLOR_KEY_COLVAL, &cvalue);
00293: if (rv != 0)
00294: {
00295: DBG("set color key value error rv = %d, %s \n",rv, strerror(errno));
00296: return rv;
00297: }
00298:
00299:
00300: //没用?????????????????????????????????????????????//
00301: //start color key KEYEN_F[25] Color Key Chroma Key( 浓度 色度 ) Enable control
00302: rv = ioctl(fb1_fd , SET_COLOR_KEY_START);
00303: if (rv != 0)
00304: {
00305: DBG("set color key value error rv = %d, %s \n",rv, strerror(errno));
00306: return rv;
00307: }
00308:
00309:
00310: //start alpha of color key KEYBLEN D [26]=1:alpha value selected by
00311: // non-key area: alpha0_r/g/b
00312: // key area : alpha1_r/g/b
00313: rv = ioctl(fb1_fd , SET_COLOR_KEY_ALPHA_START);
00314: if (rv != 0)
00315: {
00316: DBG("set color key value error rv = %d, %s \n",rv, strerror(errno));
00317: return rv;
00318: }
00319:
00320: #endif //FB1_CUSTOMED
00321:
00322: return 0;
00323: } ? end g2d_fb_init ?
00324:
00325:
00326: /*********************************************
00327: * g2d implement
00328: **********************************************/
00329: int s3c_g2d_copy_buffer(struct s3c_g2d_req * req, unsigned long buffer_base, unsigned
00329: long fb_base/*,
00330: int x, int y, int w, int h*/)
00331: {
00332: int rv;
00333: memset(req, 0, sizeof(struct s3c_g2d_req));
00334:
00335:
00336: req->src.w = SOURCE_WIDTH;
00337: req->src.h = SOURCE_HEIGHT;
00338: req->src.offs = 0;
00339: req->src.base = buffer_base;
00340: req->src.fmt = SOURCE_FMT;
00341:
00342: req->src.l = 0;
00343: req->src.t = 0;
00344: req->src.r = req->src.w;
00345: req->src.b = req->src.h;
00346:
00347: req->dst.w = DEST_WIDTH;
00348: req->dst.h = DEST_HEIGHT;
00349: req->dst.offs = 0;
00350: req->dst.base = fb_base;
00351: req->dst.fmt = DST_FMT;
00352:
00353: req->dst.l = DST_LEFT_X;
00354: req->dst.t = DST_TOP_Y;
00355:
00356: req->dst.r = DST_RIGHT_X;
00357: req->dst.b = DST_DOWN_Y;
00358:
00359: rv = ioctl(g2d_fd , S3C_G2D_BITBLT, req);
00360: if (rv != 0)
00361: {
00362: DBG("S3C_G2D_BITBLT failed = %d", -errno);
00363: return -2;
00364: }
00365: // DBG("src base:0xx%u dst:base:0x%x\n",req->src.base,req->dst.base);
00366: return 0;
00367: } ? end s3c_g2d_copy_buffer ?
00368:
00369: int main(int argc, char *argv[])
00370: {
00371: u32 fb_phy;
00372: struct s3c_g2d_req params;
00373: int file_len,frame=0,rv,image_fd,times = 10;
00374:
00375: struct timeval start,end;
00376: double timeuse;
00377: void * pmem_base /*, *fb_mem_map */;
00378: char * file_name = YUV_FILE;
00379:
00380: if(argc >= 2)
00381: {
00382: file_name = argv[1];
00383: if(argc >= 3)
00384: times = atoi(argv[2]);
00385: DBG("Request Play times %d \n",times);
00386: }
00387:
00388: /* get framebuffer phyaddr */
00389: if(g2d_fb_init() != 0)
00390: return -3;
00391: fb_phy = finfo .smem_start;
00392:
00393: /* get pmem source addr */
00394: pmem_base = mmap(NULL, G2D_SFR_SIZE, PROT_READ|PROT_WRITE, MAP_SHARED, g2d_fd , 0);
00395: if(pmem_base == MAP_FAILED)
00396: {
00397: perror("mmap");
00398: return -1;
00399: }
00400: memset(pmem_base,0, G2D_SFR_SIZE);
00401:
00402: DBG("pmem_base = %p\n",pmem_base);
00403:
00404:
00405: /* get image file */
00406: rv = open_file_image(file_name,&image_fd,&file_len);
00407: if(rv < 0)
00408: {
00409: return rv;
00410: }
00411:
00412: DBG("File[%s], size[%d], Frame[%d]\n",file_name,file_len,file_len/G2D_SFR_SIZE);
00413:
00414: sleep(1);
00415:
00416:
00417: gettimeofday(&start, NULL);
00418: while(1)
00419: {
00420: /* Start: read the content of the image file to the mem */
00421: rv = read(image_fd,pmem_base,G2D_SFR_SIZE);
00422: if(rv > 0)
00423: {
00424:
00425: rv = s3c_g2d_copy_buffer(¶ms, (unsigned long)pmem_base, fb_phy);
00426: if(rv)
00427: break;
00428: }
00429: else
00430: {
00431: if(--times <= 0)
00432: break;
00433: lseek(image_fd,0,SEEK_SET);//seek to begin
00434: }
00435: frame++;
00436: // DBG("times=%d, frame=%d\n",times,frame);
00437: usleep(50000);
00438: } ? end while 1 ?
00439: gettimeofday(&end, NULL);
00440: timeuse = 1000000 * ( end.tv_sec - start.tv_sec ) + end.tv_usec - start.tv_usec;
00441: timeuse/=1000;
00442:
00443: DBG("Total Frame[%d], Total Time[%2.1f] ms,Time Pre Frame[%2.1f] ms\n",frame,timeuse,timeuse/frame);
00444:
00445:
00446: //fb_info();
00447:
00448: // printHex(file_name, pmem_base,128);
00449: close(image_fd);
00450: munmap(pmem_base,G2D_SFR_SIZE);
00451:
00452:
00453: close(g2d_fd );
00454: #ifdef FB0_OPERATION
00455: close(fb0_fd );
00456: #endif
00457: close(fb1_fd );
00458: return 0;
00459:} ? end main ?
00460:
最终测试的效果,当然要 上传一张啦。。
横着的条纹是win0, 竖着的条文是win1,COLVAL是黑色
win0是显示整屏幕,win1只有1/2屏幕,也可想成是win0旋转+缩放后得到的。
参考网站:
http://apps.hi.baidu.com/share/detail/17513887
http://blogold.chinaunix.net/u3/111323/showart_2200014.html
http://apps.hi.baidu.com/share/detail/17513859
下面是常见问题的总结:
鱼 19:43:35
请问你的测试代码里面 SOURCE_FMT 与 DST_FMT 颜色模式 是什么?
鱼 19:43:45
6410手册里面讲的太不清楚,有几个寄存器的设置他就没讲清楚甚至没讲!
1、DST_BASE_ADDR和SRC_BASE_ADDR要设置物理地址。不能是内核的虚拟地址或者应用程序中的地址。对于FB,要使用 dma_alloc_writecombine 第三个参数返回的物理地址 fbi->fix.smem_start。
鱼 19:56:26
怎么要设置成物理地址啊?
鱼 19:56:56
目的地址是framebuff 地址 而源地址怎么设置啊?
典当七秒的魚 08:55:36
是 颜色模式。
DST_FMT 是你驱动里使用的格式。像rgb565等。
SOURCE_FMT 是你要显示的(在内存里)image的格式。
至于硬件支持哪几种 可转换的,你要看看数据手册了。
典当七秒的魚 08:57:37
硬件能处理的只有物理地址吧。我想。
因为你写进去的到下面寄存器的
DST_BASE_ADDR和SRC_BASE_ADDR
只能是物理 地址吧。。。这个地址是硬件能去访问的。
硬件的搬运负责吧原地址SRC_BASE_ADDR的数据 经过6步转换后,显示在DST_BASE_ADDR里面。
典当七秒的魚 08:58:45
我想着就是为何要用物理地址的原因。
你能找到 这个说明真的相当不错了
我当时可是在这里郁闷了好几天。。
因为 一直将虚拟地址写到 源地址。。
操作完成后一直黑屏 。。
鱼 09:09:59
就是这个帖子啊
http://blog.chinaunix.net/u3/111323/showart_2200014.html
鱼 09:10:24
那src_base 物理地址是怎么确定的呢?
典当七秒的魚 09:15:54
我是这样做的
在初始化的时候就分配好可用的,共享的内存。和显存差不多大, 主要用于 应用层 放src Image
驱动记录这个地址,并将其转换得到物理地址,用于src_base(其实,应用层会再次将此地址对应的虚拟地址写入,而驱动层将会舍弃此地址,因为是虚拟地址嘛),将虚拟地址传给应用层,应用层使用这个地址将src image写到这里地址(应用层能操作的就只能是虚拟地址,并且和内核层的不同。),因此对应的物理地址 的内容也相应的被应用填充了。
鱼 09:17:21
完全明白了 非常感谢
鱼 09:18:17
注:因为不知道如何将用户空间的虚拟地址转换为物理地址,只好在内核里面alloc了一块buffer s3c_g2d_userFB,每次都要用copy_from_user把图片先拷贝到s3c_g2d_userFB,再由2D搬到屏幕。
大概测试过一下,一张800*600的图片 copy_from_user 用了大概 4ms。2D搬到屏幕上用了大概5~6ms。还是想把copy_from_user给剩了!
鱼 09:18:39
这是刚才那个帖子里面提到的 方法估计和你一样的
典当七秒的魚 09:18:46
一样
典当七秒的魚 09:19:12
每次都要用copy_from_user把图片先拷贝到s3c_g2d_userFB 这个不用 。
鱼~BOBO 09:27:22
昨晚我也尝试把mmap 返回的虚拟地址在内核空间转换成物理地址 也是不行 我想说的是在内核空间分配的buff(虚拟地址) 与 mmap 映射返回到用户空间的虚拟地址有何不同 如果相同的话 昨晚的尝试就应该是成功的 谢谢
典当七秒的魚 09:31:40
使用setpagereserved就行了吧。。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/zanget/archive/2010/11/18/6019528.aspx