s3c6410 framebuffer分析
本文介绍了s3c6410中的framebuffer,参考代码为Linux2.6.28。网上介绍framebuffer的文章很多,内核代码中也有关于framebuffer的文档,所以本文只介绍一些其它文章较少介绍的部分。
1. Overview
在嵌入式系统中,会有一块内核空间保存LCD上每一个象素需要被显示的值。系统运行时,CPU的显示控制器会自动从这块内存读取内容,然后发送到LCD显示屏。这块内存就叫作framebuffer。对程序来说,通过修改framebuffer中的内容,就可以控制LCD的显示。
Linux的GUI系统都运行在用户空间,不能直接访问内核空间。所以就需要一个framebuffer驱动,将内核空间的framebuffer映射到用户空间,方便GUI的访问。
对framebuffer的典型操作如下所示:
l fd = open(fb, …);
l ioctl(fb, …); // 设置framebuffer,比如象素的格式等。
l pBuffer = mmap(fb, …); // 映射framebuffer到用户空间
l 。。。 // 像读写内存一样操作pBuffer
framebuffer与LCD接口之间的通路有两种,分别是DMA和local bus,一般都会将通路设置为DMA以提高性能。设置成DMA时,注意不能用kmalloc分配framebuffer,应使用dma_alloc_writecombine函数分配能被DMA访问的内存空间,对应代码在s3cfb_map_video_memory函数中。
s3c6410支持多个层叠窗口(5个),显示的时候,这些窗口会被叠加显示。在这里,framebuffer的概念变成和窗口关联,而不是和LCD显示屏关联。每个窗口对应一个framebuffer,所以,s3c6410中可以有5个framebuffer(不考虑硬件双缓冲的情况)。关于窗口的概念在s3c6410的芯片手册中有介绍。
2. 双缓冲
双缓冲是指framebuffer的大小两倍于LCD的大小,可将其称为frame1和frame2。LCD显示frame1的内容时,GUI在后台绘制frame2;LCD显示frame2时,GUI在后台绘制frame1。
有多种实现双缓冲的方法,比如硬件切换、virtual screen等。
硬件实现
s3c6410的芯片手册中提到它最多支持5个窗口叠加。其中win0和win1支持硬件双缓冲。win0对应的寄存器为
l VIDW00ADD0B0 // win0的buffer0起始地址
l VIDW00ADD0B1 // win0的buffer1起始地址
l VIDW00ADD1B0 // win0的buffer0结束地址
l VIDW00ADD1B1 // win0的buffer1结束地址
要实现win0的buffer0/1之间的切换,只需要设置WINCON0寄存器的BUFSEL位即可。显示控制器会根据VIDW00ADD0B0和VIDW00ADD0B1的值,自动切换是使用buffer0还是buffer1作为显示内容。
win1对应的寄存器与win0类似。
代码中对应的切换命令为IOCTL S3CFB_CHANGE_REQ。
Virtual Screen
virtual screen的概念在s3c6410_rev12.pdf的第485页,figure 14-10。通过设定framebuffer的xoffset和yoffset,可以设置framebuffer被LCD显示的x、y坐标。因此,可以定义frame1的坐标为(0,0),frame2的坐标为(0,<LCD’s yres>)。通过改变x/y的坐标,可以在LCD上切换frame1、frame2。
在代码中,能改变坐标的IOCTL操作为 FBIOPAN_DISPLAY。
FBIOPAN_DISPLAY通过改变framebuffer的起始地址实现双缓冲,对应的函数为s3cfb_set_fb_addr。这种机制被Android采用。
3. alpha与colorkey
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控制。
目前s3c6410的framebuffer实现中,窗口平移和virtual screen平移都由fb_var_screeninfo中的xoffset和yoffset控制,所以使用时要小心。另外FBIOPAN_DISPLAY的实现代码中没有考虑x轴平移,只有y轴平移。
s3c6410 framebuffer分析相关推荐
- S3C6410 中断分析
Andrew Huang bluedrum@163.com 转载请注明作者及联络方式 一.中断的场景模拟 ----------------------------------------------- ...
- Linux FrameBuffer分析之编写基于FrameBuffer接口的应用程序
作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz 测试环境:Ubuntu 12.04终端模式 在网上找到一个很不错的介绍FrameBuffer相关知识的帖子,原帖网址 ...
- OpenGL ES EGL TLS(线程局部存储) G3D
1. 什么是EGL EGL是用来管理绘图表面的(Drawing surfaces),并且提供了如下的机制 (1) 与本地窗口系统进行通信 (2) 查找绘图表面可用的类型和配置信息 (3) 创建绘图表面 ...
- framebuffer的入门介绍-实现程序分析【转】
本文转载自:http://blog.csdn.net/liuzijiang1123/article/details/46972723 如想想对lcd屏进行操作(例如在lcd屏幕上画线,或者显示视频数据 ...
- framebuffer结构体分析
转载出处 http://blog.chinaunix.net/uid-22666248-id-284148.html fb_fix_screeninfo fb_var_screeninfo结构体测试 ...
- s3c6410 uboot代码分析《一》
来源:http://hi.baidu.com/__eabi/blog/item/be67533797bc73f014cecb49.html 以下用以记录uboot代码的分析过程,目标是s3c6410, ...
- 三星framebuffer驱动代码分析
一.驱动总体概述 本次的驱动代码是Samsung公司为s5pv210这款SoC编写的framebuffer驱动,对应于s5pv210中的内部外设Display Controller (FIMD)模块. ...
- framebuffer驱动详解4——framebuffer驱动分析2(probe函数讲解)
以下内容源于朱有鹏<物联网大讲堂>课程的学习,如有侵权,请告知删除. 主要在填充fbdev这个结构体. 二.framebuffer驱动分析2 1.probe函数分析 (1)struct s ...
- framebuffer驱动详解3——framebuffer驱动分析(driver和device的配套查找)
以下内容源于朱有鹏嵌入式课程的学习,如有侵权,请告知删除. 一.framebuffer驱动分析1 1.s3cfb.c (1)实现为平台总线,因为使用SoC内部的LCD控制器,属于内部外设,可以借用平台 ...
最新文章
- 如何在centos安装python-mysql
- 30万奖金!首个有阿里技术培训支持,让AI落定场景应用的赛事!
- linux使用小技巧——screen
- 谷歌地图API位置请求_Google Maps API
- Gradient Tree Boosting:梯度提升树详解
- error: 'for' loop initial declarations are only allowed in C99 or C11 mode
- C语言什么时候必须用到二级指针?(需要调用函数为一维空指针确定值的情况下,需要传入二维指针,也就是那个一维指针的指针)
- 川农在线计算机考试,四川农业大学《计算机应用基础(专科)》20年6月作业考核-答案...
- MySQL内核月报 2015.02-MySQL · 答疑释惑· InnoDB丢失自增值
- 三、Socket之UDP异步传输文件-多文件传输和文件MD5校验
- pycharm主题设置
- linux 默认ssh端口号,CentOS/Linux 修改默认SSH端口号
- GRE填空词汇专项训练
- Markdown 教程
- 推荐几个很实用的编程网站
- 基于历史使用数据的虚拟机动态整合研究( 文献阅读与问题理解)
- alpine linux 安装教程,Alpine linux硬盘安装
- 浅谈使用Word和Baklib制作帮助文档区别
- Cesium(六)淹没分析(polygon版本)
- Polygon zkEVM zkROM代码解析(2)