基于MCU平台的HMI开发的性能优化与实战(上)

随着汽车座舱智能化的不断演进,车内显示设备的数量显著增加,从传统的仪表盘和中控屏扩展至空调控制、扶手、副驾驶区域以及抬头显示(HUD)等多样化的显示单元。为了有效支持这些功能单元,同时控制整车成本,越来越多的汽车制造商开始采用微控制器单元(MCU)芯片。MCU以其低功耗、高集成度和经济性,成为降低成本的优选方案。

但由于平台的计算能力和存储空间受限,如何有效利用有限的资源来实现功能丰富、页面切换平滑的HMI应用变得至关重要。资源是否被合理的使用将直接影响应用的性能和用户体验。如果计算能力或存储空间使用不当,程序可能在PC上运行流畅,但在MCU上会遇到卡顿甚至崩溃的情况,无法满足设计目标。为应对此挑战,专为资源受限设备量身定制的工具——Qt for MCUs应运而生。凭借其极小内存占用和高度优化的库,Qt for MCUs旨在为MCU和低端MPU提供高性能HMI应用程序开发工具。采用Qt for MCUs在MCU平台上可以获得极佳的开发体验以及更好性能的HMI应用。

Qt for MCUs极大地减轻了开发人员在移植和调优方面的成本,但在资源受限的MCU平台上,性能优化始终是一项不可回避的挑战。

本文将基于Qt for MCUs工具,探讨如何通过精简代码、提升运行效率以及优化内存和资源管理等策略,来提高MCU平台下的HMI开发效率和应用性能。

一、降低代码量

减少代码量不仅能够降低程序对存储空间的需求,还能简化程序结构,使代码更加清晰。这有助于系统承载更多功能,同时还可以避免因内存不足导致的系统崩溃。简化的代码逻辑减少了CPU的分支判断,从而减轻了处理器的负担。此外,减少的运行时间还能降低能耗,并且有助于编译器更有效地优化代码,生成更高效的机器码。

在Qt for MCUs平台,我们推荐从以下三个方面对代码量进行优化:

1、减少锚点的使用

锚点是一种布局方式,用于将一个元素相对于另一个元素进行定位。

通过设置元素的anchors属性,可以将元素的边缘与其父元素或其他元素的边缘对齐。锚点可以在不同大小的屏幕上自适应,并且可以根据不同的屏幕方向进行动态调整。每个项目都可以被认为有一组 6 条不可见的“锚线”:

左 | 水平中心 | 右 | 顶部 | 垂直中心 | 底部

使用锚点进行开发虽然提供了布局的灵活性,但过度依赖它们可能会带来一些弊端。特别是在界面尺寸固定的情况下,锚点的动态计算过程不仅增加了代码的复杂度,还会带来不必要的性能开销。

通过直接指定坐标位置来替代部分锚点,可以简化代码结构,降低代码行数,从而提高代码的可读性和可维护性。

让我们通过一个简单的图形示例来比较 锚点定位 和 绝对定位 两种实现方式的不同。

下表左侧代码为绝对布局实现方式,右侧代码是锚点布局实现方式

import QtQuick

Item {

    id: root

    width: 500

    height: 200

    Rectangle {

        id: rect

        x: 50

        y: 50

        width: 200

        height: 100

        color: "#ED8E00"

    }

}

import QtQuick

Item {

    id: root

    width: 500

    height: 200

    Rectangle {

        id: rect

        anchors.left: parent.left

        anchors.top: parent.top

        anchors.leftMargin: 50

        anchors.topMargin: 50

        width: 200

        height: 100

        color: "#ED8E00"

    }

}

对比可以看出锚点布局的实现方式相较于绝对布局方式代码行数要多,且从代码逻辑上看,计算逻辑要更为复杂。

  1. 使用Repeater     

Repeater是Qt for MCUs提供的一个自动重复的功能组件。通过使用Repeater可以方便的创建多个相似的控件,而无需手动编写重复的布局和逻辑代码。这不仅可以减少代码量,还可以提高界面的一致性和可维护性。

import QtQuick

