您的位置:首页 > Web前端

S3C2440 LCD framebuffer 显示图像

2015-07-28 13:22 357 查看
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);
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: