linux屏幕显示

原创 2018年04月15日 15:12:41
.像素(pixel)图像显示的基本单位
2.分辨率(image resolution)分辨率是指单位面积显示像素的数量
3.色彩深度(BPP,bits per pixel)一个像素所能表达的不同颜色数取决于比


特每像素。
常见的取值有:
8bpp:256色;16 bpp:2^16=65535色;24 bpp:2^24=1600万色
一个16位的深度通常分为5位红色,5位蓝色,6位绿色(眼睛对于绿色更为敏


感)24位的一般都是每个分量8位,而32位的颜色深度也是常见的,这意味着


除了24位的像素,还有8位的额外数位来描述透明度。
一个像素点所对应的字节数目越多,其色彩深度越深,表现力就越细腻。


        LCD显示器一般对应的设备节点文件是/dev/fb0在编写程序之前,我们还需要理解一下framebuffer,    



framebuffer机制模仿显卡的功能,将显卡硬件结构抽象为一系列的数据结构,可以通过framebuffer的读写直接对显存进行操作。用户可以将framebuffer看成是显存的一个映像,将其映射到进程空间后,就可以直接进行读写操作,写操作会直接反映在屏幕上。


了解framebuffer一些结构体

//struct fb_fix_screeninfo用于描述显卡的属性
    struct fb_fix_screeninfo {
    char id[16]; /* identification string eg "TT Builtin" */
    unsigned long smem_start; /* 显存起始地址*/
    /* 实际物理地址 */
    __u32 smem_len; /* 显存大小 */
    __u32 type; /* see FB_TYPE_* */
    __u32 type_aux; /* Interleave for interleaved Planes */
    __u32 visual; /* see FB_VISUAL_* */
    __u16 xpanstep; /* zero if no hardware panning */
    __u16 ypanstep; /* zero if no hardware panning */
    __u16 ywrapstep; /* zero if no hardware ywrap */
    __u32 line_length; /* length of a line in bytes */
    unsigned long mmio_start; /* Start of Memory Mapped I/O */
    /* (physical address) */
    __u32 mmio_len; /* Length of Memory Mapped I/O */
    __u32 accel; /* Type of acceleration available */
    __u16 reserved[3]; /* Reserved for future compatibility */
};
以上结构体是由驱动程序根据硬件配置决定的,不能修改,我们要根据该结构
体提供的具体信息来构建和操作frame-buffer映射内存。
//显卡的特性
struct fb_var_screeninfo
{
    __u32 xres; /* visible resolution */
    __u32 yres;
    __u32 xres_virtual; /* virtual resolution */
    __u32 yres_virtual;
    __u32 xoffset; /* offset from virtual to visible resolution */
    __u32 yoffset;
    __u32 bits_per_pixel; /* guess what */
    __u32 grayscale; /* != 0 Gray levels instead of colors */
    struct fb_bitfield red; /* bitfield in fb mem if true color, */
    struct fb_bitfield green; /* else only length is significant */
    struct fb_bitfield blue;
    struct fb_bitfield transp; /* transparency */
    __u32 nonstd; /* != 0 Non standard pixel format */
    __u32 activate; /* see FB_ACTIVATE_* */
    __u32 height; /* height of picture in mm */
    __u32 width; /* width of picture in mm */
    __u32 accel_flags; /* acceleration flags (hints) */
    /* Timing: All values in pixclocks, except pixclock (of course) 


*/
    __u32 pixclock; /* pixel clock in ps (pico seconds) */
    __u32 left_margin; /* time from sync to picture */
    __u32 right_margin; /* time from picture to sync */
    __u32 upper_margin; /* time from sync to picture */
    __u32 lower_margin;
    __u32 hsync_len; /* length of horizontal sync */
    __u32 vsync_len; /* length of vertical sync */
    __u32 sync; /* see FB_SYNC_* */
    __u32 vmode; /* see FB_VMODE_* */
    __u32 reserved[6]; /* Reserved for future compatibility */
};
xres_virtual和yres_virtual决定了虚拟区的大小,而xres和yres是实际屏幕


的大小,xoffset和yoffset是偏移量,是xres和yres相对于xres_virtual和


yres_virtual区域上的偏移(一般来说xres_virtual和yres_virtual比xres和


yres要大)。

下面是屏幕显示单色的c例程。


#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <linux/fb.h>


#include <fcntl.h>
#include <sys/types.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
enum color{red,green,blue};


unsigned long * create_color(struct fb_var_screeninfo *pinfo,enum color c)
{
unsigned long *three_color = calloc(1,pinfo->bits_per_pixel/8);
unsigned long *mask = calloc(1,pinfo->bits_per_pixel/8);


int i;
*mask |= 1;
switch(c)
{
//创建红色,根据pinfo所提供的信息,往表示红色的位置写1,
//其他的为0,同理创建出另外两种颜色
case red:
for(i=0;i<pinfo->red.length-1;i++)
{
*mask <<= 1;
*mask |= 0x1;
}
*three_color |= *mask<<pinfo->red.offset;
break;
case green:
for(i=0;i<pinfo->green.length-1;i++)
{
*mask <<= 1;
*mask |= 0x1;
}
*three_color |= *mask<<pinfo->green.offset;
break;
case blue:
for(i=0;i<pinfo->blue.length-1;i++)
{
*mask <<= 1;
*mask |= 0x1;
}
*three_color |= *mask<<pinfo->blue.offset;
break;
}
return three_color;
}