Item {

    .........

    //Column布局矩形元素竖向排列

    Column {

        spacing: 10 // 列元素之间的间距为10

        Repeater { // 用于重复生成元素

            model: 3 // 模型为3,生成三个矩形

            //delegate 定义了每个重复元素的模板,这里每个元素都是矩形

            delegate: Rectangle {

                id: rect

                width: 100

                height: 100

                color: getColor(index) // 使用预定义的函数获取矩形填充颜色

            }

        }

}

..........

}

通过上图的例子可以看出,创建三个矩形,我们可以通过将编辑好的矩形样式应用到Repeater内的组件中来实现,无需三次重复编写矩形控件代码和使用布局来设置它们的位置。同时还可以通过函数调用的方式为每个矩形设置不同的属性。这种方法不仅减少了代码量,还提高了代码的可维护性。

3、增加可复用组件

在UI界面开发中,经常会遇到默认的组件样式无法完全满足设计需求的情况。为了解决这一问题,我们可以将基础组件进行样式定制,以满足特定的设计要求。然后,将这些定制的组件封装到一个独立的文件中,创建为自定义组件。这样,我们就可以像使用官方组件一样,通过几行简单的代码来调用这些封装好的自定义组件。这种方法不仅提高了代码的复用性,减少了冗余,也提升了整体的代码质量,如下图所示。

除了提取重复使用的组件样式代码外,我们还可以通过将多处出现的逻辑代码抽取并封装到单独的文件中,实现代码的集中管理和统一维护。

二、提高运行效率

提升运行效率能够显著加快系统的响应速度,从而增强用户的使用体验。我们可以通过以下四种策略来提高运行效率:

1、减少动态绑定依赖次数

如图所示,当属性与其他属性绑定并形成依赖关系时,若属性值发生变化,依赖属性会被标记为“脏”状态。随后,系统会触发并处理所有标记为“脏”的事件,确保依赖属性能够及时更新其值。这种动态更新机制虽然有效,但其复杂的依赖管理和事件处理过程可能会导致性能下降。通过减少不必要的动态绑定和依赖次数,我们可以降低属性刷新的频率,进而提升系统的运行效率。

2、修改控件源代码

修改Qt for MCUs的控件源代码,可以暴露更多的控制接口,从而能够更直接地操作控件的属性和行为,减少中间层的开销,提高运行效率。

3、错峰加载与预加载

Loader是Qt for MCUs中用于加载UI资源的组件。修改Loader的加载策略可以有效平衡性能消耗,减少资源加载期间的卡顿现象。

错峰加载策略:分散资源或任务的加载时间

系统启动时可能会因资源争用而遇到性能下降或崩溃的问题。通过实施错峰加载机制,我们不是同时加载和初始化所有模块或任务,而是按计划的顺序和时间间隔分批进行。这种方法可以缓解启动时的资源竞争和高负载,确保系统的平稳运行。

预加载策略:提前加载资源或执行任务

提前加载资源

预加载策略指的是在页面实际显示给用户之前,就预先加载未显示的页面。这样做可以防止在页面加载过程中出现空白屏幕,从而提升用户体验。

为了实现系统性能的优化和用户体验的提升,我们需要根据具体状况,选择最合适的加载策略。

4、局部数据刷新

全局数据刷新会触发整个界面的重绘,造成不必要的性能损耗。通过改进刷新策略,采用局部配置数据刷新代替全局刷新,可以只更新界面中需要变化的部分,减少不必要的渲染工作,从而提高运行效率。

全局刷新

局部刷新

如上图所示,当数据发生变化时,首先进行数据对比,有数据变化的部分重新加载刷新数据,无数据变化的部分保持不变,无需再次加载,减少了渲染操作,提高了运行效率。

三、内存管理

高效的内存管理对于提升HMI的应用性能和稳定性至关重要。它有助于减少内存碎片、加快访问速度、降低分配成本、防止内存泄漏,并优化内存使用。在资源受限的MCU环境中,可以确保HMI应用的流畅运行。我们提供三种关键的内存管理策略,旨在优化内存使用。

1、单例模式

单例模式是一种设计模式,它保证一个类在整个应用中只有一个实例,并且提供了一个统一的访问点。这种模式通过一个特定的类来实现,这个类负责自己的实例化,并且保证只实例化一次。它允许我们直接访问这个唯一的实例,无需通过常规的实例化过程。这有助于降低系统复杂性,提高性能,并节省宝贵的资源。

