Skip to main content

MIPI_DSI屏

一 软件配置

1.1 屏幕相关配置

以开发板硬件lcd为例 ,lcd配置

2

(不同 lcd在不同板级设备引脚可能不同, 要根据原理图配置.)

3

此设备gpio backlight enable不设置, 在背光驱动里面单独配置. lcd及触摸屏供电共用一个gpio,通过设备电源管理"GPIO-POWER0" 控制

4

1.2 背光配置

默认使用pwm调整背光亮度

5

需要用到pwm驱动

1

1.3 framebuffer 配置

进入如下的配置目录, 勾选framebuffer 驱动, 并进入配置.

6

默认使用直通,若画面显示有异常或lcd underrun等报错,可以选择mixer, 旋转使用rotator

7

mixer及rotator默认多两帧fb内存消耗, rotator另外需要512 字节对齐, 分辨率800 ×1280的屏幕为例 , 计算如下

mixer 2帧:800×1280×4×2 , 可以修改帧数

12

rotator: 800×4需要被512整除, 实际消耗512×7×1280×2, 可以修改帧数, 旋转角度

11

fb帧数配置, 视频流默认可配置0帧,ui图形界面配置1帧

8

二 验证

开机启动后, 使用lsmod命令查看驱动是否安装成功. 需要有下面3个驱动, 否则屏幕不能正常使用.

9

查询设备列表ls /dev/fb*, 需要有fb设备. 否则fb驱动安装失败.

# ls /dev/fb*
/dev/fb0 /dev/fb1 /dev/fb_layer_mixer

三 使用cmd_fb工具命令实现显示效果

3.1 使能lcd, fb设备

如果/dev目录下没有fb设备, 表示lcd或者fb驱动未初始化成功. 请重新检查上述配置, 编译. 烧录操作

# 使能 fb 设备,上电并初始化.
cmd_fb enable /dev/fb0;

# 在某一帧绘制一个方形数据, 绿色.
# x, y: 绘制像素点的起始位置.(默认是x=0, y=0)
# width, height: 绘制方块的宽度, 高度.(默认是lcd设备宽度, 高度)
# frame_index: 根据自己设置的帧缓冲选择. 上述我设置fb0帧缓冲数为2, frame_index可以使用的值0, 1.(默认是0)
cmd_fb draw_rect /dev/fb0 color=0xff00ff00 frame_index=0 x=0 y=0 width=200 height=200;

# 将某一帧缓冲的数据刷新到屏幕上
cmd_fb display /dev/fb0 frame_index=0;
# 将fb设备中的某一帧清除成指定颜色 白色
cmd_fb clear /dev/fb0 color=0xffffffff frame_index=0;

# 将某一帧缓冲的数据刷新到屏幕上
cmd_fb display /dev/fb0 frame_index=0;

实现叠层操作, 需要配置2个fb设备. 分别操作两个fb设备 fb0 和 fb1, 刷入不同的数据. 操作的方式如上. 这样就可以看到叠层的显示效果.

四 使用fb API编写程序实现显示效果

4.1 编写测试程序

将如下代码编译, 运行, 轮流显示各种颜色.

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

/* 绘制方形, 数据长度为32位.
** 向一块fb内存写入数据
*/
static void draw_rect32(unsigned int *p, int x, int y, int x1, int y1,
unsigned int color, struct fb_device_info *info)
{
p = (void *)p + y*info->line_length + x*4;

int i, j;
for (i = 0; i < y1 - y; i++){
for (j = 0; j < x1 - x; j++) {
p[j] = color;
}
p = (void *)p + info->line_length;
}
}

