Melis4.0[D1s]:6.mango-MQ-R基于Melis移植lvgl

news2024/12/28 12:02:24

文章目录

  • 1.下载lvgl源码到《D1s-Melis/ekernel/drivers/hal/test/disp2》目录
    • 1.1 修改Makefile
    • 1.2 快速测试Makefile修改是否有效
  • 2.移植刷新显示内存函数dummy_flush_cb
  • 3.创建一个定时器调用lvgl心跳lv_tick_inc()
  • 4.pack打包出错:
  • 5.设置开机启动
  • 6.源码下载

上一篇文章《Melis4.0[D1s]:5.测试笔记 - 修改显示测试源码》可以通过C代码控制显示,就可以移植lvgl。目前只移植显示部分,没有按键或者触摸输入。

1.下载lvgl源码到《D1s-Melis/ekernel/drivers/hal/test/disp2》目录

我使用的源码是https://github.com/lvgl/lv_port_pc_eclipse,克隆到 《D1s-Melis/ekernel/drivers/hal/test/disp2》 目录。然后在 《D1s-Melis/ekernel/drivers/hal/test/disp2/lv_port_pc_eclipse》 目录下建立一个Makefile,把全部的C文件都包含进来编译的。这是因为lvgl的所有非必要的C文件都可以通过宏定义配置是否编译。例如lv_bmp.c里面的代码是否编译,取决于 宏定义 LV_USE_BMP
在这里插入图片描述
为了简单起见,很多非必要的组件我都没有包含进来,详情见 lv_conf.h(完整内容点击超链接) 。

1.1 修改Makefile

先在《disp2》目录下的Makefile(完整内容点击超链接)把子目录《disp2/lv_port_pc_eclipse》包含进来:

obj-y += lv_port_pc_eclipse/

再将《disp2/lv_port_pc_eclipse》目录下的Makefile(完整内容点击超链接)改为下面内容(节选):

obj-y += lv_main.o

obj-y += \
    lvgl/demos/benchmark/assets/img_benchmark_cogwheel_alpha16.o \
    lvgl/demos/benchmark/assets/img_benchmark_cogwheel_argb.o \
    lvgl/demos/benchmark/assets/img_benchmark_cogwheel_chroma_keyed.o \
    lvgl/demos/benchmark/assets/img_benchmark_cogwheel_indexed16.o \
    lvgl/demos/benchmark/assets/img_benchmark_cogwheel_rgb.o \
    lvgl/demos/benchmark/assets/img_benchmark_cogwheel_rgb565a8.o \
    lvgl/demos/benchmark/assets/lv_font_bechmark_montserrat_12_compr_az.c.o \
    lvgl/demos/benchmark/assets/lv_font_bechmark_montserrat_16_compr_az.c.o \
    lvgl/demos/benchmark/assets/lv_font_bechmark_montserrat_28_compr_az.c.o \
    lvgl/demos/benchmark/lv_demo_benchmark.o \
    ......

1.2 快速测试Makefile修改是否有效

把主函数中和硬件相关的显示,输入等初始化代码屏蔽,main改为lv_main,并把lv_main变成一个命令:

int lv_main(int argc, char **argv)
{
  //(void *)argc; /*Unused*/  //(void)argv; /*Unused*/
  printf("lv_main.");
#if   0
  /*Initialize LVGL*/
  lv_init();

  /*Create a default group for keyboard navigation*/
  lv_group_set_default(lv_group_create());

  /*Initialize the HAL (display, input devices, tick) for LVGL*/
  hal_init();
.....
#endif
  return 0;
}
static lv_disp_t * hal_init(void  )
{
#if 0
    disp_layer_cfg_def();

    static lv_disp_draw_buf_t draw_buf;

    lv_disp_draw_buf_init(&draw_buf, disp_buf1, disp_buf2, HOR_RES * VER_RES);

    static lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);
......   
    lv_disp_drv_register(&disp_drv);
#endif
	lv_disp_t * disp = NULL;
  	return disp;
}
FINSH_FUNCTION_EXPORT_ALIAS(lv_main, lv_main, lv_main );

编译通过,烧录测试。输入help,可以看到lv_main命令,输入lv_main,打印“lv_main”:

msh />help
RT-Thread shell commands:
......
lv_main          - lv_main
......
msh />lv_main
lv_main

2.移植刷新显示内存函数dummy_flush_cb