2、内部申请机制

我们采用统一且预定义的内存管理机制,有效预防出现内存泄漏、碎片化和过度分配等问题。

上图展示了FreeRTOS中pvPortMalloc的内存分配流程,这是FreeRTOS为动态内存分配特别设计的函数,与标准C库中的函数类似,但专为FreeRTOS的任务调度和内存管理机制优化。FreeRTOS提供了五种内存管理方案:

  1. heap_1:最基础的实现,不支持内存释放。
  2. heap_2:支持内存释放,采用简单的连续内存分配算法,可能产生内存碎片。
  3. heap_3:使用标准库的malloc()和free()函数,依赖于标准库的实现。
  4. heap_4:提供最佳平衡,采用首次适应算法,并通过合并空闲块减少碎片化。
  5. heap_5:最灵活,支持多个独立堆区域,适合复杂内存管理场景。

开发者可以根据设备条件和需求选择最合适的内存管理方案。

3、内存池技术

内存碎片是嵌入式系统中普遍存在的问题,尤其是在频繁申请和释放小块内存时更为明显。内存池技术通过预先分配一定数量的小块内存,并在程序运行期间循环使用这些内存块来解决这一问题。需要内存时,直接从内存池中获取;不再需要时,则将其返还给内存池,而不是释放回系统。这种方法减少了内存的频繁分配与释放,有效防止了内存碎片的产生。此外,内存池还有助于优化内存对齐,进一步提升内存的使用效率。

如上图所示,程序启动时,我们预先分配一定数量的固定大小内存块。在申请内存时,直接从这些预分配的块中获取;释放内存时,则将其放回预分配的块中,以便再次使用。每个内存池针对特定的使用场景设计,与传统的malloc/free相比,它减少了复杂的逻辑处理,可以显著提高性能。

四、资源管理

资源管理的核心在于优化图片资源的性能,我们采用以下三种策略来应对系统对图片资源的各种需求,目的是不影响用户体验的前提下,降低图片存储的开销。

1、BorderImage

BorderImage属性允许在用户界面中绘制可伸缩的边框图像,非常适合创建大小可变且边缘不失真的UI元素,例如按钮、面板和背景。当处理图像内容简单(如纯色图片)时,BorderImage可以替代传统的Image属性。它能够无损放大图像边缘,防止拉伸时的失真,同时减少了存储空间中不必要的像素数据。在某些特殊场景下,这种方法几乎可以避免图像质量损失,具体效果如下方图示。

2、ColorizedImage

ColorizedImage组件用于展示图片并应用颜色遮罩,能够将指定颜色应用于原始图像,从而生成具有不同色彩效果的图像。当面对内容相同但颜色各异的大量图像时,ColorizedImage提供了一种高效的解决方案:只需存储一张基础图片并进行动态上色,这样可以大幅减少因颜色不同而需存储的多张图片所占用的存储资源。然而,这种方法在执行效率上可能略低于直接使用Image,因此更适合于小型图标以及显示数量较少的场景,具体效果可以参考以下图示。

3、降低图片编码渲染格式

Qt for MCUs针对图片资源提供了多种格式选项,允许开发者根据不同场景和图片特性选择最合适的格式,以优化存储效率。每种图片格式都有其特点和占用空间大小,合理选择格式有助于在图片资源的存储优化和MCU的计算能力之间找到最佳平衡点。

图像格式

格式描述

清晰度描述

像素占用

ARGB8888

拥有透明度、红、绿、蓝四个通道,每个通道占用8位

可最大化保证图片质量和原图一致

32

ARGB4444

拥有透明度、红、绿、蓝四个通道,每个通道占用4

将会损失绝大部分的色彩细节,在复杂图像肉眼可明显感受到失真

16

RGB888

拥有红、绿、蓝三个通道,每个通道占用8位

可最大化保证图片质量和原图一致,但无法实现显示透明像素的效果

24

RGB565

拥有红、绿、蓝三个通道,其中,红色和蓝色通道占用5位,绿色通道占用6

