lvgl 双物理显示器的驱动实现
目录
- 一、背景 - 1. 要实现的功能
- 2. lvgl 版本
 
- 二、简单粗暴的方式 - 理论上可以这样实现
- 缺陷:
 
- 三、lvgl 自身机制支持 - 3.1 实现思路
- 3.2 初始化缓冲区和注册显示驱动 - 3.2.1 复制lv_port_disp → lv_port_disp_2
- 3.2.2 修改 lv_port_disp_2 文件
- 3.2.3 在应用层调用显示器2初始化程序
 
- 3.3 如何切换显示器 - 3.3.1 切换显示器的 API
- 3.3.2 如何找到显示器指针
- 3.3.3 接收显示器指针 - 定义保存显示器1 指针的变量
- 接收显示器1 指针
- 提供 API 供上层访问
 
- 3.3.4 另外一种返回显示器指针的实现方式 - 返回显示器1指针
- 返回显示器2 指针
 
- 3.3.5 应用层切换显示器实现 - 选择显示器1
- 选择显示器2
 
 
 
- 四、参考链接
一、背景
1. 要实现的功能
一个mcu 物理连接两块彩屏,使用一个lvgl内核实现对双显示器的显示驱动。
2. lvgl 版本
V8.3.x
二、简单粗暴的方式
理论上可以这样实现
- 软件应用层将两款显示器虚拟成一整块显示器。显示器的宽度就是最宽那个显示器的宽度,显示的长度是显示器1 + 显示器2 的长度。
- 在刷屏打点函数中(disp_flush),根据坐标进行判断,属于显示器1 范围的数据,写到物理显示器1;属于显示器2范围的数据,写到物理显示器2。
缺陷:
- 可能存在边界数据处理异常问题;
- 对lvgl 来说,屏幕宽度和高度是虚拟的。如果想实现参考屏幕本身对齐的功能,比较难实现。
- 在软件编码实现UI时,需要将显示坐标转换成虚拟坐标。不够直观。例如要实现分别在两块显示器的(0,0) 坐标开始位置写数据。写显示器1时,可以写(0,0) 坐标;写显示2时,需要写(0,LCD_SCR1_Y_MAX);
三、lvgl 自身机制支持
3.1 实现思路
- 为每一个显示器分配并初始化一个缓冲区;
- 为每一个显示器注册显示驱动;
- 每次更新显示内容前,先选中当前的显示器
3.2 初始化缓冲区和注册显示驱动
3.2.1 复制lv_port_disp → lv_port_disp_2
显示缓冲区初始化和显示器注册的处理部分都在 lv_port_disp.c 文件中;复制一份 lv_port_disp.c (lv_port_disp.h)文件,改名为 lv_port_disp_2.c ( lv_port_disp_2.h )负责显示器2的初始化。
3.2.2 修改 lv_port_disp_2 文件
- 更正显示器2的x,y 坐标范围
- 将每一个可能因此重定义的变量或函数重命名。例如 - lv_port_disp_init → lv_port_disp_init_2
 
