开发板:潘多拉开发板
  系统版本:v4.0.3
  LVGL版本:8.0.2

  注:这篇文章就简单记录下编译成功,跑了一个 demo 的过程,至于是否完全移植成功,不确定哈,毕竟 LVGL 还没自学呢。。

  

一、创建目录

  在 bsp/stm32/stm32l475-atk-pandora/board/ports 目录下创建一个 lvgl 目录,然后将 lvgl 的源码放进该目录。
  目录结构如下所示。
  ├─lvgl
  │ ├─lvgl-8.0.2

  

二、添加配置文件

  将 lvgl-8.0.2/lv_conf_template.h 文件复制到 lvgl 同级目录下,并将其重命名为 lv_conf.h 。打开文件并将开头的 #if 0 更改为 #if 1 以使能其内容。

  将 lv_drivers-6.1.1/lv_drv_conf_template.h 文件复制到 lv_drivers 同级目录下,并将其重命名为 lv_drv_conf.h 。打开文件并将开头的 #if 0 更改为 #if 1 以使能其内容。

  这里需要注意一下 lv_conf.h 文件里面的宏,对于 8.0.2 版本来说,只需要修改下面这个宏就可以了,具体的数值根据你的 LCD 参数决定。

/* Color depth: 1 (1 byte per pixel), 8 (RGB332), 16 (RGB565), 32 (ARGB8888) */
#define LV_COLOR_DEPTH     16

  

三、将主要的源码添加到工程中

  在实际操作之前,我们需要知道有哪些代码是需要添加到工程里面的。
  ├─lvgl
  │ ├─lvgl-8.0.2
  │ │ ├─src (必须)
  当然,这里只是添加了部分的源码,可以基本运行,如果要完整的源码,可以自行添加。

  

1、

  在 bsp/stm32/stm32l475-atk-pandora/board/ports/lvgl、bsp/stm32/stm32l475-atk-pandora/board/ports/lvgl/lvgl-8.0.2/src 目录下创建一个内容和下面相同的 SConscript 文件,用于自动生成工程。

import os
from building import *# get current dir path
cwd = GetCurrentDir()# init src and inc vars
src = Glob('*.c')inc = [cwd]objs = DefineGroup('lvgl', src, depend = [], CPPPATH = inc)list = os.listdir(cwd)for item in list:if os.path.isfile(os.path.join(cwd, item, 'SConscript')):objs = objs + SConscript(os.path.join(item, 'SConscript'))Return('objs')

  

2、

  在 bsp/stm32/stm32l475-atk-pandora/board/ports/lvgl/lvgl-8.0.2 创建一个内容和下面相同的 SConscript 文件,用于自动生成工程。

import os
from building import *# get current dir path
cwd = GetCurrentDir()objs = []list = os.listdir(cwd)for item in list:if os.path.isfile(os.path.join(cwd, item, 'SConscript')):objs = objs + SConscript(os.path.join(item, 'SConscript'))Return('objs')

  

3、

  在 bsp/stm32/stm32l475-atk-pandora/board/ports/lvgl/lvgl-8.0.2/src 目录下的子目录 core、draw、font、hal、misc、widgets 中创建一个内容和下面相同的 SConscript 文件,用于自动生成工程。

from building import *cwd = GetCurrentDir()
src = Glob('*.c') + Glob('*.cpp')+ Glob('*.a')CPPPATH = [cwd, str(Dir('#'))]# 因为是使用 keil 编译,所以要加上这句话
LOCAL_CCFLAGS = ' --c99 --gnu -g -W'group = DefineGroup('lvgl', src, depend = [], CPPPATH = CPPPATH, LOCAL_CCFLAGS = LOCAL_CCFLAGS)Return('group')

  

4、

  对于 bsp/stm32/stm32l475-atk-pandora/board/ports/lvgl/lvgl-8.0.2/src 目录下的子目录 extra 需要单独处理,因为它里面还有多个子目录。(所以下面的代码可维护性有点差)

