このページでは

C

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

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

アプリケーションのUIとバックエンド間のインタラクション。

エクスポート・アプリケーションとプラットフォーム・ソース

Qt for MCUs このセクションでは、QmlProjectからGHS MULTI IDEプロジェクトを作成するためのステップバイステップの手順を説明します。

注: TRAVEO T2G CYT4DNまたはTRAVEO T2G Cluster 4M Lite Kitを使用している場合は、以下の手順でtviic2d4m-baremetal をそれぞれtviic2d6m-baremetal またはtviic2d4mlite-baremetal に置き換えてください。

  1. 以下のコマンドでバッチスクリプトを作成し、qmlprojectexporter を呼び出して GHS Multi IDE プロジェクトを生成します。
    set QUL_ROOT=C:\path\to\QtMCUs\2.12.0
    set QMLPROJECT_FILE=C:\path\to\YourProject.qmlproject
    set BOARDDEFAULTS=%QUL_ROOT%\platform\boards\cypress\tviic2d4m-baremetal\cmake\BoardDefaults_32bpp.qmlprojectconfig
    set GRAPHICS_DRIVER_DIR=C:\path\to\TVII-GraphicsDriver-V2.4.0
    set PROJECT_DIR=C:\path\to\PROJECT_DIR
    
    %QUL_ROOT%\bin\qmlprojectexporter.exe %QMLPROJECT_FILE% --platform=tviic2d4m-baremetal --toolchain=ghs-arm --boarddefaults=%BOARDDEFAULTS% --outdir=%PROJECT_DIR% --project-type=ghs --include-ide-generated-hw-code --board-sdk=%GRAPHICS_DRIVER_DIR%

    スクリプトを実行する前に、以下の変数が設定されていることを確認します:

    • GRAPHICS_DRIVER_DIR をTRAVEO T2G Graphics Driverのインストールパスに設定します、
    • 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:TVII Graphics Driver のソースのリスト。
    • %PROJECT_DIR%/GHS/prj/QtMCUs/qul_platform.gpj:TRAVEO T2G CYT3DLプラットフォームのソースのリスト。
    • %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 Workspaceを参照してください。
    • %PROJECT_DIR%/GHS/qul_flash_jlink.bat:J-Linkプローブを使用してアプリケーションをフラッシュするためのバッチファイル。
    • %PROJECT_DIR%/GHS/qul_flash_miniprog.bat:MiniProg4プローブを使用してアプリケーションをフラッシュするバッチファイル。

詳細については、プラットフォームソースを含む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. この時点で、ここまでの手順が正しく行われていることを確認するために、部分的に実装されたアプリケーションをビルドし、GHS MULTI IDEのワークスペースのショートカットを使用して、プロジェクトのエクスポート中にqmlprojectexporter が生成した有用なバッチファイルを使用してTRAVEO T2Gボードにフラッシュすることができます。

    注意: TRAVEO T2G Cluster 4M Lite (KIT_T2G_C-2D-4M_LITE)プラットフォームポートボードのデフォルトはUSBディスプレイ出力です。詳細はディスプレイ出力(TRAVEO T2G CYT3DL 4M LITE KITおよびCYT4DN 6M LITE KIT)を参照してください。

    バッチファイル(qul_flash_jlink.bat およびqul_flash_miniprog.bat)はメインプロジェクトファイルと同じディレクトリに配置され、J-LinkまたはMiniProg4プローブを使用してアプリケーションをフラッシュするためのコマンドが含まれています。

    プローブに対応するバッチファイルは、GHS MULTI IDEのワークスペースから直接実行できます。

    注: これらのバッチファイルから実行されるコマンドの詳細については、 Infineon ボードのフラッシュ手順を参照してください。

    バッチファイルは、Infineon Auto Flash Utility 1.4 がデフォルトの場所にインストールされているか、そのパスが環境変数INFINEON_AUTO_FLASH_UTILITY_DIR に格納されていることを前提としています。

    また、TRAVEO T2GボードのCM0+コアにブートローダをフラッシュする必要があります。詳細な手順については、「Bootloader Flashing Instructions forInfineon boards」を参照してください。

