VS离线包制作以及搭建LVGL模拟器环境

在 Windows Eclipse C/C++ 以及 VS2019 下搭建模拟器环境

Posted by Jerry Chen on June 6, 2020

准备工具

一些介绍

LVGL 是开源RTOS(实时操作系统)RT-Thread 上的一个 GUI 软件包,截至目前最新版为 v7.0.2。

官网:lvgl.io

GitHub:github.com/lvgl

相关网站:

CDT 开始

一、安装 Eclipse CDT(C/C++)

  1. 在官网下载页面安装启动下载工具(进去可选择安装支持C/C++的版本)

    在如下界面选择“China - TUNA”源进行下载:

  2. 如果未安装 Java,打开安装器软件就会有如下提示

    在此页面可跳转官网,接着下载和安装包含 Java 1.8.0 的 JDK;

  3. 配置 JDK 环境变量

    需要建立 JAVA_HOME 变量,新增 Path 变量

    注意 JDK 13 版本上 jre 和 jdk 已经合在同一安装目录下了,安装后这两个都有;

    新建一个系统变量“JAVA_HOME”

    在系统”Path“变量中新增一项,写入%JAVA_HOME%\bin

    最后 CMD 验证 Java 是否安装成功:

  4. 接着继续用安装器软件进行安装

    选择”Eclipse IDE for C/C++ Developers“

    选择安装路径:

    但是安装失败了,心累。。原因是国内网络下载太慢,故直接选国内源下载 CDT:点这里

    最后,我解压放在了:D:\Program Files\eclipse\CDT

二、安装 MinGW

MinGW 提供 Windows 上的 gcc 工具;

下载页面选择”MingW-W64-builds“进行下载:

按照如下设置安装:

选择安装路径:

安装完成后,将安装目录下的 bin 目录添加到系统 Path:

我添加如下地址:

1
D:\Program Files\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin

验证是否安装成功:

CMD 中输入 gcc -v 显示版本号说明安装成功;

三、安装 SDL2

SDL 2是一个在PC上模拟 TFT 屏和触摸板的库。

这里下载开发库:

  • 复制 x86_64-w64-mingw32\include 中 SDL2 文件夹到 x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\include
  • 复制 x86_64-w64-mingw32\lib 中所有文件到 x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\lib
  • [这步在后面操作] 复制 x86_64-w64-mingw32\bin\SDL2.dll{eclipse_worksapce}/pc_simulator/Debug/,放在工程调试目录下,也就是默认的 Eclipse CDT 工程生成目标 exe 的目录;

四、下载 eclipse 环境的 PC 模拟运行源码

官方 Github 地址

  1. 从 Github 下载工程

    这步真的太痛苦了,特别是内部的三个子模块(submodule)总是下载不了,最后是使用 https://notebooks.azure.com/ 进行中转下载的;

    1
    
    git clone --recursive https://github.com/lvgl/lv_sim_eclipse_sdl.git
    

    我的工程路径(注意更名):D:\Projects\lvgl\pc_simulator

  2. 启动 Eclipse CDT,选择 Workspace

    我选择的路径是 D:\Projects\lvgl

  3. 复制 SDL2.dll 文件到 Eclipse CDT 的工作目录的子目录下

    编译后默认会在 Debug 目录下生成 exe 文件,所以放在这个目录下;

    复制 x86_64-w64-mingw32\bin\SDL2.dll{eclipse_worksapce}/pc_simulator/Debug/

  4. 导入工程

    ”File“ -> ”Import“ -> ”General“ -> ”Existing Projects into Workspace“ -> ”在 root directory 选择中拾取 pc_simulator 文件夹“,进行导入;

    成功导入的界面如下:

    注意,此时还不能点锤子图标编译工程;

  5. 配置工程

    ”project“ -> ”properties“ -> ”C/C++ Build“ -> ”Settings“ -> ”Libraries -> Add“ 进行操作,在 SDLmain 和 SDL 之前添加一项 mingw32,注意顺序;

    ”project“ -> ”properties“ -> ”C/C++ Build“ -> ”Tool Chain Editor“ -> ”Current toolchain“ 修改为 MinGW GCC;

  6. 编译工程

    如果是其他错误,说明工程有问题,请重新下载~

    点击“锤子”图标编译工程,会发现找不到“SDL2.h”头文件:

    解决方法:

    添加一个头文件路径:${MINGW_HOME}/include

  7. 运行工程

    编译完成后,点击“三角”按钮运行工程,会报如下错误:

    需要在工程启动配置中选择生成的 exe 文件:

    成功运行如下:

VS2019/VS2022 开始

VS2019/VS2022 离线包的制作

官方的离线安装说明–>点击打开

1.下载 vs引导程序 ,选择你所需的版本下载,我选择了社区版 vs_Community.exe

2.设置命令参数(命令参数说明),启动vs2019引导程序下载

命令如下:

1
<vs引导程序exe> --layout <离线安装包下载的路径> --add <功能模块> --lang <语言> 

–layout:指定用于创建脱机安装缓存的目录,也就离线安装包下载的路径,必须是绝对路径