from building import *cwd = GetCurrentDir()
src = Glob('*.c')src += Glob('./layouts/grid/*.c')
src += Glob('./layouts/flex/*.c')src += Glob('./themes/basic/*.c')
src += Glob('./themes/default/*.c')
src += Glob('./themes/mono/*.c')src += Glob('./widgets/animimg/*.c')
src += Glob('./widgets/calendar/*.c')
src += Glob('./widgets/chart/*.c')
src += Glob('./widgets/colorwheel/*.c')
src += Glob('./widgets/imgbtn/*.c')
src += Glob('./widgets/keyboard/*.c')
src += Glob('./widgets/led/*.c')
src += Glob('./widgets/list/*.c')
src += Glob('./widgets/meter/*.c')
src += Glob('./widgets/msgbox/*.c')
src += Glob('./widgets/span/*.c')
src += Glob('./widgets/spinbox/*.c')
src += Glob('./widgets/spinner/*.c')
src += Glob('./widgets/tabview/*.c')
src += Glob('./widgets/tileview/*.c')
src += Glob('./widgets/win/*.c')CPPPATH = [cwd]CPPPATH += [cwd + '/layouts']
CPPPATH += [cwd + '/layouts/grid']
CPPPATH += [cwd + '/layouts/flex']CPPPATH += [cwd + '/themes']
CPPPATH += [cwd + '/themes/default']
CPPPATH += [cwd + '/themes/basic']
CPPPATH += [cwd + '/themes/mono']CPPPATH += [cwd + '/widgets']
CPPPATH += [cwd + '/widgets/animimg']
CPPPATH += [cwd + '/widgets/calendar']
CPPPATH += [cwd + '/widgets/chart']
CPPPATH += [cwd + '/widgets/colorwheel']
CPPPATH += [cwd + '/widgets/imgbtn']
CPPPATH += [cwd + '/widgets/keyboard']
CPPPATH += [cwd + '/widgets/led']
CPPPATH += [cwd + '/widgets/list']
CPPPATH += [cwd + '/widgets/meter']
CPPPATH += [cwd + '/widgets/msgbox']
CPPPATH += [cwd + '/widgets/span']
CPPPATH += [cwd + '/widgets/spinbox']
CPPPATH += [cwd + '/widgets/spinner']
CPPPATH += [cwd + '/widgets/tabview']
CPPPATH += [cwd + '/widgets/tileview']
CPPPATH += [cwd + '/widgets/win']# 因为是使用 keil 编译,所以要加上这句话
LOCAL_CCFLAGS = ' --c99 --gnu -g -W'group = DefineGroup('lvgl', src, depend = [], CPPPATH = CPPPATH, LOCAL_CCFLAGS = LOCAL_CCFLAGS)Return('group')

   到这里,可以使用 scons --target=mdk5 来生成 keil 工程,然后编译一次,如果编译通过,那就移植完成了,后面就是初始化了。

  

四、lvgl 初始化

   对于 LVGL 的初始化,在 RT-Thread 中创建一个线程就可以了。
   对于 LVGL 心跳来说,在 RT-Thread 中创建一个软定时器就可以了。(注意内核要开启软定时器线程)
   其他的嘛,暂时没管。
   初始化完成后,就可以使用 demo 命令来运行 demo 了。

