你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

TouchGFX中Callback模板实现原理

[复制链接]
eefishing 发布时间:2019-10-2 11:52
前言
TouchGFX为MCU带来了炫彩丰富的GUI界面,使得基于STM32芯片的人机界面开发非常方便而友好,比如可以在TouchGFX Designer中创建一个按键,在interaction中给按键添加响应;或者创建多个界面,在界面间进行切换;这些功能由designer帮我们自动生成代码实现了,那与之对应的功能响应代码具体是如何实现的呢?
TouchGFX是用C++编写的,借助C++的模板特性,TouchGFX定义了一组Callback模板,基于此模板来实现上述响应的功能。


Callback模板
在TouchGFX中,Callback模板的描述放在Callback.hpp文件中,在此定义了两组模板:GenericCallback与 Callback模板。


GenericCallback模板组
GenericCallback为Callback模板的模板基类。在GenericCallback模板中,定义了两个接口函数:isValid与execute;其中isValid是来检测Callback是否被初始化过,而execute函数用于调用实际要执行的函数。GenericCallback模板组总共定义了4个模板,模板之间的差别在于execute函数的参数个数不同,4个模板分别对应execute函数带有0个参数,1个参数,2个参数与3个参数。本文中仅列出execute带一个参数的情况。

下面是execute函数带1个参数的GenericCallback模板:
1.jpg

Callback模板组
Callback模板由GenericCallback派生而来。Callback模板组也有4个模板,分别对应于包含不同参数个数execute函数的GenericCallback模板,继承关系如下图:
2.jpg
下面是execute函数带1个参数的Callback模板:
3.jpg
在Callback结构中定义了两个私有的成员指针,pobject为dest_type类型对象的指针,pmemfun_1为dest_type对象的成员函数指针,是指向dest_type类型的成员函数。这样当Callback结构初始化好了以后,再调用execute函数时,就是直接调用了dest_type类型对象的成员函数pmemfun_1。
在使用Callback模板时,根据模板的特性,C++编译器会自动选择最准确的模板匹配,来生成对应的模板类或模板函数。因此在使用Callback模板时,可以使用不同的类型参数个数来匹配使用不同的模板。

Callback模板在TouchGFX中的使用
页面切换 - pendingScreenTransitionCallback
在TouchGFX启动过程中会初始化MVPApplication对象,在MVPApplication类中定义了一个成员pendingScreenTransitionCallback,它是GenericCallback<>*类型的指针,并初始化为0;
TouchGFX会调用handlePendingScreenTransition函数进行页面切换,最终调用evaluatePendingScreenTransition函数,在此函数中会用isValid()函数来检查Callback是否已经初始化;如果初始化了,就调用execute函数 (因为Callback为GenericCallback<>*类型,因此execute函数不带参数) 。
4.jpg
具体的页面切换过程(进入第一个screen):
在TouchGFX初始化过程中,会初始化FrontendApplication对象app,在此对象的基类中包含一个transitionCallback成员,其类型为:
touchgfx::Callback<FrontendApplicationBase> transitionCallback
在进入第一个Screen时,会调用app.gotoScreen1ScreenNoTransition(),在此函数中,会将pendingScreenTransitionCallback设置为指向transitionCallback的指针,最终由TouchGFX框架调用execute函数,执行makeTransition完成页面的切换。

// 初始化FrontendApplicationBase::transitionCallback,transitionCallback的私有成员初始化:
// pobject赋值为this(指向FrontendApplicationBase)
// pmemfun_1赋值为 &FrontendApplication::gotoScreen1ScreenNoTransitionImpl
5.jpg
//execute函数内实际执行的函数(pobject->*pmemfun_1)(),即为如下函数:
6.jpg

按键响应 - flexButtonCallback
在TouchGFX designer中创建一个Flex Button,并设置interaction后,会在MainViewBase类中创建两个私有成员:
//按键响应函数,实现用户的动作响应
void flexButtonCallbackHandler(const touchgfx::AbstractButtonContainer& src)
//Callback对象
touchgfx::Callback<MainViewBase, const touchgfx::AbstractButtonContainer&> flexButtonCallback
以及一个按键成员(在designer中通过Add Style添加了Image与Text属性),例如flexButton1:
touchgfx::TextButtonStyle< touchgfx::ImageButtonStyle< touchgfx::ClickButtonTrigger > > flexButton1;

在MainViewBase的构造函数中,会初始化flexButtonCallback成员,并且调用flexButton1->setAction函数,设置此按键的AbstractButton::action为flexButtonCallback,
MainViewBase::MainViewBase():flexButtonCallback(this, MainViewBase::flexButtonCallbackHandler)

其中:
flexButtonCallback的pobject成员初始化为this(指向MainViewBase的指针)
flexButtonCallback的pmemfun_1成员初始化为&MainViewBase::flexButtonCallbackHandler

由于flexButtonCallback的类型是
struct Callback<dest_type, T1, void, void> : public GenericCallback<T1>

因此flexButtonCallback的execute函数带有一个参数,参数类型为const touchgfx::AbstractButtonContainer&,最终此参数会传递给flexButtonCallbackHandler函数。

在程序运行时,点击按键后,TouchGFX框架会捕获此事件,并在AbstractButton::handleClickEvent函数中调用action->execute(*this)函数,最终即执行了flexButtonCallbackHandler函数,实现了用户的动作响应。

小结
本文介绍了TouchGFX中Callback模板的基本原理,并结合两个例子,简要说明了Callback模板在框架中的使用方法。只要注意Callback的类型、初始化过程,以及最终execute函数执行的函数主体,就能理解Callback模板了,这对深入理解TouchGFX也有一定帮助。

收藏 评论0 发布时间:2019-10-2 11:52

举报

0个回答

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版