3.2.3 在应用层调用显示器2初始化程序
在调用 lv_port_disp_init() 后面,调用 lv_port_disp_init_2()
3.3 如何切换显示器
3.3.1 切换显示器的 API
完成上面步骤之后,就已经完成了显示器缓冲区分配,显示驱动注册。
通过阅读官方帮助文档,我们知道 lv_disp_set_default(disp)  用来切换当前的默认显示器。
void lv_disp_set_default(lv_disp_t * disp)
{disp_def = disp;
}
参数 disp 就是要设置的显示器指针。
3.3.2 如何找到显示器指针
大致看了一遍相关的源码文件,没看到直接返回显示器1,显示器2的相关接口函数。重新研究了一遍注册显示器的过程,发现 lv_disp_drv_register 注册显示驱动函数,会返回当前注册的显示器指针。这个函数在lv_port_disp.c 文件中调用。
由于默认只有一个显示器,所以默认也没接收这个函数的返回值,记录为当前显示器指针。
lv_disp_t * lv_disp_drv_register(lv_disp_drv_t * driver)
3.3.3 接收显示器指针
以显示器1 为例说明。以下代码都是在 lv_port_disp.c 文件中实现。
定义保存显示器1 指针的变量
static lv_disp_t *_local_lv_disp_1;
接收显示器1 指针
_local_lv_disp_1 =  lv_disp_drv_register( &disp_drv );
提供 API 供上层访问
lv_disp_t *lv_port_get_screen_1( void )
{return _local_lv_disp_1;
}
3.3.4 另外一种返回显示器指针的实现方式
查看lv_disp_drv_register 函数,发现函数的第一行实现如下:
lv_disp_t * disp = _lv_ll_ins_head(&LV_GC_ROOT(_lv_disp_ll));
插入一个 接节点到列表LV_GC_ROOT(_lv_disp_ll) 的头部,并返回新插入的节点的指针。列表 LV_GC_ROOT(_lv_disp_ll) 就是物理显示器列表。
那么,我们遍历整个 LV_GC_ROOT(_lv_disp_ll) 列表,就能依次返回物理显示器的指针。由于应用层先注册显示器1,所以显示器1的指针位于队列尾。
返回显示器1指针
lv_disp_t *lv_port_get_screen_1( void )
{return _lv_ll_get_tail( &LV_GC_ROOT( _lv_disp_ll ) );}
返回显示器2 指针
lv_disp_t *lv_port_get_screen_2( void )
{return _lv_ll_get_head( &LV_GC_ROOT( _lv_disp_ll ) );
}
3.3.5 应用层切换显示器实现
选择显示器1
lv_disp_set_default(lv_port_get_screen_1());
选择显示器2
lv_disp_set_default(lv_port_get_screen_2());
四、参考链接
- LVGL Displays :https://docs.lvgl.io/8.3/overview/display.html
相关文章:
lvgl 双物理显示器的驱动实现
目录 一、背景 1. 要实现的功能2. lvgl 版本 二、简单粗暴的方式 理论上可以这样实现缺陷: 三、lvgl 自身机制支持 3.1 实现思路3.2 初始化缓冲区和注册显示驱动 3.2.1 复制lv_port_disp → lv_port_disp_23.2.2 修改 lv_port_disp_2 文件3.2.3 在应用层调用显示器…...
 
