このページでは

C

アプリケーションのバックエンドの開発 (RH850)

このトピックでは、GHS MULTI IDE を使用してアプリケーションのバックエンドを作成およびビルドする手順について説明します。バックエンドにより、アプリケーションの UI はプラットフォームと通信し、ハードウェアから必要な情報を取得できるようになります。この例では、デバイスインターフェースがオンボードのユーザーボタンのステータスを取得します。 次の図は、これら2つのコンポーネント間の相互作用を示しています:

アプリケーションのUIとバックエンド間の連携。

アプリケーションおよびプラットフォームのソースコードのエクスポート

このセクションでは、Qt for MCUs ツールによってエクスポートされたアプリケーションおよびプラットフォームのソースコードをすべて含んだ、QmlProjectからGHS MULTI IDEプロジェクトを作成するための手順を段階的に説明します。

  1. 以下のコマンドを含むバッチスクリプトを作成し、qmlprojectexporter を呼び出してGHS Multi IDEプロジェクトを生成します。
    set QUL_ROOT=C:\path\to\QtMCUs\2.12.2
    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.2.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_DIRRenesas Graphics Library (RGL)2.2.0aのインストールパス、
    • QUL_ROOT QMLPROJECT_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: 各モジュールごとに1つのサブプロジェクトがあり、対応する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 Launcher(mstart.exe )を起動します。
  2. File > Load Workspace from File... 」を選択し、前のセクションでエクスポートした %PROJECT_DIR%/GHS へ移動します。ワークスペースファイル「mcu_<YourProject>_qul_workspace.gmb 」を選択します。
  3. ワークスペース内の「Project Manager 」エントリをダブルクリックし、プロジェクトマネージャーでプロジェクトを開きます。
  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 」を選択して長押しするか、右クリックして「Edit 」を選択します。その内容を以下の内容に置き換えてください。
    #!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.cpp ` および `deviceinterface.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::Singleton ` および `Qul::EventQueue` を継承する `DeviceInterface ` クラスを宣言しています。また、`buttonEvent `、Signal 、および `HWButtonEvent ` イベントタイプも宣言しています。これにより、シングルトンオブジェクトのインスタンスをグローバルに利用できるようになります。これは 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.cpp およびboardutils.h と名付けます。これらのファイルをBACKEND_DIRディレクトリに保存します。
  5. boardutils.h 内のコードを以下の内容に置き換えてください:
    #ifndef BOARDUTILS_H
    #define BOARDUTILS_H
    
    namespace BoardUtils {
    void configure();
    void toggleLED();
    } // namespace BoardUtils
    
    #endif //BOARDUTILS_H
  6. BoardUtils::configure() およびBoardUtils::toggleLED() の RH850-D1M1A 向け実装を、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

    この設定関数は、ユーザー LED およびボタンに対して、RGL ライブラリから BSP 固有の初期化関数を呼び出します。その後、ユーザーボタンイベントの割り込み要求ハンドラとしてbutton_handler() を登録します。この割り込み要求ハンドラは、DeviceInterface シングルトンオブジェクトを使用して、低レベルの割り込みイベントを 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シングルトンオブジェクトを使用して、前のセクションで実装した低レベルのバックエンド関数にアクセスします。

  1. Qt Design Studio でプロジェクトを開き、「Connections 」ビューを選択します。
  2. Connections 」タブ( )にある「さらに 」ボタンを選択し、新しい接続を追加します。

    [接続] タブで新しい接続を追加します。

  3. 新しい接続を選択し、「Connection 」パネル を使用して、「Code 」ビューに移動します。

    「接続」パネルを使用して、「コード」ビューに移動する。

  4. Code 」ビューで、最初の接続 を追加し、「target 」に「statusRect 」を、「onPressedChanged 」信号のアクションに「DeviceInterface.toggleLED() 」を指定します。

    コードビューで最初の接続を追加します。

  5. Code ビューで、2つ目の接続 を追加し、targetDeviceInterface を、onButtonEvent シグナルのアクションにstatusRect.pressed = !statusRect.pressed を指定します。

    コードビューで 2 つ目の接続を追加します。

    これで、ボタンを押すと、イベントが 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 ファイルが含まれているディレクトリに変更してください。

    詳細については、QmlProjectInterfaceFiles を参照してください。

UIに変更を加えた後、GHSプロジェクトを更新してください

アプリケーションの UI 部分に変更を加えたため、qmlprojectexporter を使用して UI ソースを再度エクスポートしてください。

--update-projectコマンドライン引数を使用して、UI コードの新しい変更を既存の GHS プロジェクトに反映させます。以下のいずれかの方法を使用してください。

  1. GHS MULTI Launcherのワークスペース内にある「Sync Qmlproject files 」の下にある定義済みコマンドを使用します。UI上でそれをダブルクリックして、プロジェクトファイルを更新します。
  2. 次のバッチスクリプトを使用して、qmlprojectexporter を手動で実行します:
    set QUL_ROOT=C:\path\to\QtMCUs\2.12.2
    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ライセンスの下で利用可能です。
詳細はこちら。