可在图像质量和图像大小之间取得较好的平衡,对于复杂色彩的图像可能失真,但肉眼感知不明显

16

RGB444

拥有红、绿、蓝三个通道,每个通道占用4位

将会损失绝大部分的色彩细节,在复杂图像肉眼可明显感受到失真且无法显示透明像素效果

12

通过在合适的场景下使用适合的图片存储格式可平衡显示效果和存储、加载的空间占用,如下图所示,上方图片为在RGB444下的显示效果,下方图片为在RGB888下的显示效果,在色彩丰富的情况下可明显看出两者的区别,但同大小图RGB888的存储占用是RGB444的2倍,但在图像颜色简单的情况下者区别肉眼 

本文深入探讨了使用Qt for MCUs进行HMI应用开发时,通过优化代码、提升运行效率、管理内存以及合理使用资源来提高应用性能的策略。这些优化措施使开发者能够在资源有限的MCU平台上构建高效且功能丰富的HMI应用,确保用户获得流畅、稳定的操作体验。随着技术的不断发展,我们将探索和分享更多的优化方法,进一步提升MCU平台上的HMI应用性能。

下一章,我们将结合实际案例,深入开展Qt for MCUs的实战演练,通过具体示例详细讲解HMI开发过程中的各项优化策略的应用及其效果,帮助开发者全面掌握通过Qt for MCUs来进行HMI开发的实战开发技巧。

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

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

相关文章

手机在网状态-手机在网状态查询-手机在网站状态接口

查询手机号在网状态,返回正常使用、停机、未启用/在网但不可用、不在网(销号/未启用/异常)、预销户等多种状态 直连三大运营商,实时更新,可查询实时在网状态 高准确率-实时更新,准确率99.99% 接口地址&…

54.Python-web框架-Django-免费模板django-datta-able

1.Datta Able Django介绍 Detta Able Djiango是什么 Datta Able Django 是一个由AppSeed提供的开源Django管理面板,基于现代设计,为开发者提供了一流的功能和优雅的界面。它源自CodedThemes的高风格化Bootstrap 4模板——Datta Able Bootstrap Lite&…

python-基础篇-文件和异常

文章目录 文件和异常读写文本文件读写二进制文件读写JSON文件 文件和异常 实际开发中常常会遇到对数据进行持久化操作的场景,而实现数据持久化最直接简单的方式就是将数据保存到文件中。说到“文件”这个词,可能需要先科普一下关于文件系统的知识&#…

什么是快乐?

什么是快乐? What is Happiness? 1. 快乐不是追求外在的物质,而是内心的平静与满足。当我们学会感恩,懂得珍惜眼前的一切,心中自然会充满喜悦。快乐并非来自拥有更多,而是感受到已经拥有的足够。每一天都怀抱感激之情…

qt如何在linux平台上设置编译生成windows程序文件,跨平台?

在开始前刚好我有一些资料,是我根据网友给的问题精心整理了一份「qt的资料从专业入门到高级教程」, 点个关注在评论区回复“888”之后私信回复“888”,全部无偿共享给大家!!!QT本来目标就是跨平台&#xf…

Commons-Collections篇-CC4链分析

前言 因为 CommonsCollections4 除 4.0 的其他版本去掉了 InvokerTransformer 继承 Serializable,导致该方法无法序列化。 同时 CommonsCollections 4的版本 TransformingComparator 继承了 Serializable接口,而CommonsCollections 3里是没有的&#xf…

hrm人力管理系统源码(从招聘到薪酬的全过程人力管控系统)

一、项目介绍 一款全源码可二开,可基于云部署、私有部署的企业级数字化人力资源管理系统,涵盖了招聘、人事、考勤、绩效、社保、酬薪六大模块,解决了从人事招聘到酬薪计算的全周期人力资源管理,符合当下大中小型企业组织架构管理运…

Stringboot

一、概述 springboot是spring家族中的一个全新框架,用来简化spring程序的创建和开发过程。在以往我们通过SpringMVCSpringMybatis框架进行开发的时候,我们需要配置web.xml,spring配置,mybatis配置,然后整合在一起&…

django.db.utils.NotSupportedError: MySQL 8 or later is required (found 5.7.33).