#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>#include <fal.h>
#include <dfs_fs.h>
#include <dfs_posix.h>#include <drv_lcd.h>
#include <lvgl.h>/* defined the LED0 pin: PE7 */
#define LED0_PIN    GET_PIN(E, 7)static rt_thread_t led_tid = RT_NULL;static rt_thread_t lvgl_tid = RT_NULL;
static rt_timer_t lvgl_timer = RT_NULL;#define MY_DISP_HOR_RES 240static void led_thread_entry(void *parameter)
{rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);while (1){rt_pin_write(LED0_PIN, PIN_HIGH);rt_thread_mdelay(500);rt_pin_write(LED0_PIN, PIN_LOW);rt_thread_mdelay(500);}
} int thread_sample(void)
{led_tid = rt_thread_create("led",led_thread_entry, RT_NULL,256,     /* stack size */25,      /* priority */5);      /* time slice */if (led_tid != RT_NULL)rt_thread_startup(led_tid);return 0;
}/* 这个函数定义在 lcd_drv.c 文件中,因为它使用了一些 lcd 驱动提供的函数 */
extern void lcd_lvgl_draw(rt_uint16_t x1, rt_uint16_t y1, rt_uint16_t x2, rt_uint16_t y2, rt_uint16_t* color);/*** void lcd_lvgl_draw(rt_uint16_t x1, rt_uint16_t y1, rt_uint16_t x2, rt_uint16_t y2,  rt_uint16_t* color)* {*   rt_uint16_t i,j;            *   rt_uint16_t width = x2 - x1 + 1;        /* 得到填充的宽度 */*   rt_uint16_t height = y2 - y1 + 1;       /* 高度 */*   *   lcd_address_set(x1,y1,x2,y2);*   rt_pin_write(LCD_DC_PIN, PIN_HIGH);**   for(i = 0; i < height; i++)*   {*       for(j = 0; j < width; j++)*       {*           lcd_write_half_word(color[i*width+j]);*       }   *   }** }**/void my_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{lv_coord_t hres = disp_drv->rotated == 0 ? disp_drv->hor_res : disp_drv->ver_res;lv_coord_t vres = disp_drv->rotated == 0 ? disp_drv->ver_res : disp_drv->hor_res;if(area->x2 < 0 || area->y2 < 0 || area->x1 > hres - 1 || area->y1 > vres - 1) {lv_disp_flush_ready(disp_drv);return;}lcd_lvgl_draw(area->x1, area->y1, area->x2, area->y2, (rt_uint16_t*)color_p);lv_disp_flush_ready(disp_drv);
}lv_disp_draw_buf_t disp_buf;
lv_disp_drv_t disp_drv;
lv_disp_t *disp;
lv_color_t g_buf[MY_DISP_HOR_RES * 10];static void lvgl_thread_entry(void *parameter)
{/* lvgl 库初始化 */lv_init();/* 显示缓冲区 */lv_disp_draw_buf_init(&disp_buf, g_buf, NULL, MY_DISP_HOR_RES * 10);/* 在 LVGL 中注册显示设备驱动程序 */lv_disp_drv_init(&disp_drv);disp_drv.draw_buf = &disp_buf;disp_drv.flush_cb = my_flush_cb;disp_drv.hor_res = 240;disp_drv.ver_res = 240;     disp = lv_disp_drv_register(&disp_drv);while (1){lv_task_handler();rt_thread_mdelay(5);  /* 官方手册是提议至少 5 ms */}
}static void lvgl_timeout(void *parameter)
{lv_tick_inc(10);    /* 因为一个时钟是 10ms */
}int lvgl_sample(void)
{lvgl_tid = rt_thread_create("lvgl",lvgl_thread_entry, RT_NULL,4096,     /* stack size */12,      /* priority */5);      /* time slice */if (lvgl_tid != RT_NULL)rt_thread_startup(lvgl_tid );lvgl_timer = rt_timer_create("lvgl_timer",lvgl_timeout,RT_NULL,1,  /* 超时时间,单位是时钟节拍 */RT_TIMER_FLAG_PERIODIC);if (lvgl_timer != RT_NULL) rt_timer_start(lvgl_timer );return 0;
}void fs_init(void)
{fal_init();fal_blk_device_create("filesystem");if (dfs_mount("filesystem", "/", "elm", 0, 0) != 0){if(dfs_mkfs("elm", "filesystem") == 0){if (dfs_mount("filesystem", "/", "elm", 0, 0) != 0){rt_kprintf("file system initialization failed!\n");}}}if (opendir("/mnt") == RT_NULL){if (mkdir("mnt", 0x777) == -1)return;}    if(rt_device_find("sd0") == RT_NULL){rt_kprintf("failed to find sd card device.\n");return;}if (dfs_mount("sd0", "/mnt", "elm", 0, 0) != RT_EOK){rt_kprintf("sd card mount to '/mnt' failed!\n");}
}/* 这个是官方例程,代码路径为:https://github.com/lvgl/lvgl/blob/master/examples/widgets/label/lv_example_label_1.c */
void demo(void)
{lv_obj_t * label1 = lv_label_create(lv_scr_act());lv_label_set_long_mode(label1, LV_LABEL_LONG_WRAP);     /*Break the long lines*/lv_label_set_recolor(label1, true);                      /*Enable re-coloring by commands in the text*/lv_label_set_text(label1, "#0000ff Re-color# #ff00ff words# #ff0000 of a# label, align the lines to the center ""and wrap long text automatically.");lv_obj_set_width(label1, 150);  /*Set smaller width to make the lines wrap*/lv_obj_set_style_text_align(label1, LV_TEXT_ALIGN_CENTER, 0);lv_obj_align(label1, LV_ALIGN_CENTER, 0, -40);lv_obj_t * label2 = lv_label_create(lv_scr_act());lv_label_set_long_mode(label2, LV_LABEL_LONG_SCROLL_CIRCULAR);     /*Circular scroll*/lv_obj_set_width(label2, 150);lv_label_set_text(label2, "It is a circularly scrolling text. ");lv_obj_align(label2, LV_ALIGN_CENTER, 0, 40);
}
MSH_CMD_EXPORT(demo, demo);int main(void)
{fs_init();  thread_sample();    lvgl_sample();return RT_EOK;
}

  

五、实际运行效果

