这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 国产MCU » 飞凌嵌入式OK3568开发板直接在开发板上开发LVGL程序

共3条 1/1 1 跳转至

飞凌嵌入式OK3568开发板直接在开发板上开发LVGL程序

高工
2025-05-15 21:58:48     打赏

一、安装需要用到的依赖

安装gcc用来编译程序,cmake用来完成构建,ccache用来加速编译,ninja用来加速构建过程。

apt install gcc cmake ccache ninja-build

CMake是一个开源的跨平台构建系统,它使用一个简单的语言来描述项目的构建过程。这个语言可以用来描述项目的源文件、库依赖、构建选项等。CMake可以生成用于构建、测试和打包项目的Makefile、Visual Studio项目文件或者Xcode项目文件。

CMake的主要特点包括:

    CMake和Ninja一起使用可以提供以下优势:

      而ccache是一个用于减少编译时间的工具,它可以缓存编译器的输出,以便在多次构建相同的代码时重复利用。简单来说,就是用空间换时间。

      二、创建LVGL的CMake工程

      下载lvgl源码,不想把lvgl源码当做git工程的一部分提交,所以使用子仓模式添加lvgl源码


      mkdir lvgl_cmake
      cd lvgl_cmake/
      git submodule add -b release/v8.3 git@gitee.com:my_lvgl/lvgl.git lvgl

      源码拉取完毕之后,创建cmake工程配置文件。
      vi CMakeList.txt
      将以下内容输入该文件

      cmake_minimum_required(VERSION 3.12)
      project(lvgl VERSION 1.0)

      add_compile_options(-std=c99)

      # Configure CCache if available
      find_program(CCACHE_FOUND ccache)
      if(CCACHE_FOUND)
              set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache)
              set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache)
      endif(CCACHE_FOUND)

      set(LVGL_SDK_PATH ${PROJECT_SOURCE_DIR}/lvgl)
      set(LVGL_MAIN_SOURCE ${PROJECT_SOURCE_DIR}/main/src)

      include_directories(include ${PROJECT_SOURCE_DIR} ${LVGL_SDK_PATH})

      file(GLOB_RECURSE INCLUDES "lvgl/src/*.h"  "./*.h" "drivers/*.h" "display/*.h")
      file(GLOB_RECURSE SOURCES "lvgl/src/*.c" "display/*.c" "drivers/*.c")

      set(EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)

      set(CMAKE_CXX_FLAGS "-03")  #设置编译选项

      #添加对应的头文件搜索目录
      aux_source_directory(${LVGL_SDK_PATH}/../main/src src)
      add_executable(main ${src} ${SOURCES} ${INCLUDES})

      target_link_libraries(main PRIVATE ${LIB_LIST})

      add_custom_target(run COMMAND ${EXECUTABLE_OUTPUT_PATH}/main)

      复制lv_port_linux_frame_buffer里的lv_drv_conf.h和lv_conf.h到根目录。将lv_drivers仓的display目录里的fbdev.c和fbdev.h复制到display目录里。
      仓库地址https://github.com/lvgl/lv_port_linux_frame_buffer

      然后将main/src/main.c的内容修改成以下内容。

      #include "src/widgets/lv_label.h"

      #include "../../lvgl/lvgl.h"
      #define LV_ATTRIBUTE_TICK_INC

      #include "ini.h"
      #include <stdlib.h>
      #include <string.h>

      #include <time.h>
      #include <sys/time.h>

      void fbdev_flush(lv_disp_drv_t * drv, const lv_area_t * area, lv_color_t * color_p);

      static lv_obj_t *meter;

      static void set_value(void *indic, int32_t v) {
          lv_meter_set_indicator_end_value(meter, indic, v);
      }

      /**
       * A meter with multiple arcs
       */
      void lv_example_meter_xxxx(void) {
          meter = lv_meter_create(lv_scr_act());
          lv_obj_center(meter);
          lv_obj_set_size(meter, 200, 200);

          /*Remove the circle from the middle*/
          lv_obj_remove_style(meter, NULL, LV_PART_INDICATOR);

          /*Add a scale first*/
          lv_meter_scale_t *scale = lv_meter_add_scale(meter);
          lv_meter_set_scale_ticks(meter, scale, 11, 2, 10,
                                   lv_palette_main(LV_PALETTE_GREY));
          lv_meter_set_scale_major_ticks(meter, scale, 1, 2, 30, lv_color_hex3(0xeee),
                                         10);
          lv_meter_set_scale_range(meter, scale, 0, 100, 270, 90);

          /*Add a three arc indicator*/
          lv_meter_indicator_t *indic1 =
              lv_meter_add_arc(meter, scale, 10, lv_palette_main(LV_PALETTE_RED), 0);
          lv_meter_indicator_t *indic2 = lv_meter_add_arc(
              meter, scale, 10, lv_palette_main(LV_PALETTE_GREEN), -10);
          lv_meter_indicator_t *indic3 = lv_meter_add_arc(
              meter, scale, 10, lv_palette_main(LV_PALETTE_BLUE), -20);

          /*Create an animation to set the value*/
          lv_anim_t a;
          lv_anim_init(&a);
          lv_anim_set_exec_cb(&a, set_value);
          lv_anim_set_values(&a, 0, 100);
          lv_anim_set_repeat_delay(&a, 100);
          lv_anim_set_playback_delay(&a, 100);
          lv_anim_set_repeat_count(&a, LV_ANIM_REPEAT_INFINITE);

          lv_anim_set_time(&a, 500);
          lv_anim_set_playback_time(&a, 200);
          lv_anim_set_var(&a, indic1);
          lv_anim_start(&a);

          lv_anim_set_time(&a, 300);
          lv_anim_set_playback_time(&a, 500);
          lv_anim_set_var(&a, indic2);
          lv_anim_start(&a);

          lv_anim_set_time(&a, 100);
          lv_anim_set_playback_time(&a, 1000);
          lv_anim_set_var(&a, indic3);
          lv_anim_start(&a);
      }

      #define DISP_BUF_SIZE (128 * 1024)

      int main(void) {
          lv_init();

          /*Linux frame buffer device init*/
          fbdev_init();

          /*A small buffer for LittlevGL to draw the screen's content*/
          static lv_color_t buf[DISP_BUF_SIZE];

          /*Initialize a descriptor for the buffer*/
          static lv_disp_draw_buf_t disp_buf;
          lv_disp_draw_buf_init(&disp_buf, buf, NULL, DISP_BUF_SIZE);

          /*Initialize and register a display driver*/
          static lv_disp_drv_t disp_drv;
          lv_disp_drv_init(&disp_drv);
          disp_drv.draw_buf   = &disp_buf;
          disp_drv.flush_cb   = fbdev_flush;
          disp_drv.hor_res    = 800;
          disp_drv.ver_res    = 480;
          lv_disp_drv_register(&disp_drv);

          lv_example_meter_xxxx();
          printf("lvgl_example\n");
          while (1) {
              lv_task_handler();
              usleep(30 * 1000);
          }

          return 0;
      }

      uint32_t custom_tick_get(void)
      {
          static uint64_t start_ms = 0;
          if(start_ms == 0) {
              struct timeval tv_start;
              gettimeofday(&tv_start, NULL);
              start_ms = (tv_start.tv_sec * 1000000 + tv_start.tv_usec) / 1000;
          }

          struct timeval tv_now;
          gettimeofday(&tv_now, NULL);
          uint64_t now_ms;
          now_ms = (tv_now.tv_sec * 1000000 + tv_now.tv_usec) / 1000;

          uint32_t time_ms = now_ms - start_ms;
          return time_ms;
      }

      添加完其他必须的源文件后,就可以开始构建和编译了。

      三、编译和测试

      使用以下命令生成构建文件目录build

      cmake -B bulid -G Ninja

      效果如下图

      image.png

      成功生成构建目录后,需要使用ninja开始编译。一旦添加了新的源码文件,或者修改了CMake编译配置,需要删除build目录重新生成构建目录。

      ninja -C bulid/
      很快就编译好了,基本上不需要耗费多少时间。由于有ccache的编译缓存,以后编译的速度都会非常快。
      image.png

      由于这个板子的Ubuntu系统默认开启了Xorg,我暂时也没找到关闭Xorg的方法。pkill Xorg无效。在别的开发板上运行这个编译出来的main程序,是可以正常显示的。

      25b0f6736ad363981f0cf250020220e.jpg

      若需要删除build构建目录,使用以下命令。

      rm -rf bulid/





      关键词: OK3568     CMake     LVGL    

      专家
      2025-05-15 22:11:33     打赏
      2楼

      感谢分享


      专家
      2025-05-16 21:10:59     打赏
      3楼

      开发图形界面,LVGL 是个不错的选择。


      共3条 1/1 1 跳转至

      回复

      匿名不能发帖!请先 [ 登陆 注册 ]