0


【开源项目】X-TRACK源码分析

文章目录

processon框架图

X-TRACK阅读笔记

整体架构

APP-HAL-HARDWARE
USER/APP/Common/HAL

下的HAL文件声明HAL的接口,具体实现在

App/HAL/

下或者

Simulator/LVGL.Simulator/HAL/

Main函数

HAL::HAL_Init();lv_Init();APP_Init();// 重点

APP_Init函数

static AppFactory factory;static PageManager manager(&factory);DataProc_Init();
manager.Install("LiveMap","Pages/LiveMap");

在此函数中,有两个重点:一是定义

PageManager

,并对页面进行管理;二是初始化

DataCenter

,实现数据的传递。

理解要点: X-TRACK将

App/Common/DataProc

下的每个

DP_XXX

,以及

App/Pages/

下的每个页面都视为一个Account。(这些Account会在

DataProc_Init()

中被定义,被

DataCenter

所管理)

PageManager框架

在这里插入图片描述

DataCenter框架

在这里插入图片描述

通过

manager.Push("Page/StartUp")

开始页面的调度

PageManager

需要关心的只有几个方法:

manager.Install("xxx")
manager.Push("xxx")// 将xxx入栈到栈顶,实则会显示xxx页面
APP/Utils/PageManager

下实现了

PageManager

,并提供了几个

public

接口,包括页面注册:

Install(会调用Register), Uninstall

;页面调度:

Push, Pop,Replace

,最终都会调用

SwitchTo(PageBase*, bool, PageBase::Stash_t*)

;

SwitchTo()

中会

  1. 调用StateUpdate(_PagePrv), StateUpdate(_PageCurrent)更新页面

PageManager的其它方法不用特别关心,其内部使用了状态机进行页面的切换。我们只需根据

App/Pages/

下的模板

Template

定义我们自己的页面。模板的结构是:

自定义页面

初略的页面框架:

在这里插入图片描述

详细的页面框架:
在这里插入图片描述

实现如下

onViewXXX()

函数:

virtual voidonViewLoad(){}/* Page load start */
virtual voidonViewDidLoad(){}/* Page load end */

virtual voidonViewWillAppear(){}/* Page appear animation start */
virtual voidonViewDidAppear(){}/* Page appear animation end  */

virtual voidonViewWillDisappear(){}/* Page disappear animation start */
virtual voidonViewDidDisappear(){}/* Page disappear animation end */

virtual voidonViewUnload(){}/* Page unload start */
virtual voidonViewDidUnload(){}/* Page unload end */