django.db.utils.NotSupportedError: MySQL 8 or later is required (found 5.7.33). 一、原因分析 在新版的Django默认需要MySQL 8或更高版本,才能运行。 二、解决办法 1、升级mysql数据库版本 只需要将mysql版本升级到8.0,即可解决,当然这…

基于esp8266_点灯blinker_智能家居

文章目录 一 实现思路1 项目简介2 项目构成3 代码实现4 外壳部分 二 效果展示UI图片 一 实现思路 摘要:esp8266,mixly,点灯blinker,物联网,智能家居,3donecut 1 项目简介 1 项目效果 通过手机blinker app…

宝藏速成秘籍(3)选择排序法

一、前言 1.1、概念 选择排序法(Selection Sort)是一种简单直观的排序算法。它的基本思想是:每次从待排序的数组中选择最小(或最大)的元素,将其放在已排序部分的末尾,直到所有元素都排序完毕。…

Unet心电信号分割方法(Pytorch)

心血管疾病是一种常见病,严重影响人们的健康及日常生活。 近年来随着人们生活习惯的不断变化,心血管疾病对人们影响愈加明显,发病率呈现出逐年攀升的趋势,心血管疾病是中国城乡居民死亡的首要原因。心电图ECG已被广泛用于研究心跳…

光学雨量监测站:科技赋能,精准监测降水过程

TH-YJ3随着科技的不断进步,光学雨量监测站作为一种先进的降水监测设备,正逐渐在气象、水文、农业等领域发挥重要作用。光学雨量监测站以其高精度、高可靠性、实时性强的特点,为降水数据的收集和分析提供了强有力的支持,为相关领域…

Nginx负载均衡之长连接负载均衡

当客户端通过浏览器访问 HTTP 服务器时,HTTP 请求会通过 TCP 协议与 HTTP 服务器建立一条访问通道,当本次访问数据传输完毕后,该 TCP 连接会立即被断开,由于这个连接存在的时间很短,所以 HTTP 连接也被称为短连接。 …

Lua实现自定义函数面向对象编程

本文目录 1、引言2、原理3、实例4、层析验证 文章对应视频教程: 暂无,可以关注我的B站账号等待更新。 点击图片或链接访问我的B站主页~~~ 1、引言 在现代软件开发中,面向对象编程(OOP)已经成为一种广泛使用的编程范式…

俄罗斯Yandex推广投放如何开户?Yandex广告开户和代运营推广流程详解_俄罗斯_受众_搜索引擎

在俄罗斯进行Yandex广告推广是一种有效的在线营销方式,特别是针对俄罗斯市场。Yandex是俄罗斯最受欢迎的搜索引擎,类似于Google在全球范围内的地位。以下是通过Yandex广告推广的一般步骤,以及如何通过上海上弦进行广告开户和代运营。 1. Yan…

怎么图片转excel表格?推荐三个方法

怎么图片转excel表格?在信息化高速发展的今天,图片转Excel表格的需求日益凸显,尤其是在职场办公中,这一需求更是显得尤为迫切。为了满足广大用户的需求,市面上涌现出了众多图片转Excel的软件。今天,就为大家…

Git 基础操作(一)

Git 基础操作 配置Git 安装完Git后,首先要做的事情是设置你的 用户名 和 e-mail 地址。这样在你向仓库提交代码的时候,就知道是谁提交的,以及提交人的联系方式。 配置用户名和邮箱 使用git config [--global] user.name "你的名字&qu…

Windows如何找回永久删除的文件?完整教程看完即会!

可以找回永久删除的文件? 你是否也在Windows 10中永久删除过文件?什么是永久删除?通常有5种方法可以永久删除文件: 正常删除文件,然后在回收站中再次删除。使用命令提示符:“del”删除文件。使用“ShiftD…

RS485和CAN电路中的TVS管选择

在RS485和CAN电路设计中,经常要考虑“静电和浪涌保护”,怎么选择TVS管,很少有人讲解。 1、先了解TVS管 TVS管有单向管和双向管,通常后缀为CA的是双向TVS管,只有字母A的是单向TVS管。见下图: 2、TVS选择依…