TouchGFX之后端通信

在大多数应用中,UI需以某种方式连接到系统的其余部分,并发送和接收数据。 它可能会与硬件外设(传感器数据、模数转换和串行通信等)或其他软件模块进行交互通讯。

Model类

所有TouchGFX应用都有Model类,Model类除了存储UI状态信息,还可用作面向周围系统的接口。 这里周围系统我们指的是在你整个系统中用到的硬件外设以及需要进行通讯的其他任务。 通常来讲,在各自的View类中直接访问其他软件模块或者硬件外设并不是个好的设计。

Model类非常适合放置任何此类接口代码,原因在于:

  1. Model类有 tick() 函数,会在每一帧自动调用,并且可实现用于查找来自其他子模块的事件或对事件作出反应。
  2. Model类有一个指向当前活动Presenter的指针,它能够将传入事件通知给UI。

以下示例为:通过button控件,触发数据发送给系统其他任务;该任务再将数据发回touchgfx任务。

首先程序需要touchgfx以外的一个任务,和两个用来收发数据的队列

然后创建一个button控件,并设置交互为调用虚函数

编写向周围系统发送数据的程序

cpp 复制代码
screenView.hpp


#ifndef SCREENVIEW_HPP
#define SCREENVIEW_HPP

#include <gui_generated/screen_screen/screenViewBase.hpp>
#include <gui/screen_screen/screenPresenter.hpp>

class screenView : public screenViewBase
{
public:
    screenView();
    virtual ~screenView() {}
    virtual void setupScreen();
    virtual void tearDownScreen();
		virtual void function1();
protected:
};

#endif // SCREENVIEW_HPP
cpp 复制代码
screenView.cpp


#include <gui/screen_screen/screenView.hpp>

screenView::screenView()
{

}

void screenView::setupScreen()
{
    screenViewBase::setupScreen();
}

void screenView::tearDownScreen()
{
    screenViewBase::tearDownScreen();
}

void screenView::function1()
{
	presenter->bc();
}
cpp 复制代码
screenPresenter.hpp


#ifndef SCREENPRESENTER_HPP
#define SCREENPRESENTER_HPP

#include <gui/model/ModelListener.hpp>
#include <mvp/Presenter.hpp>

using namespace touchgfx;

class screenView;

class screenPresenter : public touchgfx::Presenter, public ModelListener
{
public:
    screenPresenter(screenView& v);

    /**
     * The activate function is called automatically when this screen is "switched in"
     * (ie. made active). Initialization logic can be placed here.
     */
    virtual void activate();

    /**
     * The deactivate function is called automatically when this screen is "switched out"
     * (ie. made inactive). Teardown functionality can be placed here.
     */
    virtual void deactivate();

    virtual ~screenPresenter() {}

		void bc();

private:
    screenPresenter();

    screenView& view;
};

#endif // SCREENPRESENTER_HPP
cpp 复制代码
screenPresenter.cpp


#include <gui/screen_screen/screenView.hpp>
#include <gui/screen_screen/screenPresenter.hpp>

screenPresenter::screenPresenter(screenView& v)
    : view(v)
{

}

void screenPresenter::activate()
{

}

void screenPresenter::deactivate()
{

}

void screenPresenter::bc()
{
	model->toggleState();
}
cpp 复制代码
Model.hpp


#ifndef MODEL_HPP
#define MODEL_HPP

class ModelListener;

class Model
{
public:
    Model();

    void bind(ModelListener* listener)
    {
        modelListener = listener;
    }

    void tick();
		
		void toggleState();
		
protected:
    ModelListener* modelListener;
		bool state;
};

#endif // MODEL_HPP
cpp 复制代码
Model.cpp


#include <gui/model/Model.hpp>
#include <gui/model/ModelListener.hpp>
#include "../../../../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.h"

#ifndef SIMULATOR

//*******************************************************
//   Define Queue handles
//*******************************************************
extern "C" {
    extern osMessageQueueId_t myQueue01Handle;
    extern osMessageQueueId_t myQueue02Handle;
}
#else
#include <stdio.h>
#endif

Model::Model() : modelListener(0), state(0)
{

}

void Model::tick()
{

}

void Model::toggleState()
{
	state = !state;

#ifndef SIMULATOR
    uint16_t msg = state;

    if (myQueue01Handle)
    {
        osMessageQueuePut(myQueue01Handle, &msg, 0, 0);
    }
#endif
}
cpp 复制代码
freertos.c


void StartDefaultTask(void *argument)
{
  /* USER CODE BEGIN StartDefaultTask */
	uint16_t msg = 0;
  /* Infinite loop */
  for(;;)
  {
        if (osMessageQueueGet(myQueue01Handle, &msg, 0U, 1000) == osOK)
        {

        }
  }
  /* USER CODE END StartDefaultTask */
}

编写向UI发送数据的程序

cpp 复制代码
freertos.c


void StartDefaultTask(void *argument)
{
  /* USER CODE BEGIN StartDefaultTask */
	uint16_t msg = 0;
	uint16_t color;
  /* Infinite loop */
  for(;;)
  {
        if (osMessageQueueGet(myQueue01Handle, &msg, 0U, 1000) == osOK)
        {
					if(msg)
						color = 0x0000;
					else
						color = 0xFFFF;
					osMessageQueuePut(myQueue02Handle, &color, 0U, 0);
        }
  }
  /* USER CODE END StartDefaultTask */
}
cpp 复制代码
Model.hpp


#ifndef MODEL_HPP
#define MODEL_HPP

class ModelListener;

class Model
{
public:
    Model();

    void bind(ModelListener* listener)
    {
        modelListener = listener;
    }

    void tick();
		