次のセクションでは、ユーザボタンによるアプリケーション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 SignalHWButtonEvent イベント・タイプも宣言しています。これにより、シングルトンインスタンスをグローバルに利用できるようになります。C++とQMLの間のインターフェイスを提供し、HWButtonEvent 入力イベントを受信すると、変更されたシグナルを発信します。詳しくはQML におけるシングルトンの定義割り込みハンドラから QML へのデータ転送 を参照してください。

  3. 同様に、deviceinterface.cpp の内容を以下のように置き換えてください:
    #include "deviceinterface.h"
    #include "boardutils.h"
    
    #include <platforminterface/log.h>
    
    extern "C" void DeviceInterface_handleButtonEvent()
    {
        DeviceInterface::instance().postEventFromInterrupt(0);
    }
    
    void DeviceInterface::onEvent(const HWButtonEvent &inputEvent)
    {
        buttonEvent(inputEvent);
    }
    
    void DeviceInterface::toggleLED()
    {
        Qul::PlatformInterface::log("Toggling LED\n");
        BoardUtils_toggleLED();
    }
  4. 新しい C ソースファイルとヘッダーファイルを作成し、それぞれboardutils.cboardutils.h という名前にします。これらのファイルをBACKEND_DIRディレクトリに保存します。
  5. boardutils.h のコードを以下のように置き換える:
    #ifndef BOARDUTILS_H
    #define BOARDUTILS_H
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    void BoardUtils_configure();
    void BoardUtils_toggleLED();
    
    #ifdef __cplusplus
    }
    #endif
    
    #endif //BOARDUTILS_H
  6. TRAVEO T2G 固有の実装であるBoardUtils_configure()BoardUtils_toggleLED()boardutils.c に追加する:
    #include "boardutils.h"
    
    #include <stdint.h>
    
    #include <cy_project.h>
    
    #define USER_LED1_PORT CY_USER_LED1_PORT
    #define USER_LED1_PIN CY_USER_LED1_PIN
    #define USER_LED1_PIN_MUX CY_USER_LED1_PIN_MUX
    
    #define USER_BUTTON1_PORT CY_USER_BUTTON_WAKE_PORT
    #define USER_BUTTON1_PIN CY_USER_BUTTON_WAKE_PIN
    #define USER_BUTTON1_PIN_MUX CY_USER_BUTTON_WAKE_PIN_MUX
    #define USER_BUTTON1_IRQN CY_USER_BUTTON_WAKE_IRQN
    
    extern void DeviceInterface_handleButtonEvent();
    
    void ButtonInterruptHandler(void)
    {
        uint32_t interruptStatus = Cy_GPIO_GetInterruptStatusMasked(USER_BUTTON1_PORT, USER_BUTTON1_PIN);
        if (interruptStatus) {
            DeviceInterface_handleButtonEvent();
            Cy_GPIO_ClearInterrupt(USER_BUTTON1_PORT, USER_BUTTON1_PIN);
        }
    }
    
    void BoardUtils_configure()
    {
        // GPIO configuration for LED
        cy_stc_gpio_pin_config_t user_led_port_pin_cfg = {
            .outVal = 0x00,
            .driveMode = CY_GPIO_DM_STRONG_IN_OFF,
            .hsiom = USER_LED1_PIN_MUX,
            .intEdge = 0,
            .intMask = 0,
            .vtrip = 0,
            .slewRate = 0,
            .driveSel = 0,
            .vregEn = 0,
            .ibufMode = 0,
            .vtripSel = 0,
            .vrefSel = 0,
            .vohSel = 0,
        };
    
        Cy_GPIO_Pin_Init(USER_LED1_PORT, USER_LED1_PIN, &user_led_port_pin_cfg);
    
        // GPIO configuration for button
        static cy_stc_gpio_pin_config_t user_button1_port_pin_cfg = {
            .outVal = 0x00,
            .driveMode = CY_GPIO_DM_HIGHZ,
            .hsiom = USER_BUTTON1_PIN_MUX,
            .intEdge = CY_GPIO_INTR_FALLING,
            .intMask = 1,
            .vtrip = 0,
            .slewRate = 0,
            .driveSel = 0,
            .vregEn = 0,
            .ibufMode = 0,
            .vtripSel = 0,
            .vrefSel = 0,
            .vohSel = 0,
        };
    
        Cy_GPIO_Pin_Init(USER_BUTTON1_PORT, USER_BUTTON1_PIN, &user_button1_port_pin_cfg);
    
        // IRQ configuration for button
        cy_stc_sysint_irq_t irq_cfg = {
            .sysIntSrc = USER_BUTTON1_IRQN,
            .intIdx = CPUIntIdx2_IRQn,
            .isEnabled = true,
        };
    
        Cy_SysInt_InitIRQ(&irq_cfg);
        Cy_SysInt_SetSystemIrqVector(irq_cfg.sysIntSrc, ButtonInterruptHandler);
    
        NVIC_SetPriority(CPUIntIdx2_IRQn, 3);
        NVIC_ClearPendingIRQ(CPUIntIdx2_IRQn);
        NVIC_EnableIRQ(CPUIntIdx2_IRQn);
    }
    
    void BoardUtils_toggleLED()
    {
        Cy_GPIO_Inv(USER_LED1_PORT, USER_LED1_PIN);
    }

    configure 関数は LED とボタンピンを初期化します。次に、TRAVEO T2G Graphics DriverのGPIOとIRQ APIを使用して、ユーザボタンイベントの割り込み要求ハンドラとしてButtonInterruptHandler()

    注意: バックエンドロジックを実装した後、ボード上のSW5ハードウェアボタンを押してボタンイベントをトリガします。

  7. TRAVEO T2G 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.c
    ${BACKEND_DIR}/deviceinterface.cpp

Design StudioでUIとバックエンドを統合する

前のセクションで実装した低レベルのバックエンド関数にアクセスするには、Qt Design StudioDeviceInterfaceSingleton オブジェクトを使用します。

  1. Qt Design Studio でプロジェクトを開き、Connections ビューを選択します。
  2. Connections タブプラス ボタンを選択し、新しい接続を追加します。

    コネクションビューで新しいコネクションを追加する。

  3. 新しい接続を選択し、Connection パネル を使用してCode ビューにジャンプします。

    接続パネルを使ってコード・ビューにジャンプする。

  4. Code ビューで、最初の接続 を追加し、statusRecttarget として、DeviceInterface.toggleLED()onPressedChanged シグナルのアクションとして追加します。

    コード・ビューに最初の接続を追加する。

  5. Code ビューで、2番目の接続 を追加し、DeviceInterfacetarget として、statusRect.pressed = !statusRect.pressedonButtonEvent シグナルのアクションとして追加します。

    コード・ビューに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ソースを再度エクスポートします。

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

  1. GHS MULTI LauncherのワークスペースのSync Qmlproject files 。UIでこのコマンドをダブルクリックして、プロジェクトファイルを更新します。
  2. 次のバッチ スクリプトを使用して手動でqmlprojectexporter を呼び出します:
    set QUL_ROOT=C:\path\to\QtMCUs\2.12.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


詳細はこちらをご覧ください。