【RTT】移植:LVGL 8.0.2
开发板:潘多拉开发板
系统版本: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相关推荐
- STM32移植Littlevgl(LVGL)V8.0.2使用文件系统+BMP解码显示外部FLASH中图片
说明:选择BMP解码图片的方式,是因为此方式不需要占用太多的RAM 一.主要参数及版本 MCU:STM32F103ZET6 LCD:2.8寸ILI9341,使用FSMC驱动 SPI FLASH:W25 ...
- MCUXpresso开发NXP RT1060(3)——移植LVGL到NXP RT1060
目录 开发环境 目录 一.开发环境 二.准备工作 三.移植步骤 1.修改lv_conf.h 2.显示功能移植 3.触摸功能移植 4.tick及timer 四.结果展示 五.参考资料 一.开发环境 1. ...
- 乐鑫ESP32移植LVGL 7.10
零. 声明 本专栏文章我们会以连载的方式持续更新,本专栏计划更新内容如下: 第一篇:ESP-IDF基本介绍,主要会涉及模组,芯片,开发板的介绍,环境搭建,程序编译下载,启动流程等一些基本的操作,让你对 ...
- LVGL 8.0 lv_demo_widgets的学习
LVGL 8.0 lv_demo_widgets的学习 出于喜欢 LVGL这个轻量级的Gui框架,所以打算进行学习.但是我在墨水屏设备上移植不成功,所以打算直接使用模拟器进行学习.接下来开始介绍我自己 ...
- STM32移植LVGL(LittleVGL)
STM32移植LVGL(LittleVGL) 一.什么是LVGL https://lvgl.io/ 这是LVGL的官网, http://lvgl.100ask.org/8.2/intro/index. ...
- STM32移植LVGL+旋转编码器接口对接
写在前面:本菜鸟结合了许多大佬的文章,成功实现了基于LVGL的GUI设计,小开心~浅浅记录一下!~ 本文以单片机STM32F103VET6为核心,利用ST7796芯片驱动分辨率为480*320的LCD ...
- 【LVGL】学习笔记--(1)Keil中嵌入式系统移植LVGL
一 LVGL简介 最近emwin用的比较烦躁,同时被LVGL酷炫的界面吸引到了,所以准备换用LVGL试试水. LVGL(轻量级和通用图形库)是一个免费和开源的图形库,它提供了创建嵌入式GUI所需的一切 ...
- TFT-LCD移植LVGL详细过程记录
TFT-LCD移植LVGL LVGL(轻量级和通用图形库)是一个免费和开源的图形库,它提供了创建嵌入式GUI所需的一切,具有易于使用的图形元素,美丽的视觉效果和低内存占用. LVGL更多介绍:http ...
- KLite 移植说明 V1.0
2019独角兽企业重金招聘Python工程师标准>>> KLite 移植说明 V1.0 KLite是一个"简洁易用"的嵌入式操作系统微内核 目前支持Cortex- ...
最新文章
- 【TensorFlow2.0】(1) tensor数据类型,类型转换
- asp.net性能的技巧
- 2.1 DNS服务介绍和安装
- python创建变量并赋值_python怎么给变量赋值
- 硅谷公司:我们称他们为软件工程师,而非打工人
- python语言接收信息的内置函数_python接收信息的内置函数是
- 2.1.3 Sorting a Three-Valued Sequence 三值的排序
- 音乐推荐系统协同过滤算法解释
- 福利:appium+selenium+python 模拟手工点击趣头条(app赚钱软件)
- 如何搭建repo管理环境管理多个git仓库
- XTU Oj 128
- 【计算专业】有趣的拓扑学问题 动画演示
- 《Python数据分析与挖掘实战》示例源码免费下载
- php获取搜索框的函数,PHP自定义函数获取搜索引擎来源关键字的方法
- 河北工业大学c语言寻宝游戏,计算机技术基础(c语言)课程设计寻宝游戏.doc
- opencv2.0的移植 OMAP4460 FPU
- python pexpect_Python之pexpect详解
- 在家用c++实现贪吃蛇——c++小游戏
- 开课吧python课件_开课吧:廖雪峰数据分析全栈工程师第8期【视频+课件】-百度云下载...
- numpy-npy 和 npz