int main(void)
{
int lcd = open("/dev/fb0",O_RDWR);
if(lcd < 0)
{
perror("lcd open failed:\n");
exit(1);
}
//定义两个结构体分别用来存储显存的信息
struct fb_fix_screeninfo finfo;
struct fb_var_screeninfo vinfo;


//用ioctl函数根据命令字FBIOGET_FSCREENINFO和
//FBIOGET_VSCREENINFO来获取显存的信息
ioctl(lcd,FBIOGET_FSCREENINFO,&finfo);
ioctl(lcd,FBIOGET_VSCREENINFO,&vinfo);

//设置偏移量为0
vinfo.xoffset = 0;
vinfo.xoffset = 0;
ioctl(lcd,FBIOPAN_DISPLAY,&vinfo);


//因为RGB三原色在每个像素点的位置是固定的,所以要显示
//出这三种单色,就必须往每个像素点对应的字节写1,其他
//为0,这样就可以显示出这三种颜色了,我们要一个函数来
//创造出这三种颜色


//用n来保存每个像素点用多少位表示,申请内存的时候会用到
unsigned long n = vinfo.bits_per_pixel;


//创建出三种颜色
unsigned long *three_color[3] = {0};
three_color[0] = create_color(&vinfo,red);
three_color[1] = create_color(&vinfo,green);
three_color[2] = create_color(&vinfo,blue);


//映射一片内存,第一个参数为null时表示系统自动分配
//映射的内存的大小跟屏幕大小一样大
char *show=mmap(NULL,vinfo.xres*vinfo.yres*n/8,
PROT_READ | PROT_WRITE,MAP_SHARED,lcd,0) ;
//每秒钟显示一种颜色
while(1)
{
int i,k;
for(k=0;k<3;k++)
{


for(i=0;i<vinfo.xres*vinfo.yres;i++)
memcpy(show+i*n/8,three_color[k],n/8);
sleep(1);
}
}
return 0;

}

如果没有开发板的话,也可以在ubuntu下试验,按ctl+alt+f5进入屏幕终端,然后运行编译出来的文件。按ctl+alt+f7退出黑色终端。

这个程序只是简单的显示单色,要显示一张图片例如jpg,还要用到一些解码库。

嵌入式Linux简单字符设备驱动程序---helloworld

/* **$ gcc -DMODULE -D__KERNEL__ -I /usr/src/linux-2.4.20/include -c hello.c **$ insmod hello.o ...
  • dl0914791011
  • dl0914791011
  • 2012-11-07 19:51:40
  • 1553

Linux 启动信息同时输出到屏幕和串口终端

想要让 Linux 启动时的信息同时显示在屏幕上并打印在串口中,可修改 u-boot 中的启动参数 :setenv bootargs 'console=tty0 console=ttymxc0,115...
  • u010333613
  • u010333613
  • 2018-03-29 10:30:23
  • 23

嵌入式Linux驱动开发之helloword心得

自从选择了物联网这个专业,智能XX的字样牵动着每一个学习这个专业的孩子。 大家兴致勃勃的来到了学校,结果一切想象和自己的设想并不一样。想象中的各种智能般梦幻的场景变成了真实的高数/电路/模电等等...
  • chinazhangzhong123
  • chinazhangzhong123
  • 2016-06-01 00:24:21
  • 528

嵌入式Linux基于framebuffer的jpeg格式本地LCD屏显示

在基于Linux的视频监控采集系统中,摄像头采集到的一帧视频图像数据一般都是经过硬件自动压缩成jpeg格式的,然后再保存到摄像头设备的缓冲区.如果要把采集到的jpeg格式显示在本地LCD屏上,由于我们...
  • mao0514
  • mao0514
  • 2015-06-24 10:41:20
  • 2068

用shell脚本来实现日历的屏幕控制

首先什么是脚本? 脚本语句由Linux系统解释执行.脚本由脚本语言与可执行的二进制文件或命令组成,因此,脚本是不需要再编译链接的.为了与高级语言源程序加以区别,Linux中将其称为” 脚本 “ 应...
  • Chen_dSir
  • Chen_dSir
  • 2016-12-05 12:59:42
  • 676

基于SED1520的液晶屏幕显示设计

  • 2011年09月11日 13:17
  • 8.67MB
  • 下载

ubuntu下android手机动态显示在桌面上

用USB连接手机(手机设置成usb调试模式 wangfei@wangfei-ThinkPad-Edge:~$ lsusb  Bus 001 Device 002: ID 8087:0020 I...
  • wangfei199101
  • wangfei199101
  • 2014-04-13 22:53:03
  • 804

修改php.ini以达到 屏蔽错误信息

那是因为php.ini中关闭了错误显示,将错误写成了文件,这是人为设置的结果display_errors =on就好了。当PHP启动的时候,它将在Web服务器标准头信息中添加PHP版本号信息。如果希望...
  • xiaojun1288
  • xiaojun1288
  • 2010-08-05 08:20:00
  • 1326

读取INI文件在屏幕显示

  • 2014年05月26日 23:41
  • 26KB
  • 下载

更改屏幕显示区

找设置任务栏高度时发现了这些代码,保留了下来 procedure FullScreenArea; var   rcWork: TRect; begin   rcWork.Top:=0;   rcWor...
  • cnhgj
  • cnhgj
  • 2004-07-22 01:25:00
  • 872
收藏助手
不良信息举报
您举报文章:linux屏幕显示
举报原因:
原因补充:

(最多只允许输入30个字)