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颜色在黑白之间切换)

相关推荐
陌夏微秋1 小时前
51单片机基础02 动态数码管显示-并串转换
arm开发·单片机·嵌入式硬件·51单片机·硬件工程·信息与通信·信号处理
烬奇小云1 天前
使用 unicorn 和 capstone 库来模拟 ARM Thumb 指令的执行,并实现多个钩子(hook)来监控代码执行、系统调用和内存读写操作(二)
java·arm开发·python
CYRUS STUDIO2 天前
Android 下内联汇编,Android Studio 汇编开发
android·汇编·arm开发·android studio·arm
艾格北峰2 天前
STM32 BootLoader 刷新项目 (九) 跳转指定地址-命令0x55
arm开发·stm32·单片机·嵌入式硬件
橘色的喵3 天前
嵌入式ARM平台Linux网络实时性能优化
linux·网络·arm开发·性能优化·实时·内核优化
荣世蓥4 天前
2.ARM_ARM是什么
arm开发
憧憬一下4 天前
Linux 内核中断描述符 (irq_desc) 的初始化与动态分配机制详解
arm开发·嵌入式硬件·嵌入式·c/c++·linux驱动开发
亿道电子4 天前
【ARM】MDK-E203 Undefined identifier
arm开发·stm32·单片机·arm
ShuQiHere4 天前
【ShuQiHere】️计算机架构:x86 与 ARM 指令集架构的对比与发展
arm开发·架构
CYRUS STUDIO4 天前
Android下的系统调用 (syscall),内联汇编syscall
android·linux·汇编·arm开发·arm·内联汇编