このページでは

C

Qt Quick UltraliteのRTOSへの移植

Qt Quick Ultralite を RTOS プラットフォームに移植する手順は、本ガイドの他のセクションで説明しているベアメタルプラットフォームの場合とほぼ同様です。以下のセクションでは、ベアメタルプラットフォームとの違いについて概説します。

RTOSプラットフォーム上のQt Quick Ultraliteアプリケーションは、Qul::Application::exec を使用してRTOSタスク/スレッドとして起動されます。この呼び出しは最終的にPlatformContext::exec へとつながり、これがそのプロセスのメインループとして機能します。これについては、Qt Quick UltraliteとFreeRTOS の併用」および「 Qt Quick UltraliteとZephyr の併用」のページでより詳しく説明されています。

プラットフォーム移植ガイドで紹介されているすべてのプラットフォームAPIは、プラットフォームが提供するサービスやAPIを利用するように適応させることができます。その一例として、Qt Quick UltraliteのFreeRTOS 向け移植版におけるメモリ割り当てAPIが挙げられ、これはOSが提供するAPIによって実装される可能性があります。

extern void *pvPortMalloc(size_t xWantedSize);
void *qul_malloc(std::size_t size)
{
    return pvPortMalloc(size);
}

スレッドのイールド

お使いのRTOSがイールドをサポートしている場合、Qt Quick Ultralite RTOSスレッドをイールドして、計算リソースを解放することが可能です。イールドは以下の場所で呼び出すことができます:

  • メインループ内のexec() 関数内
    void ExamplePlatform::exec()
    {
        while (true) {
            logFlush(); // Flush partially filled log buffer
            const uint64_t timestamp = this->update();
    
            if (timestamp > Platform::getPlatformInstance()->currentTimestamp()) {
                // The device may yield or go into sleep mode
            }
        }
    }
  • また、ディスプレイコントローラによるバックバッファの解放を待機している際も、イールド関数を呼び出す適切な場面となります。
    static volatile bool waitingForBufferFlip = false;
    static uint32_t idleTimeWaitingForDisplay = 0;
    
    static void waitForBufferFlip()
    {
        // Has there already been a buffer flip?
        if (!waitingForBufferFlip)
            return;
        const uint64_t startTime = getPlatformInstance()->currentTimestamp();
        while (waitingForBufferFlip) {
            // The device may yield or go into sleep mode
        }
    
        idleTimeWaitingForDisplay = getPlatformInstance()->currentTimestamp() - startTime;
    }
    
    // Note: This line clearing waitingForBufferFlip will need to be moved to the
    // actual interrupt handler for the display available on the target platform.
    // It's needed to inform about when the buffer address used to scan out pixels
    // to the display has been updated, making the buffer free in order to start
    // drawing the next frame.
    void LCD_BufferFlipInterruptHandler()
    {
        waitingForBufferFlip = false;
    }

    また、次のリフレッシュ間隔がスケジュールされるまでに十分な時間がある場合にも、イールドを行うことが可能です

    static void waitForRefreshInterval()
    {
        if (refreshCount < requestedRefreshInterval) {
            uint64_t startTime = getPlatformInstance()->currentTimestamp();
            while (refreshCount < requestedRefreshInterval) {
                // The device may yield or go into sleep mode
            }
            idleTimeWaitingForDisplay += getPlatformInstance()->currentTimestamp() - startTime;
        }
    
        refreshCount = 0;
    }

    waitForBufferFlip() およびwaitForRefreshInterval() の詳細については、「基本グラフィックスの実装」のセクションを参照してください。

  • お使いのハードウェアプラットフォームがレイヤーをサポートしている場合、presentFrame() 関数内でイールドを行うことが可能です。
    // This function has to replace your PlatformContext::presentFrame
    FrameStatistics presentFrame(const PlatformInterface::Screen *screen, const PlatformInterface::Rect &rect)
    {
        static unsigned int lastFrame = 0xffffffff;
        while (currentFrame == lastFrame) {
            // The device may yield or go into sleep mode
        }
        lastFrame = currentFrame;
    
        PlatformInterface::Rgba32 color = screen->backgroundColor();
        // HW_SetScreenBackgroundColor(color.red(), color.blue(), color.green());
    
        // No frame skip compensation implemented for layers
        return FrameStatistics();
    }

    詳細については、このセクションを参照してください。

FreeRTOS- 具体的な詳細

この app_common フレームワークを使用できるようにするには、QUL_OS 変数を -DQUL_OS=FreeRTOS CMakeコマンドラインオプションを使用するか、プラットフォーム名にQUL_OS を含めることで設定します:

<platform_name>-freertos

Zephyr- 詳細

Qt Quick Ultraliteを Zephyrを使用してプラットフォームに移植する方法の詳細については、Zephyr でのQt Quick Ultraliteの使用」ページを参照してください。

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