このページでは

C

Qt Quick Ultraliteの使用方法Zephyr

Zephyr は、組み込みシステム向けのRTOSです。完全なプリエンプティブ型ティックレスカーネル、協調型およびプリエンプティブ型のスレッド処理、セマフォ、キューを提供します。

サポートされるアーキテクチャ、プラットフォーム、およびZephyr のバージョン

Qt Quick Ultraliteは以下のハードウェアをサポートしています:

ハードウェアボードMCUアーキテクチャコンパイラ対応Zephyr バージョン
NXP IMXRT1060-EVKBMIMXRT1062DVL6BARM Cortex-M7GNU Arm GCC 12.3.rel14.1.0
NXP IMXRT1064-EVKMIMXRT1064DVL6AARM Cortex-M7GNU Arm GCC 12.3.rel14.1.0

Qt Quick Ultralite をZephyr プラットフォームに移植する

Qt Quick Ultralite Platform Porting Guide」に従うことで、Qt Quick UltraliteをZephyr プラットフォームに移植できます。リファレンスポートでは、以下の部分がZephyr APIを使用して実装されています。

  • currentTimestamp() はk_uptime_get() を呼び出します。
  • タッチ操作のサポートは、Keyboard Scan API を使用して実現されています。
  • Qt Quick UltraliteキューはZephyr メッセージキューを使用しています。
  • セマフォはQt Quick のUltraliteスレッドの動作を一時停止および再開するために使用されます。
  • ディスプレイ割り込みは、Zephyr を使用して設定および有効化されます:
    void setInterruptPriorities()
    {
        IRQ_CONNECT(LCDIF_IRQn, 3, displayIRQHandler, NULL, 0);
        irq_enable(LCDIF_IRQn);
    }
  • LCD画面のピンマルチプレクシングは、Zephyr のピン制御APIを使用して初期化されます。
    #define LCDIF_DEV DT_NODELABEL(lcdif)
    
    void initializeLcdPinmux()
    {
        PINCTRL_DT_DEFINE(LCDIF_DEV);
    
        pinctrl_apply_state(PINCTRL_DT_DEV_CONFIG_GET(LCDIF_DEV), PINCTRL_STATE_DEFAULT);
    }

注: サポートされているリファレンスプラットフォームのポートのいずれかをインストールしている場合 Zephyr のリファレンスポートのソースコードは<QT_INSTALL>/QtMCUs/2.9.0/platform/boards/nxp/common/zephyr ディレクトリにあります。

Zephyr KConfig オプション

Zephyr プロジェクトをQt Quick Ultraliteで使用するように設定する際は、以下のオプションを含めてください:

  • CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048
  • CONFIG_REQUIRES_FULL_LIBC=y
  • CONFIG_NEWLIB_LIBC=y
  • CONFIG_COMMON_LIBC_MALLOC=y
  • CONFIG_COMMON_LIBC_MALLOC_ARENA_SIZE=2097152
  • CONFIG_NEWLIB_LIBC_NANO=y
  • CONFIG_NEWLIB_LIBC_MIN_REQUIRED_HEAP_SIZE=8192
  • CONFIG_CPP=y
  • CONFIG_STD_CPP14=y
  • CONFIG_EXTERNAL_LIBCPP=y
  • CONFIG_FORTIFY_SOURCE_NONE=y

注: プラットフォーム・ポートでカスタム割り当てシステムを使用している場合は malloc 関連のオプションを設定する必要はありません。

Qt Quick Ultraliteアプリケーションをメインスレッドから実行する場合は、メインスレッドのスタックサイズを増やしてください。たとえば、リファレンスプラットフォームポートではCONFIG_MAIN_STACK_SIZE=12288 が使用されており、これはthermo デモおよびサポートされているすべてのサンプルを実行するのに十分です。

あらかじめビルド済みのQt Quick Ultraliteライブラリを使用する場合は、以下のオプションを追加してください:

  • CONFIG_FPU=y
  • CONFIG_LTO=y
  • CONFIG_ISR_TABLES_LOCAL_DECLARATION=y

ワークフロー

Qt Quick Ultraliteには、既存のZephyr プロジェクトと簡単に統合できるツールが用意されています。

Qt Quick Ultralite アプリケーションの作成およびコンパイルの全体的なワークフローは、次のとおりです。

Zephyr を使用して <span translate=Qt Quick Ultralite アプリケーションを作成およびコンパイルするためのワークフロー。" src="images/qtul-zephyr-workflow.png" title="Zephyr を使用して Qt Quick Ultralite アプリケーションを作成およびコンパイルするためのワークフロー。"/>

新しいQt Quick Ultraliteアプリケーションの作成

Qt Quick Ultraliteアプリケーションを作成するには、MCU向けドキュメントの「Qt Design Studio 」を参照してください。

アプリケーションを CMake プロジェクトとしてエクスポートする

CMakeプロジェクトの生成」ページには、qmlprojectexporterを使用してCMakeプロジェクトを生成する際に使用できるフラグの一覧が記載されています。プラットフォームのソースをエクスポートする必要がない場合は、 --no-export-platform を qmlprojectexporter の呼び出しに追加してください。プラットフォームをエクスポートしない場合の qmlprojectexporter の呼び出し例については、「platform なしでエクスポートされたプロジェクトを統合する」を参照してください。