/* 绘制一个方形
** int x, int y: 绘制图像的起始点
** int weight, int height: 绘制图像的宽高
*/
static void draw_rect(void *mem, int x, int y, int width, int height,
unsigned int color, struct fb_device_info *info)
{
int xres = info->xres;
int yres = info->yres;
int x1 = (width < 0) ? xres : x + width;
int y1 = (height < 0) ? yres : y + height;

if (x1 > xres)
x1 = xres;

if (y1 > yres)
y1 = yres;

if (x < 0)
x = 0;

if (y < 0)
y = 0;

int bytes = info->line_length / info->xres;

if (bytes < 4) {
fprintf(stderr, "not support pix fmt: %d %d %d\n",
info->bits_per_pixel, info->line_length, info->xres);
exit(-1);
}
draw_rect32(mem, x, y, x1, y1, color, info);
}

int main(int argc, char *argv[])
{
int fd, ret;
struct fb_device_info info;

printf("lcd test...\n");

fd = fb_open("/dev/fb0", &info);
if (fd < 0) {
fprintf(stderr, "can`t open /dev/fb0.\n");
return -1;
}

ret = fb_enable(fd);
if (ret < 0) {
fprintf(stderr, "can`t enable fb.\n");
return -1;
}

/* 6种不同颜色的数据 */
unsigned int color[6] = {
0xffff0000,
0xffffff00,
0xffff00ff,
0xff00ff00,
0xff00ffff,
0xff0000ff,
};

void *fb_base = info.mapped_mem + info.frame_size * 0;
for (int i=0; i<12; i++) {
/* 在指定的内存区域, 填充显示数据 */
draw_rect(fb_base, 0, 0, -1, -1, color[i%6], &info);
ret = fb_pan_display(fd, &info, 0);
if (ret < 0) {
fprintf(stderr, "fb_pan_display error.\n");
return -1;
}
usleep(500 * 1000);
}

fb_close(fd, &info);
return 0;
}

4.2 测试程序编译和使用

编译流程

因为编译需要链接到一些君正提供的库文件, 使用/buildroot/buildroot24/output/host/bin/mips-linux-gnu-gcc这个编译工具.

举例, 我的应用lcd_test.c文件在工程目录下的/myapp目录.

进入/myapp目录

cd /myapp    # 进入用户app目录
../buildroot/buildroot24/output/host/bin/mips-linux-gnu-gcc lcd_test.c -o lcd_test -lhardware2 # 使用编译器编译 指定库-lhardware2

将编译好的模块传输到文件系统有2种方式.

(1). 编译好的模块可以通过adb传输到板子上, 运行. 例如

adb push lcd_test /tmp

# 在设备终端上使用命令, 可以看到颜色刷屏效果.
cd /tmp
./lcd_test

(2). 打包到文件系统, bin文件会在/usr/bin文件目录下面.

cd myapp    # 进入到用户app目录下
cp lcd_test ../buildroot/buildroot24/output/target/usr/bin/ # 拷贝模块到文件系统/usr/bin目录下.

# 进入/build目录
make buildroot # 重新打包文件系统, 重新烧录.

# 在设备终端使用命令, 运行. 可以看到颜色刷屏效果.
lcd_test

五 fb API相关说明

上述使用的API介绍

int fb_open(const char *dev_path, struct fb_device_info *info)
功能:打开fb设备驱动,获取fb操作句柄
参数:const char *dev_path 如:/dev/fb0 //fb设备路径
struct fb_device_info *info //需要初始化的info结构体
返回值:成功:fb操作句柄; 失败:-1

int fb_close(int fd, struct fb_device_info *info)
功能:关闭fb设备句柄,释放内存资源
参数:int fd //fb设备操作句柄
struct fb_device_info *info //需要被释放的info结构体
返回值:成功:0; 失败:负数.

int fb_enable(int fd);
功能:使能fb设备,上电
参数:int fd //fb设备操作句柄
返回值:成功:0; 失败:负数.

int fb_pan_display(int fd, struct fb_device_info *info, unsigned int frame_index);
功能:显示/刷新fb指定的帧
参数:int fd //fb设备操作句柄
struct fb_device_info *info //fb设备的相关信息的结构体
unsigned int frame_index //要显示帧的序号
返回值:成功:0; 失败:负数.