问题

  1. App/Pages/Dialate/*中的Dialate.*, DialateModel.*, DialteView.*分别有什么用?特别是ModelView
View

应该是创建并管理页面各个

wigdet

的,由

View.Create(lv_ojb_t _root)

可知,

_root

充当该页面的根节点,其它的各个lv组件都是

_root

的子节点,如btn、label等。

Model

是用于获取数据的

  1. 搞懂页面之间的消息传递机制(或者页面的数据怎么从硬件上获取到的?)

每个页面类/对象有一个方法

Update()

,其会更新页面上的各个数据,它会在

onTimerUpdate()

中被调用,又会被

onViewDidAppear()

中被使用(创建一个定时器)

#mermaid-svg-p09A7QnnfJiDNGND {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-p09A7QnnfJiDNGND .error-icon{fill:#552222;}#mermaid-svg-p09A7QnnfJiDNGND .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-p09A7QnnfJiDNGND .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-p09A7QnnfJiDNGND .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-p09A7QnnfJiDNGND .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-p09A7QnnfJiDNGND .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-p09A7QnnfJiDNGND .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-p09A7QnnfJiDNGND .marker{fill:#333333;stroke:#333333;}#mermaid-svg-p09A7QnnfJiDNGND .marker.cross{stroke:#333333;}#mermaid-svg-p09A7QnnfJiDNGND svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-p09A7QnnfJiDNGND .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-p09A7QnnfJiDNGND .cluster-label text{fill:#333;}#mermaid-svg-p09A7QnnfJiDNGND .cluster-label span{color:#333;}#mermaid-svg-p09A7QnnfJiDNGND .label text,#mermaid-svg-p09A7QnnfJiDNGND span{fill:#333;color:#333;}#mermaid-svg-p09A7QnnfJiDNGND .node rect,#mermaid-svg-p09A7QnnfJiDNGND .node circle,#mermaid-svg-p09A7QnnfJiDNGND .node ellipse,#mermaid-svg-p09A7QnnfJiDNGND .node polygon,#mermaid-svg-p09A7QnnfJiDNGND .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-p09A7QnnfJiDNGND .node .label{text-align:center;}#mermaid-svg-p09A7QnnfJiDNGND .node.clickable{cursor:pointer;}#mermaid-svg-p09A7QnnfJiDNGND .arrowheadPath{fill:#333333;}#mermaid-svg-p09A7QnnfJiDNGND .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-p09A7QnnfJiDNGND .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-p09A7QnnfJiDNGND .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-p09A7QnnfJiDNGND .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-p09A7QnnfJiDNGND .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-p09A7QnnfJiDNGND .cluster text{fill:#333;}#mermaid-svg-p09A7QnnfJiDNGND .cluster span{color:#333;}#mermaid-svg-p09A7QnnfJiDNGND div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-p09A7QnnfJiDNGND :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}
three

two

one

lv_timer_del()

onViewWillDisappear()
删除定时器

Update()
最终被调用
更新页面数据

onTimerUpdate()
被周期性调用

onViewDidAppear()
创建定时器

StateUpdate()
利用状态机调用onViewXXX函数

SwitchTo()

manager.Push()

manager.Install()
加载并注册页面

  1. DataProc.cppDataProc_Init()函数内的宏在这里插入图片描述

订阅-发布机制的核心:每个人都有一个账户,有一个代理。每个账户要设置一个事件回调函数

onEvent()

,供

Pull(), Notify()

调用,但会传入不同的事件类型,比如

Account::EVENT_SUB_PULL

Account::EVENT_NOTIFY

数据分发机制有点没懂:相关代码:

DataProc.cpp, DataCenter.*, Account.*

#mermaid-svg-J2dhP1ifP9ZoTjBw {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-J2dhP1ifP9ZoTjBw .error-icon{fill:#552222;}#mermaid-svg-J2dhP1ifP9ZoTjBw .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-J2dhP1ifP9ZoTjBw .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-J2dhP1ifP9ZoTjBw .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-J2dhP1ifP9ZoTjBw .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-J2dhP1ifP9ZoTjBw .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-J2dhP1ifP9ZoTjBw .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-J2dhP1ifP9ZoTjBw .marker{fill:#333333;stroke:#333333;}#mermaid-svg-J2dhP1ifP9ZoTjBw .marker.cross{stroke:#333333;}#mermaid-svg-J2dhP1ifP9ZoTjBw svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-J2dhP1ifP9ZoTjBw .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-J2dhP1ifP9ZoTjBw .cluster-label text{fill:#333;}#mermaid-svg-J2dhP1ifP9ZoTjBw .cluster-label span{color:#333;}#mermaid-svg-J2dhP1ifP9ZoTjBw .label text,#mermaid-svg-J2dhP1ifP9ZoTjBw span{fill:#333;color:#333;}#mermaid-svg-J2dhP1ifP9ZoTjBw .node rect,#mermaid-svg-J2dhP1ifP9ZoTjBw .node circle,#mermaid-svg-J2dhP1ifP9ZoTjBw .node ellipse,#mermaid-svg-J2dhP1ifP9ZoTjBw .node polygon,#mermaid-svg-J2dhP1ifP9ZoTjBw .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-J2dhP1ifP9ZoTjBw .node .label{text-align:center;}#mermaid-svg-J2dhP1ifP9ZoTjBw .node.clickable{cursor:pointer;}#mermaid-svg-J2dhP1ifP9ZoTjBw .arrowheadPath{fill:#333333;}#mermaid-svg-J2dhP1ifP9ZoTjBw .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-J2dhP1ifP9ZoTjBw .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-J2dhP1ifP9ZoTjBw .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-J2dhP1ifP9ZoTjBw .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-J2dhP1ifP9ZoTjBw .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-J2dhP1ifP9ZoTjBw .cluster text{fill:#333;}#mermaid-svg-J2dhP1ifP9ZoTjBw .cluster span{color:#333;}#mermaid-svg-J2dhP1ifP9ZoTjBw div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-J2dhP1ifP9ZoTjBw :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}
成员变量

注册许多accounts到center

center

AccountMain

DataProc_Init()

accounts

AddAccount()
RemoveAccount()
SearchAccount()

Subscirbe()
Commit()
Publish()
Pull()
Notify()

Center
UserData
publishers
subscribers

Account

对象的

Pull(pub,data,size),Notify(pub,data,size)

函数都会调用

pub->priv.eventCallback(pub,para)

而在

App/Common/DataProc/

下的每个

DP_XXX.cpp

都包含一个

account

对象,其会在

DATA_PROC_INIT_DEF(Clock)

中调用

account->SetEventCallback(onEvent)

设置事件回调函数。而在回调函数中,就可以通过判断传入的参数,返回订阅者需要的数据(通过调用HAL层提供的接口)。

此外,

DialplateModel::Init()

中也会创建

account

,并像上面一样,设置回调函数。

页面的分析

以Diplate页面为例

StatusBar

在任何页面都显示,不会被遮挡,因为位于

lv_layer_top()


在这里插入图片描述

Startup页面

在这里插入图片描述

Dilaplate页面

在这里插入图片描述

void DialplateView::Create(lv_obj_t* root)

设计页面的布局,及动画设置

页面的布局

BottomInfo_Create(root);TopInfo_Create(root);BtnCont_Create(root);

动画的设置

核心:成员

lv_anim_timeline_t* anim_timeline;

通过宏定义

ANIM_DEF

定义多个动画:

lv_anim_timeline_wrapper_t

类型

调用

LiveMap页面

在这里插入图片描述

SystemInfos页面

在这里插入图片描述

标签: lvgl 嵌入式 码表

本文转载自: https://blog.csdn.net/weixin_44360592/article/details/126073439
版权归原作者 CofCai 所有, 如有侵权,请联系我们删除。

“【开源项目】X-TRACK源码分析”的评论:

还没有评论