C

开发应用后端 (RH850)

本主题指导您通过 GHS MULTI IDE 的步骤来创建和构建应用程序的后端,后端使应用程序的 UI 能够与平台通信,并从硬件中获取所需信息。在这种情况下,设备接口获取板上用户按钮的状态。以下图表描述了两个组件之间的交互

导出应用程序和平台源代码

本节提供了逐步说明,指导您如何使用 Qt for MCUs 工具从 QmlProject 创建 GHS MULTI IDE 项目,包括导出的应用程序和平台源代码。

  1. 创建包含以下命令的批处理脚本,该命令调用 qmlprojectexporter 以生成 GHS Multi IDE 项目
    set QUL_ROOT=C:\path\to\QtMCUs\2.8.0
    set QMLPROJECT_FILE=C:\path\to\YourProject.qmlproject
    set BOARDDEFAULTS=%QUL_ROOT%\platform\boards\renesas\rh850-d1m1a-baremetal\cmake\BoardDefaults_32bpp.qmlprojectconfig
    set RGL_DIR=C:\path\to\rgl_ghs_D1Mx_obj_V2.1.0a
    set PROJECT_DIR=C:\path\to\PROJECT_DIR
    
    %QUL_ROOT%\bin\qmlprojectexporter.exe %QMLPROJECT_FILE% --platform=rh850-d1m1a-baremetal --toolchain=GHS --boarddefaults=%BOARDDEFAULTS% --outdir=%PROJECT_DIR% --project-type=ghs --include-ide-generated-hw-code --board-sdk=%RGL_DIR%

    运行脚本之前,请确保以下变量已设置

    • RGL_DIR 设置为 Renesas 图形库 (RGL) 2.1.0a 的安装路径,
    • QUL_ROOTQMLPROJECT_FILE
    • PROJECT_DIR 设置为您想要放置 GHS 项目文件的输出目录。

    现在,从命令提示符运行脚本以生成以下内容

    • 从 QML 生成的 C++ 源文件位于 %PROJECT_DIR%/QtMCUs/generated
    • %PROJECT_DIR%/QtMCUs/platform 中的导出平台源代码
    • 包含子项目文件的顶层项目文件,位于 %PROJECT_DIR%/GHS 中。

    生成的 GHS 项目包括以下内容

    • %PROJECT_DIR%/GHS/project.gpj:顶层项目文件。
    • %PROJECT_DIR%/GHS/prj/program.gpj:程序编译定义、包含目录、编译器和链接器选项。
    • %PROJECT_DIR%/GHS/prj/drivers.gpj:RGL 源代码列表。
    • %PROJECT_DIR%/GHS/prj/QtMCUs/qul_platform.gpj:RH850-D1M1A 平台源代码列表。
    • %PROJECT_DIR%/GHS/prj/QtMCUs/qul_app.gpj:从 qmlproject 导出生成的源代码列表。
    • %PROJECT_DIR%/GHS/prj/QtMCUs/qul_module_<ModuleName>.gpj:每个模块的一个子项目,包括为相应的 QmlProject 模块生成的源代码。
    • %PROJECT_DIR%/GHS/prj/application.gpj:一个方便的空子项目,用于应用程序,您将在下一部分中进行编辑。
    • %PROJECT_DIR%/GHS/mcu_<YourProject>_qul_workspace.gmb:一个包含一些便利命令的工作空间。有关详细信息,请参阅 GHS Multi IDE QUL 工作空间
    • %PROJECT_DIR%/GHS/qul_probe_E1.con:包含连接到 E1 探针的元数据。
    • %PROJECT_DIR%/GHS/qul_probe_E2.con:包含连接到E2探头的元数据。

更多信息,请参阅导出具有平台源代码的Qt for MCUs项目

在GHS MULTI IDE中构建应用程序