エクスポートされた CMake プロジェクトを `Zephyr ` プロジェクトに追加する

エクスポートされた CMake プロジェクトは、CMake プロジェクトファイルの作成手順に従って追加できますが、以下の点が異なります:

  • CMakeLists.txt 内で新しいプロジェクトを指定する必要はありません。ただし、プロジェクトでLANGUAGES C CXX ASM が指定されていることを確認してください。
  • find_package およびすべてのtarget_* 呼び出しを、 find_package(Zephyr)の後に配置してください。
  • target_* を指定する際は、ターゲットとしてapp を使用し、Qt Quick のUltraliteアプリケーションがZephyr プロジェクトに確実にビルドされるようにしてください。

リンカースクリプトへの「Qt Quick 」Ultralite固有のセクションの追加

Qt Quick Ultralite では、Qt Quick Ultralite アプリケーションに関連するすべてのデータを格納できるいくつかのセクションをリンカースクリプトに含める必要があります。これらのセクションの説明はこちらを参照してください。

ただし、カスタムリンカースクリプトを使用しない限り、Zephyr がスクリプトを自動的に生成します。自動的に生成されたスクリプトにQt Quick Ultraliteで必要なセクションを追加するには、リンカースクリプト内でZephyr 固有のセクション記述表記を使用し、zephyr_linker_sources(SECTION_NAME "path/to/linkerscript.ld") を使用してそれらを含める必要があります。zephyr_linker_sources およびこの表記の使用方法の詳細については、ZEPHYR_DIR/zephyr/cmake/modules/extensions.cmake を参照してください。

Qt Quick Ultralite リファレンスプラットフォームの移植版では、3つのファイルでリンカーセクションが定義されています:

  • qul_data_sections.ld
    /*
     * Copyright (C) 2026 The Qt Company Ltd.
     * SPDX-License-Identifier: LicenseRef-Qt-Commercial
     */
    
    SECTION_PROLOGUE (QulModuleResourceData,,SUBALIGN(4)) {
        __ModuleResourceDataCacheStart = .;
        *(QulModuleResourceData)
        __ModuleResourceDataCacheEnd = .;
    } GROUP_LINK_IN(RAMABLE_REGION) AT > ROMABLE_REGION
    
    __ModuleResourceDataStart = LOADADDR(QulModuleResourceData);
  • qul_ram_sections.ld
    /*
     * Copyright (C) 2026 The Qt Company Ltd.
     * SPDX-License-Identifier: LicenseRef-Qt-Commercial
     */
    
    SECTION_PROLOGUE (QulPreloadData,,SUBALIGN(4)) {
        __preloadRamStart = .;
        *(QulPreloadData)
        . += 10M;
        __preloadRamEnd = .;
    } GROUP_LINK_IN(RAMABLE_REGION)
  • qul_rom_sections.ld
    /*
     * Copyright (C) 2026 The Qt Company Ltd.
     * SPDX-License-Identifier: LicenseRef-Qt-Commercial
     */
    
    SECTION_PROLOGUE (QulFontResourceData,,) {
        . = ALIGN(4);
        *(QulFontResourceData)
        . = ALIGN(4);
    } GROUP_LINK_IN(ROMABLE_REGION)
    
    SECTION_PROLOGUE (QulResourceData,,SUBALIGN(4)) {
        *(QulResourceData)
    } GROUP_LINK_IN(ROMABLE_REGION)

これらのファイルは、zephyr-linker-sources.cmake を使用してZephyr プロジェクトに追加されます:

# Copyright (C) 2025 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial
zephyr_linker_sources(DATA_SECTIONS "${CMAKE_CURRENT_LIST_DIR}/cmake/armgcc/qul_data_sections.ld")
zephyr_linker_sources(RAM_SECTIONS "${CMAKE_CURRENT_LIST_DIR}/cmake/armgcc/qul_ram_sections.ld")
zephyr_linker_sources(SECTIONS "${CMAKE_CURRENT_LIST_DIR}/cmake/armgcc/qul_rom_sections.ld")

# Workaround for https://github.com/zephyrproject-rtos/zephyr/issues/90581
target_link_options(app INTERFACE -Wl,-u,image_vector_table -Wl,-u,boot_data)

Qt Quick Ultralite アプリケーションの反復ビルド

Qt Quick のUltraliteアプリケーションの内容を変更する場合、Zephyr プロジェクトを再ビルドするだけで済みます。qmlprojectexporterを実行すると、変更内容が読み込まれ、Qt Quick のUltraliteアプリケーションのソースが再エクスポートされ、QulExportパッケージが更新されるため、Zephyr プロジェクトで変更内容が利用可能になります。

Qt Quick のUltraliteスレッドの作成