上一篇文章《Melis4.0[D1s]:5.测试笔记 - 修改显示测试源码》的《2.disp_mem源码阅读》知道,只要往显存地址 mem = g_disp_mm[mem_id].info_base里面填写像素数据,就可以得到我们要显示的内容,把这个地址传给一个全局变量,在lvgl中使用这个全局变量即可。
于是我们在disp_mem源码所在的C文件声明一个全局变量:

uint32_t * g_p_mem_base;

把显存地址传给g_p_mem_base:

g_p_mem_base = g_disp_mm[mem_id].info_base;

在这里插入图片描述
有了这个地址,我们就可以编写自己的显示回调函数:
在这里插入图片描述

#define HOR_RES 800
#define VER_RES 480
extern  uint32_t * g_p_mem_base;
#define line_length 800 * sizeof(rt_uint32_t) / 4
static void dummy_flush_cb(lv_disp_drv_t * disp_drv, const lv_area_t * area, lv_color_t * color_p)
{
    /*Truncate the area to the screen*/
    int32_t act_x1 = area->x1 < 0 ? 0 : area->x1;
    int32_t act_y1 = area->y1 < 0 ? 0 : area->y1;
    int32_t act_x2 =        area->x2 > (int32_t)HOR_RES - 1 ? (int32_t)HOR_RES - 1 : area->x2;
    int32_t act_y2 =        area->y2 > (int32_t)VER_RES - 1 ? (int32_t)VER_RES - 1 : area->y2;

    lv_coord_t w = (act_x2 - act_x1 + 1);

    long int location = 0;

    /* 32 bit per pixel */
    uint32_t *fbp32 = (uint32_t *)g_p_mem_base;
    uint32_t y;
    for (y = act_y1; y <= act_y2; y++)
    {
        location = act_x1 + y * line_length;
        rt_memcpy(&fbp32[location], (uint32_t *)color_p, (act_x2 - act_x1 + 1) * 4);
        color_p += w;
    }   
        
    lv_disp_flush_ready(disp_drv);
}
static lv_color_t disp_buf1[HOR_RES * VER_RES];
static lv_color_t disp_buf2[HOR_RES * VER_RES];
int disp_layer_cfg_def(void);
static lv_disp_t * hal_init(void  )
{
#if 1
    disp_layer_cfg_def();

    static lv_disp_draw_buf_t draw_buf;

    lv_disp_draw_buf_init(&draw_buf, disp_buf1, disp_buf2, HOR_RES * VER_RES);

    static lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);
    disp_drv.draw_buf = &draw_buf;
    disp_drv.flush_cb = dummy_flush_cb;
    disp_drv.hor_res = HOR_RES;
    disp_drv.ver_res = VER_RES;
    lv_disp_drv_register(&disp_drv);
#endif
	lv_disp_t * disp = NULL;
  return disp;
}

再make编译,通过。

3.创建一个定时器调用lvgl心跳lv_tick_inc()

Melis使用rt-thread内核,rt-thread的节拍由宏定义 CONFIG_HZ决定:

#define RT_TICK_PER_SECOND  CONFIG_HZ

CONFIG_HZ通过 命令 make menuconfig 配置:
在这里插入图片描述
这里是200Hz,也就是一个时钟节拍为5ms。

static rt_timer_t timer1;      
//      lv_tick_inc(5);
static lv_disp_t * hal_init(void  )
{
#if 1
    /* 创建定时器1  周期定时器 */
    timer1 = rt_timer_create("timer1", 
    						lv_tick_inc,	//	回调函数
                             5,				//	回调函数的传入参数
                             1,	//	一个时钟节拍调用一次回调函数,具体是5ms
                             RT_TIMER_FLAG_PERIODIC);
    /* 启动定时器1 */
    if (timer1 != RT_NULL)
        rt_timer_start(timer1);

    disp_layer_cfg_def();

......
#endif
	lv_disp_t * disp = NULL;
  return disp;
}

lv_timer_handler()调用间隔是10ms,而lv_tick_inc()调用间隔是5ms,这样比较合理。

4.pack打包出错:

root@SK-JNTINRTMRDZW:/home/book/D1s-Melis-master# pack
INFO: temporarily Enter pack directory: "/home/book/D1s-Melis-master/out/d1s-mq/image", will be back when terminated
INFO: copying config/boot binary/phoenix plugin files
/home/book/D1s-Melis-master/tools/phoenixplugin/Tools.fex
......
......
INFO: running the function do_finish "sys_partition_nor.bin"

