找回密码
 立即注册
收起左侧

如何得到QT最终输出到FrameBuffer的RAM基地址?

7
回复
10819
查看
[复制链接]
累计签到:2 天
连续签到:1 天
来源: 2015-6-22 11:04:17 显示全部楼层 |阅读模式
各位大侠好!
最近在研究一款内嵌ARM-A9的FPGA,人机交互界面使用QT-4.8实现。
QT运行在ARM下的linux中,在这个项目中QT实现菜单显示的功能,数据显示和处理由FPGA来完成。
因此,显示在LCD上的图像是由好几个图层叠加而成。
因为LCD显示的分辨率很高,为了保证LCD显示的图像稳定,各个图层之间叠加是通过FPGA的硬件来实现
FPGA的图层叠加模块为了能够显示QT的图层,需要知道QT最终输出到FrameBuffer的起始地址。
请问,在QT-4.8里,如何获取该FrameBuffer的基地址呢?
谢谢!
本人是初学者,对QT不太了解,希望大侠们有时间能帮忙解答一下

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

累计签到:2 天
连续签到:1 天
2015-6-23 13:02:47 显示全部楼层
今天查了些资料,终于知道如何处理了:
QT最终输出到linux 下的FrameBuffer里,所以,按照以下方式就得到/dev/fb的基地址了:
//-----------------------------------------------------------------------//
struct fb_fix_screeninfo    fb_fixinfo; //linux下对fb的定义,该结构体中,有一个参数 smem_start即为FB的基地址
int fd= open("/dev/fb0", O_RDONLY);// Read_Only

ioctl(fd, FBIOGET_FSCREENINFO, &fb_fixinfo);
unsigned long frame_address= fb_fixinfo.smem_start;//此处即为FB的基地址


//--------------------------------------------------------------------//


得到该地址后,还可以实现截图的功能


不过,这个没有满足我的要求
验证后发现,将linux_fb的基地址映射到FPGA一侧后,当退出QT程序,LCD却显示Linux的终端窗口,看来映射linux_fb的基地址是不对的,应该映射QT的frame_buffer,如图所示。请问,如何得到QT所代表的FrameBuffer呢?

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复 支持 反对

使用道具 举报

累计签到:256 天
连续签到:1 天
2015-6-24 11:17:07 显示全部楼层
留脚印......................
回复 支持 反对

使用道具 举报

累计签到:2 天
连续签到:1 天
2015-6-26 09:56:03 显示全部楼层
本帖最后由 sh200436 于 2015-6-26 10:36 编辑

各位,这几天看了下Qt里的各种类,发现在qscreenlinuxfb_qws.cpp里有这么一句:

data = (unsigned char *)mmap(0, mapsize, PROT_READ | PROT_WRITE,
                                     MAP_SHARED, d_ptr->fd, 0);


想必这个data就是Qt的FrameBuffer指针了。而后在QSreen的类里找到了data的定义,同时在该类里出现一个函数:base(),它的返回值就是data指针。

继续追踪,在qapplication_qws.cppvoid QWSDisplay Data:init()函数里,有这么一句:

QScreen *s = qt_get_screen(qws_display_id, qws_display_spec.constData());

这个 s 里就包含Qt_FrameBuffer的指针, 即 FrameBuffer_address = s-->base();
上述是反推的过程。再正过来看,应该是这么一个过程:
Qapplication----->初始化显示参数——>申请FrameBuffer----->将Linux_fb映射到该FrameBuffer------>显示

现在的问题其实就转化成了这个问题:

如何在Qapplication里得到Qscreenbase()参数?
或者,在Qt里如何使用Qscreen而得到base()参数?

--估计这应该是个简单的的问题,但对于我这个初学者来说,有点难啊,希望大家帮帮忙啊,我C语言不好。。。。谢谢。
回复 支持 反对

使用道具 举报

累计签到:2 天
连续签到:1 天
2015-7-24 21:26:18 显示全部楼层
本帖最后由 sh200436 于 2015-7-24 22:09 编辑

经过这段时间的研究,理清了物理地址和虚拟地址的关系

1.上述的Qscreen的base()参数得到的是虚拟地址,即QT_Buffer对应的是虚拟地址。

2.FPGA一侧需要的是物理地址,并且要求物理地址连续。

因此,即使得到了base()的地址,直接给FPGA也是不行的。

下面就阐述一下解决方法:

1.在linux下重新开发一个frameBuffer驱动。设置好fb_fix_info和fb_var_info后,让该驱动去申请一块连续的物理地址。安装好驱动后,在驱动列表里,会出现第二个fb ----  /dev/fb1。linux默认的fb是fb0 -----/dev/fb0。

2.修改QT的源代码:在src/gui/embedded/qscreenlinuxfb_qws.cpp里,把“/dev/fb0”修改为“/dev/fb1”,然后交叉编译QT。

3. 在QT应用程序里,使用open("/dev/fb1", O_RD_ONLY) 和iotl()得到fb1的fix.smem_start即为fb1的物理地址,将该参数赋值给FPGA即可。

-----这样就成功躲开了linux-fb0,当QT退出后,LCD就不再显示linux黑色命令框了。









回复 支持 反对

使用道具 举报

累计签到:139 天
连续签到:1 天
2016-4-28 10:42:08 显示全部楼层
楼主好大牛啊,刚开始学qt就已经研究的这么深入了,膜拜,希望有机会多向你请教学习。
回复 支持 反对

使用道具 举报

累计签到:13 天
连续签到:1 天
2016-6-21 17:00:59 显示全部楼层
在寻找qt frambuffer双缓冲路上,看到楼主文章,感觉楼主学得好深入,膜拜
回复 支持 反对

使用道具 举报

累计签到:4 天
连续签到:1 天
2017-6-19 22:36:32 显示全部楼层
sh200436 发表于 2015-7-24 21:26
经过这段时间的研究,理清了物理地址和虚拟地址的关系:

1.上述的Qscreen的base()参数得到的是虚拟地址 ...

多谢楼主分享,很核心啊
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

公告
可以关注我们的微信公众号yafeilinux_friends获取最新动态,或者加入QQ会员群进行交流:190741849、186601429(已满) 我知道了