		void toggleState();
		void setboxColor(unsigned short color);
protected:
    ModelListener* modelListener;
		bool state;
};

#endif // MODEL_HPP
cpp 复制代码
Model.cpp


#include <gui/model/Model.hpp>
#include <gui/model/ModelListener.hpp>
#include "../../../../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS_V2/cmsis_os2.h"

#ifndef SIMULATOR

//*******************************************************
//   Define Queue handles
//*******************************************************
extern "C" {
    extern osMessageQueueId_t myQueue01Handle;
    extern osMessageQueueId_t myQueue02Handle;
}
#else
#include <stdio.h>
#endif

Model::Model() : modelListener(0), state(0)
{

}

void Model::tick()
{
#ifndef SIMULATOR

    //*******************************************************
    //
    //  HANDLE MESSAGES
    //
    //  Check for messages from backend, with zero timeout to
    //  avoid blocking the UI.
    //
    //*******************************************************
    //

    uint16_t msg = 0;
    if (osMessageQueueGet(myQueue02Handle, &msg, 0U, 0) == osOK)
    {
			setboxColor(msg);
    }

#endif
}

void Model::toggleState()
{
	state = !state;

#ifndef SIMULATOR
    uint16_t msg = state;

    if (myQueue01Handle)
    {
        osMessageQueuePut(myQueue01Handle, &msg, 0, 0);
    }
#endif
}

void Model::setboxColor(unsigned short color)
{
    modelListener->setboxColor(color);
}
cpp 复制代码
#ifndef MODELLISTENER_HPP
#define MODELLISTENER_HPP

#include <gui/model/Model.hpp>

class ModelListener
{
public:
    ModelListener() : model(0) {}
    
    virtual ~ModelListener() {}

    void bind(Model* m)
    {
        model = m;
    }
		
		virtual void setboxColor(unsigned short color) {}
protected:
    Model* model;
};

#endif // MODELLISTENER_HPP
cpp 复制代码
#ifndef SCREENPRESENTER_HPP
#define SCREENPRESENTER_HPP

#include <gui/model/ModelListener.hpp>
#include <mvp/Presenter.hpp>

using namespace touchgfx;

class screenView;

class screenPresenter : public touchgfx::Presenter, public ModelListener
{
public:
    screenPresenter(screenView& v);

    /**
     * The activate function is called automatically when this screen is "switched in"
     * (ie. made active). Initialization logic can be placed here.
     */
    virtual void activate();

    /**
     * The deactivate function is called automatically when this screen is "switched out"
     * (ie. made inactive). Teardown functionality can be placed here.
     */
    virtual void deactivate();

    virtual ~screenPresenter() {}

		void bc();
		virtual void setboxColor(unsigned short color);
private:
    screenPresenter();

    screenView& view;
};

#endif // SCREENPRESENTER_HPP
cpp 复制代码
#include <gui/screen_screen/screenView.hpp>
#include <gui/screen_screen/screenPresenter.hpp>

screenPresenter::screenPresenter(screenView& v)
    : view(v)
{

}

void screenPresenter::activate()
{

}

void screenPresenter::deactivate()
{

}

void screenPresenter::bc()
{
	model->toggleState();
}

void screenPresenter::setboxColor(unsigned short color)
{
	view.setbox1Color(color);
}
cpp 复制代码
#ifndef SCREENVIEW_HPP
#define SCREENVIEW_HPP

#include <gui_generated/screen_screen/screenViewBase.hpp>
#include <gui/screen_screen/screenPresenter.hpp>

class screenView : public screenViewBase
{
public:
    screenView();
    virtual ~screenView() {}
    virtual void setupScreen();
    virtual void tearDownScreen();
		virtual void function1();
		void setbox1Color(unsigned short color);
protected:
};

#endif // SCREENVIEW_HPP
cpp 复制代码
#include <gui/screen_screen/screenView.hpp>

screenView::screenView()
{

}

void screenView::setupScreen()
{
    screenViewBase::setupScreen();
}

void screenView::tearDownScreen()
{
    screenViewBase::tearDownScreen();
}

void screenView::function1()
{
	presenter->bc();
}

void screenView::setbox1Color(unsigned short color)
{
	box1.setColor(color);
	box1.invalidate();
}

烧录进开发板,现象(点击按钮,box颜色在黑白之间切换)

相关推荐
代码游侠5 天前
STM32开发——基础外设
linux·运维·arm开发·stm32·单片机·嵌入式硬件·学习
代码游侠6 天前
Linux驱动复习——驱动
linux·运维·arm开发·笔记·学习
古译汉书6 天前
【IoT死磕系列】Day 6:工业控制底层大动脉—CAN总线
linux·网络·arm开发·单片机·物联网·tcp/ip
姜太公钓鲸2336 天前
STM32是ST公司基于ARM Cortex-M内核开发的32位微控制器。上述文字中的内核是什么意思?作用是什么?
arm开发·stm32·嵌入式硬件
日更嵌入式的打工仔6 天前
FIQ 与 IRQ
arm开发·笔记
The️7 天前
STM32-FreeRTOS操作系统-软件定时器
arm开发·stm32·单片机·嵌入式硬件·mcu·c#
szxinmai主板定制专家7 天前
RK3588 8个USB工控解决方案,适用于机器视觉,工业互联等
arm开发·人工智能·fpga开发
我在人间贩卖青春7 天前
ARM编程模型
arm开发·arm工作模式
安全二次方security²7 天前
【CVE-2025-0647】ARM CPU漏洞安全通告
arm开发·安全·cve-2025-0647·tlbi·cpp rctx 指令·c1-ultra·虚拟化漏洞
道亦无名8 天前
armBitRevIndexTable1024
arm开发