Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1319783
  • 博文数量: 168
  • 博客积分: 2124
  • 博客等级: 大尉
  • 技术积分: 2590
  • 用 户 组: 普通用户
  • 注册时间: 2011-09-16 23:51
文章分类

全部博文(168)

文章存档

2014年(6)

2013年(74)

2012年(71)

2011年(17)

分类: LINUX

2012-10-22 15:06:58

本文介绍了s3c6410中的framebuffer,参考代码为Linux2.6.28。网上介绍framebuffer的文章很多,内核代码中也有关于framebuffer的文档,所以本文只介绍一些其它文章较少介绍的部分。

1. Overview

在嵌入式系统中,会有一块内核空间保存LCD上每一个象素需要被显示的值。系统运行时,CPU的显示控制器会自动从这块内存读取内容,然后发送到LCD显示屏。这块内存就叫作framebuffer。对程序来说,通过修改framebuffer中的内容,就可以控制LCD的显示。

LinuxGUI系统都运行在用户空间,不能直接访问内核空间。所以就需要一个framebuffer驱动,将内核空间的framebuffer映射到用户空间,方便GUI的访问。

framebuffer的典型操作如下所示:

l fd = open(fb, …);

l ioctl(fb, …); // 设置framebuffer,比如象素的格式等。

l pBuffer = mmap(fb, …); // 映射framebuffer到用户空间

l 。。。 // 像读写内存一样操作pBuffer

framebufferLCD接口之间的通路有两种,分别是DMAlocal bus,一般都会将通路设置为DMA以提高性能。设置成DMA时,注意不能用kmalloc分配framebuffer,应使用dma_alloc_writecombine函数分配能被DMA访问的内存空间,对应代码在s3cfb_map_video_memory函数中。

s3c6410支持多个层叠窗口(5个),显示的时候,这些窗口会被叠加显示。在这里,framebuffer的概念变成和窗口关联,而不是和LCD显示屏关联。每个窗口对应一个framebuffer,所以,s3c6410中可以有5framebuffer(不考虑硬件双缓冲的情况)。关于窗口的概念在s3c6410的芯片手册中有介绍。

2. 双缓冲

双缓冲是指framebuffer的大小两倍于LCD的大小,可将其称为frame1frame2LCD显示frame1的内容时,GUI在后台绘制frame2LCD显示frame2时,GUI在后台绘制frame1

有多种实现双缓冲的方法,比如硬件切换、virtual screen等。

硬件实现

s3c6410的芯片手册中提到它最多支持5个窗口叠加。其中win0win1支持硬件双缓冲。win0对应的寄存器为

l VIDW00ADD0B0 // win0buffer0起始地址

l VIDW00ADD0B1 // win0buffer1起始地址

l VIDW00ADD1B0 // win0buffer0结束地址

l VIDW00ADD1B1 // win0buffer1结束地址

要实现win0buffer0/1之间的切换,只需要设置WINCON0寄存器的BUFSEL位即可。显示控制器会根据VIDW00ADD0B0VIDW00ADD0B1的值,自动切换是使用buffer0还是buffer1作为显示内容。

win1对应的寄存器与win0类似。

代码中对应的切换命令为IOCTL S3CFB_CHANGE_REQ

Virtual Screen

virtual screen的概念在s3c6410_rev12.pdf的第485页,figure 14-10。通过设定framebufferxoffsetyoffset,可以设置framebufferLCD显示的xy坐标。因此,可以定义frame1的坐标为(0,0)frame2的坐标为(0,)。通过改变x/y的坐标,可以在LCD上切换frame1frame2

在代码中,能改变坐标的IOCTL操作为 FBIOPAN_DISPLAY

FBIOPAN_DISPLAY通过改变framebuffer的起始地址实现双缓冲,对应的函数为s3cfb_set_fb_addr。这种机制被Android采用。

3. alphacolorkey

s3c6410支持硬件alpha操作和colorkey操作。

alpha操作用于实现图形渐变效果,以及半透明效果等等。

colorkey操作可以在融合两个窗口时过滤掉其中一个窗口的某一种特定颜色。因为GUI在显示图象时都是通过画矩形实现,所以这个功能在显示非矩形图像(比如圆形)时很有用。假设要显示圆形图案,可以把圆形放进一个矩形,然后矩形的剩余部分填充一个背景色,并把这个背景色指定为colorkey。这样,显示的时候自动将colorkey指定的颜色过滤,屏幕上就能显示出那个圆形了。

不管是alpha操作还是colorkey操作,都有对应的软件模拟实现。网上类似的代码有很多,不再赘述。

4. 窗口平移与virtual screen平移

窗口平移与virtual screen平移是两个容易被混淆的概念,下面简单介绍一下:

窗口平移

s3c6410硬件上支持5个窗口,每一个窗口都可以显示在LCD的不同位置。所以窗口平移就是指硬件支持的窗口在LCD上的移动。

窗口平移由以下寄存器控制:

S3C_VIDOSD[0-4]A

S3C_VIDOSD[0-4]B

framebuffer的驱动中,可以通过以下IOCTL控制窗口平移:

S3CFB_OSD_MOVE_LEFT

S3CFB_OSD_MOVE_RIGHT

S3CFB_OSD_MOVE_UP

S3CFB_OSD_MOVE_DOWN

另外SET_OSD_INFO也可以用于控制平移。内核中与窗口平移对应的函数为s3cfb_set_win_position

virtual screen平移

virtual screen的概念在上面介绍双缓冲的地方提到过,具体可查阅芯片手册。这里的平移指的是显示内容的平移,可以想象成通过拖动GUI中的滚动条造成的效果。

virtual screen的平移由寄存器VIDWxxADD[0-1]实现内核中对应函数为s3cfb_set_fb_addr用户程序可以通过调用FBIOPAN_DISPLAY控制。

目前s3c6410framebuffer实现中,窗口平移和virtual screen平移都由fb_var_screeninfo中的xoffsetyoffset控制,所以使用时要小心。另外FBIOPAN_DISPLAY的实现代码中没有考虑x轴平移,只有y轴平移。

阅读(1923) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~