–add:要添加的一个或多个工作负载或组件 ID。指定多个工作负载和组件时,在每个负载前都使用 --add 命令行开关;

示例:

安装 C++ 的桌面开发(包含 MSVC 编译器):

1
.\vs_community.exe --layout D:\VS2022 --add Microsoft.VisualStudio.Workload.NativeDesktop --includeRecommended --lang zh-CN

安装 C++ 的 Linux 开发(WSL2 需要用到这个组件),建议和 C++ 桌面开发同时制作离线包:

1
.\vs_community.exe --layout D:\VS2022 --add Microsoft.VisualStudio.Workload.NativeCrossPlat --includeRecommended --lang zh-CN

还可用 Free ISO Creator 工具将目标文件夹制作为 ISO 镜像,方便使用;

PC 模拟运行源码

该章节使用 VS2019。如果你是 VS2022 请看个大概,应该也是大同小异;

  1. 下载仿真源码 LVGL 在 VS2017 下的仿真源码
  2. 使用 VS2019 打开项目(2017),提示升级,按默认升级工程

运行效果如图:

LVGL 移植方法

参见官方博客

参见 Github README

一、下载 lvgl 库

下载地址: github.com/lvgl/lvgl

国内码云: gitee.com/mirrors/lvgl

下载好的根目录 lvgl 是我们的库目录;

二、将库复制到项目

从库中复制 lvgl/lv_conf_template.h 文件放到库根目录的同级目录并重命名为 lv_conf.h

三、修改配置文件

首先启用配置文件 lv_conf.h,把该文件顶部的 if 0 改为 if 1

修改 lv_conf.h 文件,至少修改这三个地方:

  • LV_HOR_RES_MAX 显示横向像素
  • LV_VER_RES_MAX 显示纵向像素
  • LV_COLOR_DEPTH 显示色彩深度(可选 1、8、16、32)

单色屏的配置可参考这篇官方博客,参考上面的宏定义更改即可;

四、创建我的应用程序

  1. 在我的应用程序中引用 lvgl/lvgl.h 头文件;

    1
    
    #include "lvgl/lvgl.h"
    
  2. 初始化 LVGL

    1
    2
    
    /*Initialize LVGL*/
    lv_init();
    
  3. 创建和注册显示缓冲区

    1
    2
    3
    
    static lv_disp_buf_t disp_buf;
    static lv_color_t buf[LV_HOR_RES_MAX * 10];
    lv_disp_buf_init(&disp_buf, buf, NULL, LV_HOR_RES_MAX * 10);
    
  4. 创建和注册显示驱动

    1
    2
    3
    4
    5
    6
    7
    
    monitor_init(); //显示设备的初始化(配置、清屏等)
       
    lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);
    disp_drv.flush_cb = my_disp_flush;
    disp_drv.buffer = &disp_buf;
    lv_disp_drv_register(&disp_drv);
    

    其中 my_disp_flush 是显示函数,需要实现中间的打点函数 my_set_pixel(x, y, *color_p)

    color_p 指针指向的是显示缓冲区,每打一个点需要右移色深的位数;可能你还需要在这片区域全部打点完成后,调用一次你的屏幕刷新函数 my_monitor_flush(或者在 lvgl 配置中用宏指定你的刷新函数,这样只用在函数尾部保留 lv_disp_flush_ready 即可);

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    void my_disp_flush(lv_disp_t * disp, const lv_area_t * area, lv_color_t * color_p){
        int32_t x, y;
        for(y = area->y1; y <= area->y2; y++) {
            for(x = area->x1; x <= area->x2; x++) {
                my_set_pixel(x, y, *color_p);
                color_p++;
            }
        }
        //my_monitor_flush(); //在这里刷新一次,或者宏定义中指定刷新函数
        lv_disp_flush_ready(disp);
    }
    
  5. 创建显示

    如下是创建了一个 “Hello world” 文本标签,并放在中心;

    1
    2
    3
    4
    
    /*Create a "Hello world!" label*/
    lv_obj_t * label = lv_label_create(lv_scr_act(), NULL);
    lv_label_set_text(label, "Hello world!");
    lv_obj_align(label, NULL, LV_ALIGN_CENTER, 0, 0);
    
  6. 5ms 执行一次

    1
    2
    3
    4
    5
    
    while (1) {
    	lv_task_handler();
    	usleep(5 * 1000);
    	lv_tick_inc(5);
    }
    

五、打印测试

单色屏将驱动改为如下,把 color_p 指向的内容全部打印出来:

1
2
3
4
5
6
7
8
9
10
11
12
void my_disp_flush(struct _disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
{
    int32_t x, y;
    for(y = area->y1; y <= area->y2; y++) {
        for(x = area->x1; x <= area->x2; x++) {
            printf("%d", *color_p);
            color_p++;
        }
        printf("\n");
    }
    lv_disp_flush_ready(disp_drv);
}

结果:

你也可以尝试打印下坐标,看看 my_disp_flush 执行了几次,写入了哪些地方;