【RTT】移植:LVGL 8.0.2相关推荐

  1. STM32移植Littlevgl(LVGL)V8.0.2使用文件系统+BMP解码显示外部FLASH中图片

    说明:选择BMP解码图片的方式,是因为此方式不需要占用太多的RAM 一.主要参数及版本 MCU:STM32F103ZET6 LCD:2.8寸ILI9341,使用FSMC驱动 SPI FLASH:W25 ...

  2. MCUXpresso开发NXP RT1060(3)——移植LVGL到NXP RT1060

    目录 开发环境 目录 一.开发环境 二.准备工作 三.移植步骤 1.修改lv_conf.h 2.显示功能移植 3.触摸功能移植 4.tick及timer 四.结果展示 五.参考资料 一.开发环境 1. ...

  3. 乐鑫ESP32移植LVGL 7.10

    零. 声明 本专栏文章我们会以连载的方式持续更新,本专栏计划更新内容如下: 第一篇:ESP-IDF基本介绍,主要会涉及模组,芯片,开发板的介绍,环境搭建,程序编译下载,启动流程等一些基本的操作,让你对 ...

  4. LVGL 8.0 lv_demo_widgets的学习

    LVGL 8.0 lv_demo_widgets的学习 出于喜欢 LVGL这个轻量级的Gui框架,所以打算进行学习.但是我在墨水屏设备上移植不成功,所以打算直接使用模拟器进行学习.接下来开始介绍我自己 ...

  5. STM32移植LVGL(LittleVGL)

    STM32移植LVGL(LittleVGL) 一.什么是LVGL https://lvgl.io/ 这是LVGL的官网, http://lvgl.100ask.org/8.2/intro/index. ...

  6. STM32移植LVGL+旋转编码器接口对接

    写在前面:本菜鸟结合了许多大佬的文章,成功实现了基于LVGL的GUI设计,小开心~浅浅记录一下!~ 本文以单片机STM32F103VET6为核心,利用ST7796芯片驱动分辨率为480*320的LCD ...

  7. 【LVGL】学习笔记--(1)Keil中嵌入式系统移植LVGL

    一 LVGL简介 最近emwin用的比较烦躁,同时被LVGL酷炫的界面吸引到了,所以准备换用LVGL试试水. LVGL(轻量级和通用图形库)是一个免费和开源的图形库,它提供了创建嵌入式GUI所需的一切 ...

  8. TFT-LCD移植LVGL详细过程记录

    TFT-LCD移植LVGL LVGL(轻量级和通用图形库)是一个免费和开源的图形库,它提供了创建嵌入式GUI所需的一切,具有易于使用的图形元素,美丽的视觉效果和低内存占用. LVGL更多介绍:http ...

  9. KLite 移植说明 V1.0

    2019独角兽企业重金招聘Python工程师标准>>> KLite 移植说明 V1.0 KLite是一个"简洁易用"的嵌入式操作系统微内核 目前支持Cortex- ...

最新文章

  1. 【TensorFlow2.0】(1) tensor数据类型,类型转换
  2. asp.net性能的技巧
  3. 2.1 DNS服务介绍和安装
  4. python创建变量并赋值_python怎么给变量赋值
  5. 硅谷公司:我们称他们为软件工程师,而非打工人
  6. python语言接收信息的内置函数_python接收信息的内置函数是
  7. 2.1.3 Sorting a Three-Valued Sequence 三值的排序
  8. 音乐推荐系统协同过滤算法解释
  9. 福利:appium+selenium+python 模拟手工点击趣头条(app赚钱软件)
  10. 如何搭建repo管理环境管理多个git仓库
  11. XTU Oj 128
  12. 【计算专业】有趣的拓扑学问题 动画演示
  13. 《Python数据分析与挖掘实战》示例源码免费下载
  14. php获取搜索框的函数,PHP自定义函数获取搜索引擎来源关键字的方法
  15. 河北工业大学c语言寻宝游戏,计算机技术基础(c语言)课程设计寻宝游戏.doc
  16. opencv2.0的移植 OMAP4460 FPU
  17. python pexpect_Python之pexpect详解
  18. 在家用c++实现贪吃蛇——c++小游戏
  19. 开课吧python课件_开课吧:廖雪峰数据分析全栈工程师第8期【视频+课件】-百度云下载...
  20. numpy-npy 和 npz

热门文章

  1. Lesson 9.4 随机森林在巨量数据上的增量学习和 Bagging 方法 6 大面试热点问题
  2. 汉语拼音的26个拼音字母该怎么学?
  3. 多元微积分_如何参数化实现绘制甜甜圈
  4. 全球及中国金属包装市场发展状况与竞争趋势研究报告2022版
  5. 计算机是白色的两种英文翻译,求翻译,汉翻英 ,急用!!!
  6. linux虚拟机使用NAT模式联网
  7. python 简单网络编程
  8. 电气器件系列十一:电气保护装置
  9. [绍棠] ijkplayer 的编译、打包 framework 和 https 支持
  10. 【海洋】SODA的资料下载,nc格式