xml-ph-0000@deepl.internal Ultraliteアプリケーションをエクスポートする際に --generate-entrypointQt Quick Ultraliteアプリケーションのエクスポート時に`main`が使用される場合、メインスレッドがアプリケーションのエントリポイントとして使用されます。スレッドの作成をより細かく制御したい場合は、Qt Quick Ultraliteアプリケーションを実行する Zephyr スレッドを生成することもできます。これを行うには、qmlprojectexporterの呼び出しから --generate-entrypoint 引数を省略します。

Zephyr プロジェクトでは、まずQt Quick Ultraliteアプリケーションのスレッドを宣言し、そのスレッドにスタック領域を割り当てます:

k_tid_t QulThread;
static K_THREAD_STACK_DEFINE(qul_stack_area, 12288);

注:スタックサイズは Qt Quick Ultraliteアプリケーションの複雑さによって異なります。ここでの例示値は、Qt Quick Ultraliteサーモスタットデモには十分です。

次に、Qt Quick Ultraliteアプリケーションスレッドを定義します:

void Qul_Thread(void *arg1, void *arg2, void *arg3)
{
    (void) arg1;
    (void) arg2;
    (void) arg3;

    Qul::Application app;
    static MainScreen item;
    app.setRootItem(&item);
    while (true)
        app.update();
}

注: MainScreen では Qt Quick UltraliteアプリケーションのメインQMLファイルがMainScreen.qml であることを前提としています。アプリケーションのメインQMLファイル名に合わせて、項目の名前を変更してください。

その後、Qt Quick Ultralite アプリケーションのスレッドを作成します:

struct k_thread qul_thread_data;

QulThread = k_thread_create(&qul_thread_data,
                            qul_stack_area,
                            K_THREAD_STACK_SIZEOF(qul_stack_area),
                            Qul_Thread,
                            NULL,
                            NULL,
                            NULL,
                            4,
                            0,
                            K_NO_WAIT);

注: Qt Quick Ultraliteアプリケーションを実行する前に、ハードウェアの初期化が完了していることを確認してください

Qt Quick Ultraliteアプリケーションスレッドを起動する完全なZephyr プロジェクトのmain.cppは、例えば以下のようになります:

#include "MainScreen.h"

#include <zephyr/kernel.h>

k_tid_t QulTask;
static K_THREAD_STACK_DEFINE(qul_stack_area, 12288);

static void Qul_Thread(void *arg1, void *arg2, void *arg3);

int main()
{
    Qul::initHardware();
    Qul::initPlatform();

    struct k_thread qul_thread_data;

    QulThread = k_thread_create(&qul_thread_data,
                                qul_stack_area,
                                K_THREAD_STACK_SIZEOF(qul_stack_area),
                                Qul_Thread,
                                NULL,
                                NULL,
                                NULL,
                                4,
                                0,
                                K_NO_WAIT);

    return 0;
}

static void Qul_Thread(void *arg1, void *arg2, void *arg3)
{
    (void) arg1;
    (void) arg2;
    (void) arg3;

    Qul::Application app;
    static MainScreen item;
    app.setRootItem(&item);
    while (true)
        app.update();
}

Zephyr プラットフォームで、独自にビルドしたQt Quick Ultraliteを使用する場合

ソースからQt Quick Ultraliteをビルドするには、「ソースからのQt Quick Ultraliteのビルド」の手順に従ってください。

mkdir -p <builddir>/.cmake/api/v1/query && touch <builddir>/.cmake/api/v1/query/codemodel-v2
cmake
    -S $QUL_ROOT
    -B <builddir>
    -DQul_ROOT=$QUL_ROOT
    -DQUL_TARGET_TOOLCHAIN_DIR=<toolchaindir>
    -DQUL_GENERATORS=$QUL_ROOT/lib/cmake/Qul/QulGenerators.cmake
    -DCMAKE_TOOLCHAIN_FILE=$QUL_ROOT/lib/cmake/Qul/toolchain/armgcc.cmake
    -DQUL_PLATFORM_ARCHITECTURE=cortex-m7-hf-fpv5-d16
    -DQUL_BUILD_PLATFORM=OFF
    -DCMAKE_INSTALL_PREFIX=<installdir>
    -DQUL_PLATFORM_ARCHITECTURE_FILE=$QUL_ROOT/platform/architecture/cortex-m7-hf-fpv5-d16/armgcc/architecture.cmake
make -C <builddir> install

ビルドが完了したら、ビルドされたライブラリを使用してQt Quick Ultraliteアプリケーションをエクスポートできます:

$QUL_ROOT/bin/qmlprojectexporter
    $QUL_ROOT/examples/chess/mcu_chess.qmlproject
    --boarddefaults=<path/to/>BoardDefaults_24bpp_default.qmlprojectconfig
    --toolchain GNU
    --cxx-standard=c++17
    --platform <platform_name>
    --outdir <target_dir>
    --qul-source-dir <installdir>
    --project-type cmake
    --no-export-platform
    --generate-entrypoint
    --platform-metadata <installdir>/lib/cortex-m7-hf-fpv5-d16-export.json

エクスポート後、エクスポートされた CMake プロジェクトをZephyr プロジェクトに追加してください

特定のQtライセンスの下で利用可能です。
詳細はこちらをご覧ください。