touchgfx -- Integration
将UI连接到系统
在大多数应用程序中,UI需要以某种方式连接到系统的其余部分,并发送和接收数据。这可以与硬件外围设备(传感器数据,A / D转换,串行通信等)接口,也可以与其他软件模块接口。
本文介绍了实现此连接的推荐解决方案。
第一种方法是“快速且肮脏的”方法,主要用于原型制作,而第二种方法是在架构上合理地将UI与现实应用程序中的其余组件连接的一种方法。
在本文的最后,我们链接到使用这两种方法的示例。
模型类
所有TouchGFX应用程序都有一个Model类,该类除了存储UI状态信息之外,还旨在充当您周围系统的接口。这样,我们既指硬件外围设备,也指系统中的其他OS任务。通常,访问各个View类中的其他软件模块或硬件不是一个好的设计。
Model类非常适合放置任何此类接口代码,因为:
- Model类具有tick()函数,该函数会在每帧中自动调用,并且可以实现为查找其他子模块中的事件并对事件做出反应。
- Model类具有指向您当前活动的Presenter的指针,以便能够将传入事件通知UI。
硬件接口
方法1:直接从GUI任务采样
与硬件接口的最佳方法取决于您需要采样的频率,采样的时间和时间的紧迫性。如果您在这些方面的要求比较宽松,那么最简单的方法就是直接在Model::tick功能中对硬件进行采样 。如果采样发生的频率低于帧速率(通常在60Hz左右),则可以添加一个计数器,并且仅在第N个时钟间隔进行一次采样。用这种方法完成后,您的采样操作必须快一些(通常为1ms或更短),否则您的帧速率将开始受到影响,因为采样是在GUI任务的上下文中完成的,并且会延迟绘制帧。
方法2:从辅助任务采样
或者,如果不希望将硬件交互直接放在GUITask的上下文中,则可以创建一个新的OS任务来执行采样。您可以配置此任务以在特定情况下所需的确切时间间隔上运行。另外,根据您的需要,此新任务的优先级可以比GUI任务低或高。如果它具有更高的优先级,那么可以保证它在指定的时间准确运行,而不管GUI任务在做什么。这样做的缺点是,如果这是占用CPU的进程,则可能会影响UI的帧速率。另一方面,如果采样不是时间紧迫的,则可以为任务分配比GUI任务更低的优先级,这样UI帧速率就不会受到硬件采样的影响。
如果您使用辅助任务方法,我们建议您利用RTOS提供的任务间消息传递系统。大多数(如果不是全部)RTOS具有队列/邮件机制,可让您将数据(通常是用户定义的C结构,字节数组或简单整数)从一个任务发送到另一个任务。为了将新数据传递到GUI任务,请为UI tast设置邮箱或消息队列,然后使用此消息传递系统将数据发送到GUI任务。然后,您可以Model::tick轮询GUI任务的邮箱,以检查是否有新数据到达。以防万一,读取数据并相应地更新UI。
将数据传播到UI
无论使用方法1还是方法2,该Model::tick功能都是GUITask知道要在UI中显示的新数据的地方。除了充当与周围系统的接口之外,还记得以前Model该类还负责保存状态数据,因此可能还需要更新一些状态变量。
让我们考虑一个简单的示例,其中将温度传感器连接到系统,并且当前温度将显示在UI中。在准备中,我们将扩展Model类以支持此操作:
Model.hpp:
class Model
{
public:
// Function that allow your presenters to read current temperature.
int getCurrentTemperature() const { return currentTemperature; }
// Called automatically by framework every tick.
void tick();
...
private:
// Variable storing last received temperature;
int currentTemperature;
...
};
通过上述操作,您Presenters 可以向模型询问当前温度,从而允许演示者在进入显示温度的屏幕时在UI(视图)中设置此值。我们现在需要做的是能够在收到新的温度信息时再次更新UI。为此,我们利用了模型具有指向您当前活动的演示者的指针这一事实。该指针的类型是接口(ModelListener),您可以对其进行修改以反映适当的应用程序特定事件:
ModelListener.hpp:
class ModelListener
{
public:
// Call this function to notify that temperature has changed.
// Per default, use an empty implementation so that only those
// Presenters interested in this specific event need to
// override this function.
virtual void notifyTemperatureChanged(int newTemperature) {}
};
现在我们已经连接了该接口,剩下的就是对传入的“新温度”事件进行实际采样了。 Model::tick
Model.cpp
void Model::tick()
{
// Pseudo-code for Method 1 or Method 2. Depends on your concrete Operating System
if (OS_Poll(GuiTaskMBox))
{
// Here we assume that you have defined a "Message" struct containing type and data,
// along with some event definitions.
struct Message msg = OS_Read(GuiTaskMBox);
if (msg.eventType == EVT_TEMP_CHANGED)
{
// We received information that temperature has changed.
// First, update Model state variable
currentTemperature = msg.data;
// Second, notify the currently active presenter that temperature has changed.
// The modelListener pointer points to the currently active presenter.
if (modelListener != 0)
{
modelListener->notifyTemperatureChanged(currentTemperature);
}
}
}
}
上面的方法可以确保两件事:
- currentTemperature变量始终是最新的,以便您的Presenter可以随时获取当前温度。
- 主持人会立即收到有关温度变化的通知,并可以采取适当的措施。
MVP模式的优点之一是,您可以根据当前所处的屏幕来单独处理通知。例如,假设在显示某种与当前温度无关的设置菜单(例如,MainMenuPresenter / MainMenuView处于活动状态)时发生了温度变化事件。
由于notifyTemperatureChanged函数具有默认的空实现,因此MainMenuPresenter完全忽略了此通知。另一方面,如果您有TemperatureControlPresenter,则可以在此演示者中重写notifyTemperatureChanged函数,并通知View它应显示更新的温度:
TemperatureControlPresenter.hpp:
class TemperatureControlPresenter : public ModelListener
{
public:
// override the empty function.
virtual void notifyTemperatureChanged(int newTemperature) {
view.setTemp(newTemperature);
}
};
将数据从UI传输到周围的系统
数据/事件从UI传输到周围系统的相反方向是通过Model进行的,方法大致相同。如果需要添加配置新设定点(目标温度)的功能,则从上一个示例继续进行,我们将在模型中添加以下内容:
Model.hpp:
void setNewTargetTemperature(int newTargetTemp)
{
// Pseudo-code for sending an event to a task responsible for controlling temperature.
struct Message msg;
msg.eventType = EVT_SET_TARGET_TEMP;
msg.data = newTargetTemp;
OS_Send(SystemTaskMBox, &msg);
}
如果用户在UI中设置新的目标温度,则视图可以通知Presenter,该Presenter拥有指向Model对象的指针,因此可以调用该 setNewTargetTemperature函数。
例子
方法1-从GUI任务
下载此链接可找到STM32F746的工作示例,该示例演示如何在Model类中对按钮进行采样并直接控制LED。该示例使用MVP体系结构在两个视图和Model类之间传递值和事件。Model类对按钮进行采样并更新LED以匹配应用程序的状态。
下载此链接可找到STM32F429的工作示例,其中显示了如何对Model类中的按钮进行采样。该示例使用MVP架构将按钮事件传输到视图。
方法2-从其他任务
方法3-从多个任务(4.9.3)
该工作示例已在2018年5月28日举行的TouchGFX网络研讨会“与硬件集成”中进行了演示。
该应用程序是为STM32F769-DISCO板设计的,并与LED和用户按钮交互,以显示如何将C代码和硬件外围设备集成到您的TouchGFX应用程序中。
应用程序以GPIO模式配置按钮。行为是在btntask.c中采样按钮的状态,如果按下按钮,则将消息通过GUI消息队列传递。这使我们可以通过按住按钮来在应用程序中推进动画。
该应用程序使用三个FreeRTOS任务。一个用于GUI,每个用于外围设备(LED和用户按钮)。
方法4-从任务和外部中断线(4.9.3)
该工作示例已在2018年5月28日举行的TouchGFX网络研讨会“与硬件集成”中进行了演示。
该应用程序是为STM32F769-DISCO板设计的,并与LED和用户按钮交互,以显示如何将C代码和硬件外围设备集成到您的TouchGFX应用程序中。
该应用程序将按钮配置为EXTI模式(外部中断线0)。行为是在按下按钮后接收中断,然后清除中断。这不允许与GPIO中的行为相同,但是我们将单步执行动画,因为仅在接收到中断时才通过gui消息队列发送消息。
该应用程序使用两个FreeRTOS任务。一个用于GUI,一个用于LED。(方法3中的Button任务在此应用程序中保持活动状态,以说明外围设备交互代码已移至中断处理程序中)。
【原文】
touchgfx -- Integration的更多相关文章
- 在 Laravel 中使用图片处理库 Integration/Image
系统需求 PHP >= 5.3 Fileinfo Extension GD Library (>=2.0) … or … Imagick PHP extension (>=6.5.7 ...
- 按照Enterprise Integration Pattern搭建服务系统
在前一篇文章中,我们已经对Enterprise Integration Pattern中所包含的各个组成进行了简单地介绍.限于篇幅(20页Word以内),我并没有深入地讨论各个组成.但是如果要真正地按 ...
- Enterprise Integration Pattern - 组成简介
近些年来,越来越多的Web应用正在逐渐向大型化的方向发展.它们通常都会包含一系列相互协作的子服务.在开发过程中,如何让这些子服务协同工作常常是软件开发人员所最为头疼的问题,如各个子服务之间的数据表示不 ...
- Spring 4 + Quartz 2.2.1 Scheduler Integration Example
In this post we will see how to schedule Jobs using Quartz Scheduler with Spring. Spring provides co ...
- OpenCASCADE Gauss Integration
OpenCASCADE Gauss Integration eryar@163.com Abstract. Numerical integration is the approximate compu ...
- MAGENTO - APACHE SOLR INTEGRATION - PART II (SETUP)
MAGENTO - APACHE SOLR INTEGRATION - PART II (SETUP) Tue, 03/01/2011 - 18:30 Tweet Development E-Comm ...
- POSTMAN as debugger for integration APPs
Chrome Menu: Window > Extensions > Postman - REST Client 0.8.4.10 起个标题,有空总结一下一个经验,关于Netsuite i ...
- [转](六)unity4.6Ugui中文教程文档-------概要-UGUI Animation Integration
5.Animation Integration(动画集成) 动画允许控件的所有状态之间相互转换,充分使用unity的动画系统.这是最强大的的转换模式的在处理很多属性的同时可以进行动画. 要使用动画转换 ...
- Informatica相同环境与不同环境的导入导出( Repository Name,Integration Service Name,Folder Name是否相同):
Informatica相同环境与不同环境的导入导出( Repository Name,Integration Service Name,Folder Name是否相同): 1.repository N ...
随机推荐
- 使用 Metrics.net + influxdb + grafana 搭建项目自动化监控和预警方案
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明.本文链接:https://blog.csdn.net/qq_25042791/article/d ...
- css 边框和圆角
CSS3圆角 border-radius属性 一个最多指定四个border -*- radius复合属性,这个属性允许你为元素添加圆角边框 语法 border-radius:1-4 length|% ...
- centos安装软件
rpm指令, 该指令安装文件后缀.rpm的可执行程序 yum指令 安装软件源代码,后缀为 .tar.gz(用gzip压缩过的tar包) rpm rpm软件包格式为 (一)查询系统装已经安装的软件信息 ...
- Milo-OPC UA处理Subscription和Triggering
Subscription有两种模式,一种是Reporting,另一种是Sampling. 如果定义为Sampling,则这个Subscription是一个Triggered Item,即被激发的订阅, ...
- vue项目中event bus的简单使用
之前做的一个vue后台管理系统中,需要实现这样一个功能:从列表页点击新建或编辑进入新建.编辑页面,新建.编辑完成后需要关闭当前的新建和编辑tab,而tab的关闭则是由项目中的tag组件控制的, 新建和 ...
- 【ARM-Linux开发】Linux内存管理:ARM Memory Layout以及mmu配置
原文:Linux内存管理:ARM Memory Layout以及mmu配置 在内核进行page初始化以及mmu配置之前,首先需要知道整个memory map. 1. ARM Memory Layout ...
- 【FFMEPG】windows下编译ffmpeg2.5——使用VS2013,ARMLINUX,ANDORID编译ffmpeg
原文:http://blog.csdn.net/finewind/article/details/42784557 一.准备: 1. 本机环境: win7 64bit: 2. 安装MinGW到C:\M ...
- java SerialPort串口通讯的使用
api文档 http://fazecast.github.io/jSerialComm/javadoc/com/fazecast/jSerialComm/package-summary.html ma ...
- PTA(Basic Level)1020.月饼
月饼是中国人在中秋佳节时吃的一种传统食品,不同地区有许多不同风味的月饼.现给定所有种类月饼的库存量.总售价.以及市场的最大需求量,请你计算可以获得的最大收益是多少. 注意:销售时允许取出一部分库存.样 ...
- idea调试框架时如何能够进入maven依赖包的源码
最近用idea使用spring security做登录与权限控制,在调试过程中碰到问题,经常需要断点追踪源码,深入查看其中问题.但是maven中引用的包,进入后都是.class文件,非源码.导致查看时 ...