20150731更新:另一篇文章也写好了,下一篇。
****************************
先直接给出程序,过两天再写有关framebuffer的内容,主要怕忘了:
代码参考了网上的画图代码,因为画斜线不是那么好画的:
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <linux/fb.h> #include <sys/mman.h> #include <string.h> #include <stdlib.h> #define XRES 480 char *fb_addr; unsigned int fb_size; //void drawline(int x1, int y1, int x2, int y2, int c); /* light a pixel */ void Pixel(int x, int y, int color) { *((unsigned short *)(fb_addr+y*XRES*2+x*2)) = color; } /* draw a line */ void Line(int x1,int y1,int x2,int y2,int color) { int dx,dy,e; dx=x2-x1; dy=y2-y1; if(dx>=0) { if(dy >= 0) // dy>=0 { if(dx>=dy) // 1/8 octant { e=dy-dx/2; while(x1<=x2) { Pixel(x1,y1,color); if(e>0){y1+=1;e-=dx;} x1+=1; e+=dy; } } else // 2/8 octant { e=dx-dy/2; while(y1<=y2) { Pixel(x1,y1,color); if(e>0){x1+=1;e-=dy;} y1+=1; e+=dx; } } } else // dy<0 { dy=-dy; // dy=abs(dy) if(dx>=dy) // 8/8 octant { e=dy-dx/2; while(x1<=x2) { Pixel(x1,y1,color); if(e>0){y1-=1;e-=dx;} x1+=1; e+=dy; } } else // 7/8 octant { e=dx-dy/2; while(y1>=y2) { Pixel(x1,y1,color); if(e>0){x1+=1;e-=dy;} y1-=1; e+=dx; } } } } else //dx<0 { dx=-dx; //dx=abs(dx) if(dy >= 0) // dy>=0 { if(dx>=dy) // 4/8 octant { e=dy-dx/2; while(x1>=x2) { Pixel(x1,y1,color); if(e>0){y1+=1;e-=dx;} x1-=1; e+=dy; } } else // 3/8 octant { e=dx-dy/2; while(y1<=y2) { Pixel(x1,y1,color); if(e>0){x1-=1;e-=dy;} y1+=1; e+=dx; } } } else // dy<0 { dy=-dy; // dy=abs(dy) if(dx>=dy) // 5/8 octant { e=dy-dx/2; while(x1>=x2) { Pixel(x1,y1,color); if(e>0){y1-=1;e-=dx;} x1-=1; e+=dy; } } else // 6/8 octant { e=dx-dy/2; while(y1>=y2) { Pixel(x1,y1,color); if(e>0){x1-=1;e-=dy;} y1-=1; e+=dx; } } } } } void Rectangle(int x1,int y1,int x2,int y2,int color) { Line(x1,y1,x2,y1,color); Line(x2,y1,x2,y2,color); Line(x1,y2,x2,y2,color); Line(x1,y1,x1,y2,color); } void FilledRectangle(int x1,int y1,int x2,int y2,int color) { int i; for(i=y1;i<=y2;i++) Line(x1,i,x2,i,color); } void main() { int x1, y1,\ x2, y2,\ c; int fbd = 0; struct fb_fix_screeninfo fb_fix; struct fb_var_screeninfo fb_var; fbd = open("/dev/fb0", O_RDWR); ioctl(fbd, FBIOGET_FSCREENINFO, &fb_fix); ioctl(fbd, FBIOGET_VSCREENINFO, &fb_var); fb_size = fb_var.yres * fb_fix.line_length; printf("xres:%d, yres:%d\n"\ "bits_per_pixel:%d\n"\ "height:%d, width:%d\n",\ fb_var.xres, fb_var.yres,\ fb_var.bits_per_pixel,\ fb_var.height, fb_var.width); printf("smem_start:%ld\n"\ "smem_len:%d\n"\ "line_length:%d\n",\ fb_fix.smem_start,\ fb_fix.smem_len,\ fb_fix.line_length); fb_addr=(char *)mmap(0, fb_size, PROT_READ|PROT_WRITE, MAP_SHARED, fbd, 0); Line(0, 0, 480, 272, 0xF800); Rectangle(100, 100, 200, 200, 0x7E00); FilledRectangle(300, 5, 480, 10, 0x1F); //drawline(136, 100, 136, 300, 0xFFFF); close(fbd); }
#include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <fcntl.h> #include <linux/fb.h> #include <sys/mman.h> int main(int argc, char *argv[]) { int fbfd = 0; struct fb_var_screeninfo vinfo; unsigned long screensize = 0; unsigned long location = 0; char *fbp = 0; int x = 0, y = 0; int seg_len = 0; int tmp_seg_len = 0; int seg_num = 0; unsigned short rgb = 0; unsigned int r = 0, g = 0, b = 0; // Open the file for reading and writing fbfd = open("/dev/fb0", O_RDWR); if (!fbfd) { printf("Error: cannot open framebuffer device.\n"); exit(1); } printf("The framebuffer device was opened successfully.\n"); // Get variable screen information if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) { printf("Error reading variable information.\n"); exit(1); } printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel); if (vinfo.bits_per_pixel != 16) { printf("Error: not supported bits_per_pixel, it only supports 16 bit color\n"); exit(1); } // Figure out the size of the screen in bytes screensize = vinfo.xres * vinfo.yres * 2; // Map the device to memory fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0); if ((int)fbp == -1) { printf("Error: failed to map framebuffer device to memory.\n"); exit(4); } printf("The framebuffer device was mapped to memory successfully.\n"); seg_len = vinfo.yres/6; #if 1 seg_len = vinfo.yres/6; for (seg_num = 0; seg_num < 6; seg_num++) { if (seg_num == 5) tmp_seg_len = vinfo.yres - seg_len*5; else tmp_seg_len = seg_len; for (y = 0; y < tmp_seg_len; y++) { for (x = 0; x < vinfo.xres; x++) { location = seg_num*seg_len*vinfo.xres*2 + (y*vinfo.xres+ x)*2; switch (seg_num) { case 0: r = 0xff; g = (0xff/seg_len)*y; b = 0; break; case 1: r = (0xff/seg_len)*(seg_len-y); g = 0xff; b = 0; break; case 2: r = 0; g = 0xff; b = (0xff/seg_len)*y; break; case 3: r = 0; g = (0xff/seg_len)*(seg_len-y); b = 0xff; break; case 4: r = (0xff/seg_len)*y; g = 0; b = 0xff; break; case 5: r = 0xff; b = (0xff/seg_len)*(seg_len-y); g = 0; break; default: printf("%s--%d:unknown seg_num %d\n", __FILE__, __LINE__); break; } r = (r*0x1f)/0xff; g = (g*0x3f)/0xff; b = (b*0x1f)/0xff; rgb = (r << 11) | (g << 5) | b; *((unsigned short*)(fbp + location)) = rgb; } } } sleep(2); seg_len = vinfo.yres/6; for (seg_num = 0; seg_num < 6; seg_num++) { if (seg_num == 5) tmp_seg_len = vinfo.yres - seg_len*5; else tmp_seg_len = seg_len; for (y = 0; y < tmp_seg_len; y++) { for (x = 0; x < vinfo.xres; x++) { location = seg_num*seg_len*vinfo.xres*2 + (y*vinfo.xres+ x)*2; switch (seg_num) { case 0://grey r = 100; g = 100; b = 100; break; case 1: //black r = 0x00; g = 0x00; b = 0x00; break; case 2://white r = 0xff; g = 0xff; b = 0xff; break; case 3://red r = 0xff; g = 0; b = 0; break; case 4: //green r = 0; g = 0xff; b = 0; break; case 5: //blue r = 0; g = 0; b = 0xff; break; default: printf("%s--%d:unknown seg_num %d\n", __FILE__, __LINE__); break; } r = (r*0x1f)/0xff; g = (g*0x3f)/0xff; b = (b*0x1f)/0xff; rgb = (r << 11) | (g << 5) | b; *((unsigned short*)(fbp + location)) = rgb; } } } #endif #if 1 sleep(2); seg_len = vinfo.xres/6; for (seg_num = 0; seg_num < 6; seg_num++) { if (seg_num == 5) tmp_seg_len = vinfo.xres - seg_len*5; else tmp_seg_len = seg_len; for (x = 0; x < tmp_seg_len; x++) { for (y = 0; y < vinfo.yres; y++) { location = y*vinfo.xres*2 + (seg_num*seg_len + x)*2; switch (seg_num) { case 0: r = 0xff; g = (0xff/seg_len)*x; b = 0; break; case 1: r = (0xff/seg_len)*(seg_len-x); g = 0xff; b = 0; break; case 2: r = 0; g = 0xff; b = (0xff/seg_len)*x; break; case 3: r = 0; g = (0xff/seg_len)*(seg_len-x); b = 0xff; break; case 4: r = (0xff/seg_len)*x; g = 0; b = 0xff; break; case 5: r = 0xff; g = 0; b = (0xff/seg_len)*(seg_len-x); break; default: printf("%s--%d:unknown seg_num %d\n", __FILE__, __LINE__); break; } r = (r*0x1f)/0xff; g = (g*0x3f)/0xff; b = (b*0x1f)/0xff; rgb = (r << 11) | (g << 5) | b; *((unsigned short*)(fbp + location)) = rgb; } } } sleep(2); seg_len = vinfo.xres/6; /* white black gray red green blue */ for (seg_num = 0; seg_num < 6; seg_num++) { if (seg_num == 5) tmp_seg_len = vinfo.xres - seg_len*5; else tmp_seg_len = seg_len; for (x = 0; x < tmp_seg_len; x++) { for (y = 0; y < vinfo.yres; y++) { location = y*vinfo.xres*2 + (seg_num*seg_len + x)*2; switch (seg_num) { case 0://grey r = 100; g = 100; b = 100; break; case 1://black r = 0; g = 0; b = 0; break; case 2: //white r = 0xff; g = 0xff; b = 0xff; break; case 3://red r = 0xff; g = 0; b = 0; break; case 4: //green r = 0; g = 0xff; b = 0; break; case 5: //blue r = 0; g = 0; b = 0xff; break; default: printf("%s--%d:unknown seg_num %d\n", __FILE__, __LINE__); break; } r = (r*0x1f)/0xff; g = (g*0x3f)/0xff; b = (b*0x1f)/0xff; rgb = (r << 11) | (g << 5) | b; *((unsigned short*)(fbp + location)) = rgb; } } } #endif munmap(fbp, screensize); close(fbfd); return 0; }
#include <stdio.h> #include <unistd.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <linux/fb.h> #include <sys/mman.h> #include <string.h> #include <stdlib.h> #define XRES 480 char *fb_addr; unsigned int fb_size; const unsigned short logo[] = {/*内容省略,因为数据实在太长了*/ }; void main() { int x1, y1,\ x2, y2,\ c, i, j; int fbd = 0; struct fb_fix_screeninfo fb_fix; struct fb_var_screeninfo fb_var; fbd = open("/dev/fb0", O_RDWR); ioctl(fbd, FBIOGET_FSCREENINFO, &fb_fix); ioctl(fbd, FBIOGET_VSCREENINFO, &fb_var); fb_size = fb_var.yres * fb_fix.line_length; printf("xres:%d, yres:%d\n"\ "bits_per_pixel:%d\n"\ "height:%d, width:%d\n",\ fb_var.xres, fb_var.yres,\ fb_var.bits_per_pixel,\ fb_var.height, fb_var.width); printf("smem_start:%ld\n"\ "smem_len:%d\n"\ "line_length:%d\n",\ fb_fix.smem_start,\ fb_fix.smem_len,\ fb_fix.line_length); fb_addr=(char *)mmap(0, fb_size, PROT_READ|PROT_WRITE, MAP_SHARED, fbd, 0); for(i=0; i<130560; i++) { *((unsigned short *)(fb_addr+i*2)) = logo[i]; } // Line(0, 0, 480, 272, 0xF800); //Rectangle(100, 100, 200, 200, 0x7E00); //FilledRectangle(300, 5, 480, 10, 0x1F); //drawline(136, 100, 136, 300, 0xFFFF); close(fbd); }