想用hi3531做Qt的开发,网上有相关的资料,但是解释就没那么清楚了,总结一下给大家分享.首先是网上已经有的文章.
http://blog.sina.com.cn/s/blog_48fba8050100y5yl.html
最近本人想要在Hi3531平台上运行QT,故有一些心得,写在这里与大家分享一下:
但是这时候qt 程序只显示在一个小方块上,还有其他鼠标和图片的干扰,分辨率也只有720P,而不是1080P.接下来我们做相应的修改,使其满足我们开发Qt程序的需要.
一、设置显存
在《HIFB开发指南》中讲到要给每个图形叠加层多大的显存。
2.2 参数设置
HiFB可配置其管理的叠加图形层物理显存的大小。物理显存大小决定了HiFB可使用
的最大物理显存和系统的可设置虚拟分辨率。在加载HiFB驱动时通过参数传递设置物
理显存大小,物理显存的大小一经设置就不会改变。
参数video
video=“hifb:vram0_size:xxx, vram1_size:xxx,…”
z 选项之间用逗号“,”隔开。
z 选项和选项值之间用冒号“:”隔开。
z 如果某个图层不配置物理显存大小,则系统默认分配为0。
z vram0_size ~ vram6_size分别对应于叠加图形层0 ~ 叠加图形层6。
其中,vramn_size:xxx表示对叠加图形层n配置xxx K字节的物理显存。
(1)对于FB标准模式,vramn_size和虚拟分辨率的关系如下:
Vramn_size * 1024 >= xres_virtual * yres_virtual * bpp;
其中:xres_virtual * yres_virtual是虚拟分辨率,bpp是每个像素所占字节数。
(2)对于FB扩展模式,各个图形层需要的内存大小取决于displaysize的大小、图层像
素格式以及刷新模式,具体关系如下:
vramn_size * 1024 >= displaywidth * displayHeight * bpp * BufferMode;
如:图形层0在1280*720 分辨率、ARGB8888格式的2 buffer模式下需要的内存
vram0_size = 1280*720*4*2 = 7200 K。
vramn_size必须是PAGE_SIZE(4K byte)的倍数,否则HiFB驱动强制将其设为PAGE_SIZE的
倍数,向上取整。
参数默认值
如果加载HiFB驱动时不带任何参数,则系统默认配置的参数值见下。
(1) Hi3531
video="hifb:vram0_size:7200,vram1_size:7200,vram2_size:3240,vram3_size:3240,v
ram4_size:7200,vram5_size:128,vram6_size:128" softcursor="off"
2.3 配置举例
配置HiFB管理叠加图形层的示例如下:
HiFB驱动的模块文件为hifb.ko。
z 配置HiFB管理一个叠加图形层。
如果只需要HiFB管理叠加图形层0,且最大虚拟分辨率为720 x 576,用到的象素
格式为ARGB1555,则叠加图形层0需要的最小显存为720 x 576 x 2 = 829440 =
810K,配置参数如下:
insmod hifb.ko video="hifb:vram0_size:810, vram2_size:0"。
如果采用的是double buffer的方式,则需要乘以2,即:
insmod hifb.ko video="hifb:vram0_size:1620, vram2_size:0"。
z 配置HiFB管理多个叠加图形层。
如果需要HiFB管理叠加图形层0和叠加图形层1两个叠加层,且最大虚拟分辨率
为720 x 576,用到的像素格式为ARGB1555,则两个叠加层需要的最小显存都为
720 x 576 x 2 = 829440 = 810K,配置参数如下:
insmod hifb.ko video="hifb:vram0_size:810, vram1_size: 810"
我使用的是fb0设备,分辨率为1080P=1920*1080, 1920*1080=2073600=2025k 这个应该是最小的内存数,我在 load3531中设置的参数为
insmod hifb.ko video="hifb:vram0_size:20000,vram1_size:7200,vram2_size:3240,vram3_size:3240,\
vram4_size:7200,vram5_size:128,vram6_size:128" softcursor="off" u32VcmpBufNum=2\
apszLayerMmzNames="mmzname0","mmzname1",,"graphics",,"mmzname0"
hifb:vram0_size:20000,20M肯定够了。
二、打开HDMI接口,设置屏幕分辨率、屏幕起始坐标,透明度等
下面修改 sample_hifb.c 文件.里面有打开HDMI接口,设置屏幕分辨率、屏幕起始坐标等
参考文档: 《HiFB 开发指南》,《HiFB API参考》,《HiMPP 媒体处理软件开发参考》
1. main 函数
VO_PUB_ATTR_S
【说明】
定义视频输出公共属性结构体。
【定义】
typedef struct hiVO_PUB_ATTR_S
{
HI_U32 u32BgColor; /* 设备背景色RGB表示*/
VO_INTF_TYPE_E enIntfType; /* Vo 接口类型*/
VO_INTF_SYNC_E enIntfSync; /* Vo接口时序类型*/
VO_SYNC_INFO_S stSyncInfo; /* Vo接口时序信息*/
HI_BOOL bDoubleFrame; /* 是否需要倍帧*/
} VO_PUB_ATTR_S;
u32BgColor 设备背景色,表示方法RGB888。
分辨率修改为1080P,这个最后才找到。
stPubAttr.enIntfSync = VO_OUTPUT_1080P50;
只用一个线程phifb0设置屏幕分辨率和phifb1设置画布起始点 就行了,所以可以把phifb2 的pthread_create, pthread_join 函数注释掉。线程0的参数如下
/*start hifb */
stInfo0.layer = 0;
stInfo0.fd = -1;
stInfo0.ctrlkey = 0;
pthread_create(&phifb0,0,SAMPLE_HIFB_REFRESH,(void *)(&stInfo0));
2. 函数HI_VOID *SAMPLE_HIFB_REFRESH(void *pData) 里包含了设置屏幕分辨率的部分.先用FBIOGET_VSCREENINFO:获取屏幕可变信息,再用 FBIOPUT_VSCREENINFO:设置屏幕可变信息 。
s32Ret = ioctl(pstInfo->fd, FBIOGET_VSCREENINFO, &stVarInfo);
if(s32Ret < 0)
{
printf("GET_VSCREENINFO failed!\n");
return HI_NULL;
}
if (ioctl(pstInfo->fd, FBIOPUT_SCREEN_ORIGIN_HIFB, &stPoint) < 0)
{
printf("set screen original show position failed!\n");
return HI_NULL;
}
//slq
maxW = 1920;
maxH = 1080;
stVarInfo.xres = stVarInfo.xres_virtual = maxW;
stVarInfo.yres = stVarInfo.yres_virtual = maxH;
s32Ret = ioctl(pstInfo->fd, FBIOPUT_VSCREENINFO, &stVarInfo);
if(s32Ret < 0)
{
printf("PUT_VSCREENINFO failed!\n");
return HI_NULL;
}
else
{
printf("PUT_VSCREENINFO success!\n");
}
缓存方式选择,有无缓存,单缓存,双缓存
switch (pstInfo->ctrlkey)
{
case 0 :
{
stLayerInfo.BufMode = HIFB_LAYER_BUF_ONE;
stLayerInfo.u32Mask = HIFB_LAYERMASK_BUFMODE;
break;
}
case 1 :
{
stLayerInfo.BufMode = HIFB_LAYER_BUF_DOUBLE;
stLayerInfo.u32Mask = HIFB_LAYERMASK_BUFMODE;
break;
}
default:
{
stLayerInfo.BufMode = HIFB_LAYER_BUF_NONE;
stLayerInfo.u32Mask = HIFB_LAYERMASK_BUFMODE;
}
}
这部分不知道干啥的,应该是内存计算之类的吧,反正里面的1280,720改成 1920,1080不会错
for (y = 358; y < 362; y++)
{
for (x = 0; x < 1920; x++)
{
*(pBuf + y * maxW + x) = HIFB_RED_1555;
}
}
for (y = 0; y < 1080; y++)
{
for (x = 638; x < 642; x++)
{
*(pBuf + y * maxW + x) = HIFB_RED_1555;
}
}
我的主函数调用时,pstInfo->ctrlkey =0,所以只用修改 case 0 就可以了,虚拟宽度,高度和真实宽度,高度都设为1920*1080
switch(pstInfo->ctrlkey)
{
case 0:
{
//slq
//window width and height
var.xres_virtual = 1920;
var.yres_virtual = 1080;
var.xres = 1920;
var.yres = 1080;
}
break;
case 1:
{
var.xres_virtual = 100;
var.yres_virtual = 100;
var.xres = 220;
var.yres = 200;
}
break;
case 2:
{
var.xres_virtual = SAMPLE_VIR_SCREEN_WIDTH;
var.yres_virtual = SAMPLE_VIR_SCREEN_HEIGHT;
var.xres = SAMPLE_IMAGE_WIDTH;
var.yres = SAMPLE_IMAGE_HEIGHT;
}
break;
case 3:
{
var.xres_virtual = 48;
var.yres_virtual = 48;
var.xres = 48;
var.yres = 48;
}
break;
default:
{
var.xres_virtual = 98;
var.yres_virtual = 128;
var.xres = 98;
var.yres = 64;
}
}
3. 函数HI_VOID *SAMPLE_HIFB_PTHREAD_RunHiFB(void *pData)里包含了设置屏幕起始坐标等
设置 alpha 透明度, 修改 stAlpha.u8GlobalAlpha = 0xff; 即可.
/* 3.set alpha */
stAlpha.bAlphaEnable = HI_TRUE;
stAlpha.bAlphaChannel = HI_TRUE;
stAlpha.u8Alpha0 = 0xff;
stAlpha.u8Alpha1 = 0xff;
//slq
//set transparent
stAlpha.u8GlobalAlpha = 0xff;
if (ioctl(pstInfo->fd, FBIOPUT_ALPHA_HIFB, &stAlpha) < 0)
{
printf("Set alpha failed!\n");
close(pstInfo->fd);
return HI_NULL;
}
if(pstInfo->layer == HIFB_LAYER_CURSOR_0 || pstInfo->layer == HIFB_LAYER_CURSOR_1)
{
stColorKey.bKeyEnable = HI_TRUE;
stColorKey.u32Key = 0x0;
if (ioctl(pstInfo->fd, FBIOPUT_COLORKEY_HIFB, &stColorKey) < 0)
{
printf("FBIOPUT_COLORKEY_HIFB!\n");
close(pstInfo->fd);
return HI_NULL;
}
}
在上述工作完成后
退出编辑,make后在板子上运行,屏幕为绿色,分辨率设置为1920*1080
# ./sample_hifb
tw2865 0x50 set to PAL mode ok!
tw2865 0x54 set to PAL mode ok!
tw2865 0x52 set to PAL mode ok!
tw2865 0x56 set to PAL mode ok!
u32Width:1920, u32Square:2
HDMI start success.
PUT_VSCREENINFO success!
expected:two red line!
程序运行一会就会自动结束,为了不让其自动结束,在上述工作后添加如下代码使程序一直运行,比如在设置好屏幕起始坐标后
//slq
if (pstInfo->ctrlkey == 0)
{
while(1)
sleep(5);
}
在后台运行 sample_hifb程序,便可再运行Qt 程序了
# ./sample_hifb &
tw2865 0x50 set to PAL mode ok!
tw2865 0x54 set to PAL mode ok!
tw2865 0x52 set to PAL mode ok!
tw2865 0x56 set to PAL mode ok!
u32Width:1920, u32Square:2
HDMI start success.
PUT_VSCREENINFO success!
expected:two red line!
此时屏幕背景色是青绿色的,