论文阅读——X-Decoder
Generalized Decoding for Pixel, Image, and Language Towards a Generalized Multi-Modal Foundation Model 1、概述 X-Decoder没有为视觉和VL任务开发统一的接口,而是建立了一个通用的解码范式,该范式可以通过采用共同的(例如语义&#…...
 
【Kubernetes】控制器Statefulset
Statefulset控制器 一、概念二、Statefulset资源清单文件编写技巧2.1、查看定义Statefulset资源需要的字段2.2、查看statefulset.spec字段如何定义2.3、查看statefulset的spec.template字段如何定义 三、Statefulset使用案例:部署web站点3.1、编写一个Statefulset资…...
 
智能优化算法应用:基于鱼鹰算法3D无线传感器网络(WSN)覆盖优化 - 附代码
智能优化算法应用:基于鱼鹰算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用:基于鱼鹰算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.鱼鹰算法4.实验参数设定5.算法结果6.参考文献7.MA…...
探索 Vue3 (五) 骨架屏
骨架屏是页面的一个空白版本,通常会在页面完全渲染之前,通过一些灰色的区块大致勾勒出轮廓,待数据加载完成后,再替换成真实的内容。 目前主流 UI库 都有骨架屏,如 Element-UI、Antd 可以看到使用起来非常简单&#x…...
java取出list中的某几个属性组成一个新的集合的几种方式
我用了三种方式,1:forEach循环;2:for循环;3:stream方法 package org.springblade.test;import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.stream.Collectors;public class Test {org.junit.jupiter.api…...
 
开源自托管导航页配置服务Dashy本地搭建结合内网穿透远程访问
开源自托管导航页配置服务Dashy本地搭建结合内网穿透远程访问 简介1. 安装Dashy2. 安装cpolar3.配置公网访问地址4. 固定域名访问 简介 Dashy 是一个开源的自托管的导航页配置服务,具有易于使用的可视化编辑器、状态检查、小工具和主题等功能。你可以将自己常用的一…...
 
Cloudstack多个管理服务器节点
https://docs.cloudstack.apache.org/en/4.18.0.0/adminguide/reliability.html 参考翻译: 代理上支持多个管理服务器 在具有多个管理服务器的Cloudstack环境中,可以根据算法配置代理,将其连接到哪个管理服务器。这对于内部负载均衡器或高可…...
 
31. Ajax
简介 AJAX 是 Asynchronous JavaScript And XML 的简称。直译为,异步的JS和XML。AJAX的实际意义是,不发生页面跳转、异步载入内容并改写页面内容的技术。AJAX也可以简单的理解为通过JS向服务器发送请求。 AJAX这门技术很早就被发明,但是直到…...
ArrayList源码学习笔记(3)
时隔两年,重新读ArrayList源码,轻松了很多,以问题的方式记录一下收获 装饰器模式 注释中提到ArrayList本身不是线程安全的,注释如下: * <p><strong>Note that this implementation is not synchronized.&…...
flutter怎么对ReorderableListView中的用于排序的控制手柄进行显示或隐藏
我在使用ReorderableListView创建可排序列表的时候,需要在编辑的时候才显示右侧的控制排序的手柄。研究了半天,配合搜索引擎,才找到正确的方案。 答案很简单,就是在它的属性当中有一个叫做:buildDefaultDragHandles的…...
python 1200例——【9】斐波那契数列
文章目录 定义求解方法1. 递归方法2. 循环方法3. 动态规划方法4. 矩阵方法总结:定义 斐波那契数列(Fibonacci sequence)是一个在自然世界中经常出现的数学序列。它是由0和1开始,然后的每个数字都是前两个数字的和。因此,斐波那契数列的前几个数字是:0, 1, 1, 2, 3, 5, 8…...
 
JavaScript读写T5557卡源码
本示例使用发卡器: https://item.taobao.com/item.htm?spma1z10.5-c-s.w4002-21818769070.13.48ce6f89XlQ9Vf&id675212889085 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-t…...
 
【数据结构】LRU缓存的简单模拟实现(leetcode力扣146LRU缓存)
文章目录 一、定义二、LRU模拟实现二、代码实现 一、定义 LRU是Least Recently Used的缩写,意思是最近最少使用,它是一种Cache替换算法。 Cache的容量有限,因此当Cache的容量用完后,而又有新的内容需要添加进来时, 就…...
 
基于电商场景的高并发RocketMQ实战-Commitlog基于内存的高并发写入优化、基于JVM offheap的内存读写分离机制
🌈🌈🌈🌈🌈🌈🌈🌈 【11来了】文章导读地址:点击查看文章导读! 🍁🍁🍁🍁🍁🍁dz…...
 
工具系列:TensorFlow决策森林_(3)使用dtreeviz可视化
文章目录 介绍设置安装 TF-DF 和 dtreeviz导入库 可视化分类树加载、清洗和准备数据分割训练/测试集并训练模型训练一个随机森林分类器显示决策树检查叶节点统计信息决策树如何对实例进行分类特征空间划分 可视化回归树加载、清洗和准备数据分割训练/测试集并训练模型训练一个随…...
 
【算法学习】斐波那契数列模型-动态规划
前言 我在算法学习过程中,针对斐波那契数列模型的动态规划的例题进行了一个整理,并且根据标准且可靠一点的动态规划解题思路进行求解类似的动归问题,来达到学习和今后复习的必要。 所谓的斐波那契数列模型,即当前状态的值等于前两…...
 
ES的安装和RestClient的操作
目录 初识elasticsearch 什么是elasticsearch elasticsearch的发展 Lucene的优缺点 elasticsearch的优势 倒排索引 es与mysql的概念对比 文档 索引 概念对比 架构 安装es 安装kibana 安装ik分词器 分词器 安装ik分词器 ik分词器的拓展和停用词典 操作索引库…...
访问者模式(Visitor)
访问者模式(Visitor Pattern)是一种将算法与对象结构分离的行为型设计模式。这种模式主要用于对一个由许多不同类型的对象构成的复杂对象结构(如组合结构)进行操作,而不需要对这些对象的类进行修改。 访问者模式涉及以下几个角色: 访问者(Visitor):为每一个具体元素类…...
 
ATTCK红队评估一
一、环境搭建 主机 ip地址 win7外网服务器(两张网卡) 外网:192.168.92.135 内网:192.168.52.143 server2003域成员主机 内网:192.168.52.141 server2008域空主机 内网:192.168.52.138 kali攻击机 …...
 
DIY|Mac 搭建 ESP-IDF 开发环境及编译小智 AI
前一阵子在百度 AI 开发者大会上,看到基于小智 AI DIY 玩具的演示,感觉有点意思,想着自己也来试试。 如果只是想烧录现成的固件,乐鑫官方除了提供了 Windows 版本的 Flash 下载工具 之外,还提供了基于网页版的 ESP LA…...
linux 下常用变更-8
1、删除普通用户 查询用户初始UID和GIDls -l /home/ ###家目录中查看UID cat /etc/group ###此文件查看GID删除用户1.编辑文件 /etc/passwd 找到对应的行,YW343:x:0:0::/home/YW343:/bin/bash 2.将标红的位置修改为用户对应初始UID和GID: YW3…...
unix/linux,sudo,其发展历程详细时间线、由来、历史背景
sudo 的诞生和演化,本身就是一部 Unix/Linux 系统管理哲学变迁的微缩史。来,让我们拨开时间的迷雾,一同探寻 sudo 那波澜壮阔(也颇为实用主义)的发展历程。 历史背景:su的时代与困境 ( 20 世纪 70 年代 - 80 年代初) 在 sudo 出现之前,Unix 系统管理员和需要特权操作的…...
 
【Oracle】分区表
个人主页:Guiat 归属专栏:Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...
 
Python 实现 Web 静态服务器(HTTP 协议)
目录 一、在本地启动 HTTP 服务器1. Windows 下安装 node.js1)下载安装包2)配置环境变量3)安装镜像4)node.js 的常用命令 2. 安装 http-server 服务3. 使用 http-server 开启服务1)使用 http-server2)详解 …...
探索Selenium:自动化测试的神奇钥匙
目录 一、Selenium 是什么1.1 定义与概念1.2 发展历程1.3 功能概述 二、Selenium 工作原理剖析2.1 架构组成2.2 工作流程2.3 通信机制 三、Selenium 的优势3.1 跨浏览器与平台支持3.2 丰富的语言支持3.3 强大的社区支持 四、Selenium 的应用场景4.1 Web 应用自动化测试4.2 数据…...
 
uniapp 小程序 学习(一)
利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 :开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置,将微信开发者工具放入到Hbuilder中, 打开后出现 如下 bug 解…...
vue3 daterange正则踩坑
<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...
 
CSS3相关知识点
CSS3相关知识点 CSS3私有前缀私有前缀私有前缀存在的意义常见浏览器的私有前缀 CSS3基本语法CSS3 新增长度单位CSS3 新增颜色设置方式CSS3 新增选择器CSS3 新增盒模型相关属性box-sizing 怪异盒模型resize调整盒子大小box-shadow 盒子阴影opacity 不透明度 CSS3 新增背景属性ba…...
AWS vs 阿里云:功能、服务与性能对比指南
在云计算领域,Amazon Web Services (AWS) 和阿里云 (Alibaba Cloud) 是全球领先的提供商,各自在功能范围、服务生态系统、性能表现和适用场景上具有独特优势。基于提供的引用[1]-[5],我将从功能、服务和性能三个方面进行结构化对比分析&#…...