partitation file Path=/home/book/D1s-Melis-master/out/d1s-mq/image/sys_partition_nor.bin
mbr_name file Path=/home/book/D1s-Melis-master/out/d1s-mq/image/sunxi_mbr_nor.fex
download_name file Path=/home/book/D1s-Melis-master/out/d1s-mq/image/dlinfo.fex

ERROR: dl file melis_pkg_nor.fex size too large
ERROR: filename = melis_pkg_nor.fex
ERROR: dl_file_size = 2272 sector
ERROR: part_size = 2048 sector
ERROR: update mbr file fail
ERROR: update_mbr failed

《melis_pkg_nor.fex》文件比分配的空间要大,装不下。
修改分区文件《D1s-Melis/projects/d1s-mq/configs/sys_partition_nor.fex》第44,45行:
在这里插入图片描述

;---------------------------------------------------------------------------------------------------------
; 说明: 脚本中的字符串区分大小写,用户可以修改"="后面的数值,但是不要修改前面的字符串
;---------------------------------------------------------------------------------------------------------


;--------------------------------------------------------------------------------------------------
;                                   固件下载参数配置
;--------------------------------------------------------------------------------------------------
;****************************************************
;    mbr的大小, 以Kbyte为单位
;****************************************************
[mbr]
size = 16

;********************************************************************************************************
;                                              分区配置
;
;
;  partition 定义范例:
;    [partition]                ;  //表示是一个分区
;    name        = USERFS2      ; //分区名称
;    size        = 16384        ; //分区大小 单位: 扇区.分区表示个数最多2^31 * 512 = 2T
;    downloadfile = "123.fex"   ; //下载文件的路径和名称,可以使用相对路径,相对是指相对于image.cfg文件所在分区。也可以使用绝对路径
;    keydata     = 1            ; //私有数据分区,重新量产数据将不丢失
;    encrypt     = 1            ; //采用加密方式烧录,将提供数据加密,但损失烧录速度
;    user_type   = ?            ; //私有用法
;    verify      = 1            ; //要求量产完成后校验是否正确
;
; 注:1、name唯一, 不允许同名
;     2、name最大12个字符
;     3、size = 0, 将创建一个无大小的空分区
;     4、为了安全和效率考虑,分区大小最好保证为16M字节的整数倍
;********************************************************************************************************
[partition_start]

;[partition]
;    name         = boot
;    size         = 6656
;    downloadfile = "boot.fex"
;    user_type    = 0x8000

[partition]
    name         = bootA
    ;size         = 2048
    size         = 4096
    downloadfile = "melis_pkg_nor.fex"
    user_type    = 0x8000

;[partition]
;    name         = bootB
;    size         = 6144
;    downloadfile = "melis_pkg_nor.fex"
;    user_type    = 0x8000

;[partition]
;    name         = env
;    size         = 8
;    downloadfile = "env.fex"
;    user_type    = 0x8000

;[partition]
;    name         = env-redund
;    size         = 8
;    downloadfile = "env.fex"
;    user_type    = 0x8000

;rootfs 7616 sector in rootfs.ini make 7616*1024/512=15232 sectors for it.
[partition]
    name         = ROOTFS
    size         = 10240
    ;size         = 20336
    downloadfile = "data_udisk.fex"
    user_type    = 0x8000

[partition]
    name         = UDISK
    ;size = flash size - (boot0 + mbr) size - env - env-redund - ROOTFS
    ;8(or 16) * 1024 * 2 - 64 * 2 - 5632 - 8 - 8 - 10240
    ;size         = 20336
    ;downloadfile = "data_udisk.fex"
    user_type    = 0x8000

再次pack打包成功。烧录运行,输入lv_main命令:

msh />lv_main

在这里插入图片描述

5.设置开机启动

修改《startup.sh》(位于目录 D1s-Melis/projects/d1s-mq/data/UDISK/startup.sh):

echo "Execute startup script begin.............."

#insmod d:\mod\display.mod
#insmod d:\mod\orange.mod
#insmod d:\apps\desktop.mod
lv_main
echo "...............Execute startup script end"

6.源码下载