以下说明将引导您完成构建应用程序所需的GHS项目调整步骤

  1. 启动GHS MULTI启动器(mstart.exe
  2. 选择文件 > 从文件加载工作区... 并切换到上一节中导出的 %PROJECT_DIR%/GHS。选择工作区文件 mcu_<YourProject>_qul_workspace.gmb
  3. 在工作区中双击项目管理器条目,将项目在项目管理器中打开。
  4. 在任何目录中创建一个新的名为 main.cpp 的文件。该目录将被称为 BACKEND_DIR
    #include "YourProject.h"
    
    #include <qul/application.h>
    #include <qul/qul.h>
    
    int main()
    {
        Qul::initHardware();
        Qul::initPlatform();
        Qul::Application app;
        static YourProject item;
        app.setRootItem(&item);
        app.exec();
        return 0;
    }

    这包含应用程序的默认入口点。您将在此入口点中添加额外的配置步骤以使用LED和用户按钮。有关更多信息,请参阅在应用程序中运行Qt Quick Ultralite。请确保使用与前面章节中选择的相同项目名称(YourProject)。

  5. 右键点击 application.gpj 并选择 编辑。用以下内容替换其内容。
    #!gbuild
    
    macro APPLICATION_EXPORT_DIR=C:/path/to/PROJECT_DIR/QtMCUs/generated
    macro BACKEND_DIR=C:/path/to/BACKEND_DIR
    
    [Subproject]
        -DQUL_STD_STRING_SUPPORT
        -I${APPLICATION_EXPORT_DIR}
    
    # ----- backend -----
    ${BACKEND_DIR}/main.cpp

    确保将 APPLICATION_EXPORT_DIR 宏设置为您导出的UI源代码所在的目录,并将 BACKEND_DIR 宏设置为包含 main.cpp 和您之前创建的后端源代码的目录。

    注意: .gpj 项目文件中缩进很重要。确保每行的开头没有空白,包括源文件。有关更多信息,请参阅 MULTI IDE 文档。

  6. 应用程序二进制名称默认为 application.elf。要使用不同的名称,在 program.gpj 项目文件中将 -o application.elf 更改为 -o YourProject.elf
  7. 至此,为了验证前面的步骤是否正确执行,您可以将部分实现的应用程序构建并烧录到RH850板上,以在目标硬件上运行它。

    在烧录之前,请确保板子连接到目标板和电脑。有关更多信息,请参阅将Renesas RH850连接到探头

    连接建立后,您可以使用GHS MULTI IDE将应用程序烧录到板上,并利用IDE中的调试功能进行调试。

在下文中,您将添加低级逻辑,以通过用户按钮使UI和硬件之间交互。

开发C++后端

以下说明将引导您完成为应用程序开发C++后端的过程

  1. 创建新的C++源文件和头文件,分别命名为 deviceinterface.cppdeviceinterface.h。将这些文件保存在您刚刚创建的 BACKEND_DIR 目录中。
  2. deviceinterface.h 的内容替换如下
    #ifndef DEVICEINTERFACE_H
    #define DEVICEINTERFACE_H
    
    #include <qul/signal.h>
    #include <qul/singleton.h>
    #include <qul/eventqueue.h>
    
    typedef int HWButtonEvent;
    
    class DeviceInterface : public Qul::Singleton<DeviceInterface>, public Qul::EventQueue<HWButtonEvent>
    {
    public:
        Qul::Signal<void(int button)> buttonEvent;
        void onEvent(const HWButtonEvent &inputEvent);
    
        void toggleLED();
    };
    
    #endif //DEVICEINTERFACE_H

    头文件声明了从Qul::SingletonQul::EventQueue继承的DeviceInterface类。它还声明了buttonEvent信号HWButtonEvent事件类型。这允许Singleton对象实例全局可用。它提供了一个C++和QML之间的接口,用于在接收HWButtonEvent输入事件时发出changed信号。有关更多信息,请参阅QML中定义单例从中断处理程序到QML传输数据

  3. 同样,用以下内容替换deviceinterface.cpp的内容
    #include "deviceinterface.h"
    #include "boardutils.h"
    
    void DeviceInterface::onEvent(const HWButtonEvent &inputEvent)
    {
        buttonEvent(inputEvent);
    }
    
    void DeviceInterface::toggleLED()
    {
        BoardUtils::toggleLED();
    }
  4. 创建一个新的C++源文件和头文件对,分别命名为boardutils.cppboardutils.h。将这些文件保存在BACKEND_DIR目录中。
  5. 将以下内容替换到boardutils.h中的代码
    #ifndef BOARDUTILS_H
    #define BOARDUTILS_H
    
    namespace BoardUtils {
    void configure();
    void toggleLED();
    } // namespace BoardUtils
    
    #endif //BOARDUTILS_H
  6. 将针对RH850-D1M1A的BoardUtils::configure()BoardUtils::toggleLED()的特定实现添加到boardutils.cpp
    #include "boardutils.h"
    #include "deviceinterface.h"
    #include "r_typedefs.h"
    #include "r_bsp_hmi_api.h"
    
    #define LED_NR 0
    #define LED_BRIGHTNESS_ON 100u
    #define LED_BRIGHTNESS_OFF 0u
    
    void button_handler()
    {
        DeviceInterface::instance().postEventFromInterrupt(0);
    }
    
    namespace BoardUtils {
    void configure()
    {
        R_BSP_HMI_Init();
        R_BSP_SetButtonCallback(BSP_BTN_CENTER_PRESS, button_handler);
        R_BSP_HMI_SetLed(LED_NR, LED_BRIGHTNESS_OFF);
    }
    
    void toggleLED()
    {
        static bool isOff = true;
        R_BSP_HMI_SetLed(LED_NR, isOff ? LED_BRIGHTNESS_ON : LED_BRIGHTNESS_OFF);
        isOff = !isOff;
    }
    } // namespace BoardUtils

    配置函数调用来自RGL库的用户LED和按钮的BSP特定初始化函数。然后注册button_handler()作为用户按钮事件的中断请求处理程序。中断请求处理程序通过DeviceInterface Singleton对象将低级中断事件传播到QML上下文。

  7. 为了正确配置RH850 LED和按钮,将main.cpp更改为主目录的boardutils.h头文件,并在正常平台初始化后调用BoardUtils::configure()
    #include "boardutils.h"
    ...
    
    int main()
    {
        Qul::initHardware();
        Qul::initPlatform();
        BoardUtils::configure();
        ...
    }
  8. 将新的源文件添加到application.gpj
    #!gbuild
    ...
    
    # ----- backend -----
    ${BACKEND_DIR}/main.cpp
    
    ${BACKEND_DIR}/boardutils.cpp
    ${BACKEND_DIR}/deviceinterface.cpp
  9. 最后,将用于LED和用户按钮交互所需的RGL库源代码添加到application.gpj
    • ${QUL_BOARD_SDK_DIR}/vlib/bsp/board/d1mx_mango/src/hmi/r_bsp_hmi_knob.c
    • ${QUL_BOARD_SDK_DIR}/vlib/bsp/board/d1mx_mango/src/hmi/r_bsp_sys_hmi.c
    • ${QUL_BOARD_SDK_DIR}/vlib/bsp/hmi/src/r_bsp_hmi_main.c

在Design Studio中集成UI和后端

从Qt Design Studio使用DeviceInterface Singleton对象,以访问前面部分中实现的低级后端函数。

  1. 在Qt Design Studio中打开您的项目,并选择连接视图。
  2. 连接选项卡中,选择按钮以添加新连接。

  3. 选择新连接,并使用连接面板跳转到代码视图。

  4. 代码视图中,将第一个连接添加到target,并作为onPressedChanged信号的ActionstatusRect

  5. 代码视图中,将第二个连接添加到target,并将statusRect.pressed = !statusRect.pressed作为onButtonEvent信号的action。

    现在,当您按按钮时,事件会传播到QML上下文,这会更改statusRect.pressed属性。这会导致UI项目的颜色改变。作为对statusRect.pressed属性更改的响应,DeviceInterface.toggleLED()方法切换LED。

  6. 使用文本编辑器更改yourproject.qmlproject以生成生成必要的C++/QML接口,这些接口用于单例对象
    InterfaceFiles {
        files: ["C:/path/to/BACKEND_DIR/deviceinterface.h"]
    }

    BACKEND_DIR路径更改为包含deviceinterface.h文件的目录。

    有关更多信息,请参阅QmlProject 接口文件

在修改用户界面后更新GHS项目

由于您已修改了应用程序的用户界面部分,请再次使用 qmlprojectexporter 导出UI源代码。

使用以下方法之一,使用 --update-project 命令行参数将UI代码的新更改应用到现有的GHS项目中:

  1. 在GHS MULTI启动器的工作空间中,使用预定义的 Sync Qmlproject files 命令。双击UI中的该命令以更新项目文件。
  2. 使用以下批处理脚本手动调用 qmlprojectexporter
    set QUL_ROOT=C:\path\to\QtMCUs\2.8.0
    set QMLPROJECT_FILE=C:\path\to\YourProject.qmlproject
    set PROJECT_DIR=C:\path\to\PROJECT_DIR
    set QMLPROJECT_DIR=%PROJECT_DIR%\QtMCUs\generated
    
    %QUL_ROOT%\bin\qmlprojectexporter.exe %QMLPROJECT_FILE% --update-project=%PROJECT_DIR%/GHS/project.gpj

您的应用程序现在已准备就绪。构建您的GHS MULTI项目并将其编程到RH850板以测试是否一切按预期工作。接下来,您可以尝试添加对其他LED的支持。

在某些Qt许可证下可用。
了解更多信息。