源码没有startup.shmelis_pkg_nor.fex ,这两个文件的修改比较简单。
源码链接:https://gitee.com/huangweide001/linux-d1-h-test/tree/master/disp2
源码包含了可以直接烧录的img文件 melis_d1s-mq_uart0_8Mnor_lvgl.img

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/425343.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《类和对象》(上)

本文主要对类和对象有一个初步的了解。 文章目录前言1、类的引入和定义2、类的访问限定符及封装2.1 访问限定符2.2 封装3 、类的作用域4 、类的实例化5 、类对象的模型5.1 类对象的大小5.2 类对象存储方式6、this 指针6.1 引子6.2 特性6.3 this指针的一个问题前言 C语言是面向过…

【微信小程序】-- 分包 - 独立分包 分包预下载(四十五)

&#x1f48c; 所属专栏&#xff1a;【微信小程序开发教程】 &#x1f600; 作  者&#xff1a;我是夜阑的狗&#x1f436; &#x1f680; 个人简介&#xff1a;一个正在努力学技术的CV工程师&#xff0c;专注基础和实战分享 &#xff0c;欢迎咨询&#xff01; &…

VRIK+Unity XR Interaction Toolkit 实现VR上半身的追踪(附带VRM模型导入Unity方法和手腕扭曲的解决方法)

文章目录&#x1f4d5;第一步&#xff1a;配置 OpenXR XR Interaction Toolkit 的开发环境&#x1f4d5;第二步&#xff1a;导入人物模型⭐VRM 模型导入 Unity 的方法&#x1f4d5;第三步&#xff1a;配置 VRIK⭐给模型加上 VRIK 组件⭐将模型的头部和手部的位置作为 VR 追踪目…

如何用ChatGPT做设计?激发设计师们的灵感

伴随着人工智能技术的迅猛发展&#xff0c;AI 工具在设计领域中的应用也越来越广泛。 当前&#xff0c;诸如ChatGPT等 AI 工具不仅可以进行自然语言处理&#xff0c;还可以应用于图像、视频等多种媒体领域&#xff0c;为设计师们提供了丰富的应用场景。 使用Chatgpt&#xff1…

开源了,我做了一个基于GPT的桌宠聊天系统:Pet-GPT!

前言 最近chatgpt的热度高居不下。作为一个深度成谜者&#xff0c;发现大部分开发者在调用GPT的时候要不就是基于Tauri做本地窗口外接网页&#xff0c;要不就是web直接展示。在沉思苦想一段时间后&#xff0c;才发现好像没啥什么人用pyqt做啊&#xff1f;特别是没人用桌面宠物…

浏览器:好用的浏览器插件,亲测好用

插件一、CSDN&#xff0c;推荐指数五颗星&#xff0c;强烈推荐 说明&#xff1a;超级好用的浏览器桌面&#xff0c;功能强大&#xff0c;操作简单&#xff0c;效率神器 插件二、AIX智能下载器 说明&#xff1a; 就这么简单的拖放即可实现保存图片&#xff0c;即使观看中的视频…

凌恩生物美文分享|好看又实用,多组学联合分析项目大揭秘!

基因层面的功能潜能有没有真的实现表达&#xff0c;表达量是高是低&#xff1f;下游合成的蛋白质行使了什么样得功能&#xff0c;代谢产物通过体循环到达靶器官&#xff0c;又是如何影响靶器官的工作运行的&#xff1f; 一个完整的生物学故事&#xff0c;中心法则贯穿始终&…

2023十大连锁店进销存软件排名(真实测评)

目前市面上很多连锁店进销存软件的排名都比较主观&#xff0c;结合自己实际工作过程中接触过的软件和在进销存软件多年的经验&#xff0c;给大家整理下2023十大连锁店进销存软件&#xff0c;希望能帮到正在选择连锁店进销存软件的老板&#xff01; 第一名&#xff1a;秦丝连锁联…

机器学习 | 实验三:逻辑回归和牛顿法

⭐ 对应笔记&#xff1a;牛顿法 &#x1f4da;描述 在本练习中&#xff0c;我们将使用牛顿法对分类问题实现逻辑回归。 &#x1f4da;数据 在本练习中&#xff0c;假设一所高中有一个数据集&#xff0c;该数据集表示40名被大学录取的学生和40名未被录取的学生。 每个(x(i),y…

pandas笔记:offset.DateOffset

进行date的偏移 class pandas.tseries.offsets.DateOffset 1 参数说明 n 偏移量表示的时间段数。 如果没有指定时间模式&#xff0c;则默认为n天。 normalize是否将DateOffset偏移的结果向下舍入到前一天午夜**kwds 添加到偏移量的时间参数 年&#xff08;years&#xff09…

软考软件设计师 数据库知识点笔记

概念数据模型 了解即可 结构数据模型 数据库的三级模式结构 外模式对应视图 概念模式对应的是数据库管理系统里面的基本表 内模式对应的是数据库里的一些存储文件 上图可直接背下面概念 两级映像 有内模式跟物理独立性相关&#xff0c;有外模式跟逻辑独立性相关 两级映像其…

MySQL主从复制原理剖析与应用实践

vivo 互联网服务器团队- Shang Yongxing MySQL Replication&#xff08;主从复制&#xff09;是指数据变化可以从一个MySQL Server被复制到另一个或多个MySQL Server上&#xff0c;通过复制的功能&#xff0c;可以在单点服务的基础上扩充数据库的高可用性、可扩展性等。 一、背…

人工智能AI简史

AI人工智能简史 最近学习AI&#xff0c;顺便整理了一份AI人工智能简史&#xff0c;大家参考&#xff1a; 1951年 第一台神经网络机&#xff0c;称为SNARC&#xff1b;1956年 达特茅斯学院会议&#xff0c;正式确立了人工智能的研究领域&#xff1b;1966年 MIT发明ELIZA人机心…

【Java|golang】2409. 统计共同度过的日子数

Alice 和 Bob 计划分别去罗马开会。 给你四个字符串 arriveAlice &#xff0c;leaveAlice &#xff0c;arriveBob 和 leaveBob 。Alice 会在日期 arriveAlice 到 leaveAlice 之间在城市里&#xff08;日期为闭区间&#xff09;&#xff0c;而 Bob 在日期 arriveBob 到 leaveBo…

数字孪生灌区信息化-灌区现代化建设

平台概述 柳林数字孪生灌区信息化平台以物理灌区为单元、时空数据为底座、数学模型为核心、水利知识为驱动&#xff0c;对物理灌区全要素和建设运行全过程进行数字映射、智能模拟、前瞻预演&#xff0c;与物理灌区同步仿真运行、虚实交互、迭代优化&#xff0c;实现对物理灌区…

企业不会用、不敢用AIGC+ 服务怎么办,不妨试一下它?

自从去年ChatGPT上线后,国内外与AIGC相关的话题就一直备受关注。AIGC是指人工智能通用语言模型(Artificial General Language Model),是一种具有极高自然语言理解能力的人工智能模型,其通过大规模语料库训练,能够像人类一样自然地理解和生成语言。ChatGPT正是基于AIGC技术开发的…

数据挖掘(3.1)--频繁项集挖掘方法

目录 1.Apriori算法 Apriori性质 伪代码 apriori算法 apriori-gen(Lk-1)【候选集产生】 has_infrequent_subset(c,Lx-1)【判断候选集元素】 例题 求频繁项集&#xff1a; 对于频繁项集L{B,C,E}&#xff0c;可以得到哪些关联规则&#xff1a; 2.FP-growth算法 FP-tre…

sealos部署k8s集群

使用sealos部署kubernetes集群并实现集群管理 1. 初始环境 官方参考&#xff1a;https://www.sealyun.com/zh-Hans/docs/ 1.1 主机准备 都是静态ip&#xff0c;可上网 主机名主机IP服务器配置k8s-master01192.168.200.1002c4g 40Gk8s-node01192.168.200.1012c4g 40Gk8s-no…

Pytorch实现R-CNN系列目标检测网络

在PyTorch提供的已经训练好的图像目标检测中,均是R-CNN系列的网络&#xff0c;并且针对目标检测和人体关键点检测分别提供了容易调用的方法。针对目标检测的网络&#xff0c;输入图像均要求使用相同的预处理方式&#xff0c;即先将每张图像的像素值预处理到0 &#xff5e;1之间…

Flink 优化 (一) --------- 资源配置调优

目录一、内存设置1. TaskManager 内存模型2. 生产资源配置示例二、合理利用 cpu 资源1. 使用 DefaultResourceCalculator 策略2. 使用 DominantResourceCalculator 策略3 使用 DominantResourceCalculator 策略并指定容器 vcore 数三、并行度设置1. 全局并行度计算2. Source 端…