このページでは

C

DeviceLink通信の移植

DeviceLinkコンポーネントは、ホストとデバイス間の通信を可能にします。これにより、デバッグやテストの目的で、タッチ操作、スクリーンショット、パフォーマンス、またはログデータを交換することができます。

Platform::DeviceLinkInterface は、プロトコル機能とハードウェア間のインターフェースを提供します。以下の関数を実装する必要があります:

以下は、上記の関数の実装例です:

struct ExampleDeviceLinkInterface : Qul::Platform::DeviceLinkInterface
{
    void platformInit()
    {
        // Enable and start actual transfer and reception of the serial port,
        // eg. enabling interrupts
    }

    void transmitChars(const uint8_t *data, uint32_t size)
    {
        QUL_UNUSED(data);
        QUL_UNUSED(size);

        // Use the serial port to transfer the data to the host
        // HAL_UART_Transmit(&uartHandle, (uint8_t *) data, size, 0xFFFF);
    }

    Qul::Platform::FramebufferFormat framebufferFormat(const Qul::PlatformInterface::LayerEngine::ItemLayer *layer)
        QUL_DECL_OVERRIDE
    {
        // Assuming we use 32bpp framebuffers
        static const int BytesPerPixel = 4;

        static const int ScreenWidth = QUL_PLATFORM_DEFAULT_SCREEN_WIDTH;
        static const int ScreenHeight = QUL_PLATFORM_DEFAULT_SCREEN_HEIGHT;

        Qul::Platform::FramebufferFormat format;

        format.address = frontBuffer();
        format.width = ScreenWidth;
        format.height = ScreenHeight;
        format.bytesPerLine = ScreenWidth * BytesPerPixel;
        format.bitsPerPixel = BytesPerPixel * 4;
        format.redChannel.offset = 16;
        format.redChannel.length = 8;
        format.greenChannel.offset = 8;
        format.greenChannel.length = 8;
        format.blueChannel.offset = 0;
        format.blueChannel.length = 8;
        format.swapBytes = 0;
        return format;
    }
};

移植先のプラットフォームにレイヤーエンジンが存在する場合framebufferFormat 関数はこれに対応するために異なる方法で実装する必要があります:

Qul::Platform::FramebufferFormat framebufferFormat(const PlatformInterface::LayerEngine::ItemLayer *layer)
{
    const ExampleItemLayerBase *base = static_cast<const ExampleItemLayerBase *>(layer);

    Qul::Platform::FramebufferFormat format;

    format.address = base->drawingDevice.bits();
    format.width = base->drawingDevice.width();
    format.height = base->drawingDevice.height();
    format.bytesPerLine = base->drawingDevice.bytesPerLine();
    format.bitsPerPixel = base->drawingDevice.bitsPerPixel();

    switch (format.bitsPerPixel) {
    case 16:
        format.redChannel.offset = 0;
        format.redChannel.length = 5;
        format.greenChannel.offset = 5;
        format.greenChannel.length = 6;
        format.blueChannel.offset = 11;
        format.blueChannel.length = 5;
        format.swapBytes = 2;
        break;
    case 32:
        format.redChannel.offset = 16;
        format.redChannel.length = 8;
        format.greenChannel.offset = 8;
        format.greenChannel.length = 8;
        format.blueChannel.offset = 0;
        format.blueChannel.length = 8;
        format.swapBytes = 0;
        break;
    default:
        QUL_ASSERT(false, QulError_LayerEngine_UnsupportedColorDepth, format.bitsPerPixel);
    }

    return format;
}

Qt Quick Ultralite がカスタムデバイスリンク実装を使用できるようにするには、デバイス用のデバイスリンクインターフェースを返す関数を作成してください。

DeviceLinkInterface *getDeviceLinkInterface()
{
    static ExampleDeviceLinkInterface deviceLink;
    return &deviceLink;
}

QUL_PLATFORM_DEVICELINK_ENABLED も参照してください。

ハードウェアの設定

PlatformContext::initializeHardware の実装において、対象のチャネル(通常はシリアルポート)のハードウェアを初期化した後に、デバイスリンクライブラリの初期化を追加してください。

if (Qul::Platform::DeviceLink::instance())
    Qul::Platform::DeviceLink::instance()->init();

これにより、上記で実装したplatformInit 関数が呼び出され、データ受信が開始されます。

シリアル受信関数内では、受信したデータをデコードのためにデバイスリンクコンポーネントに転送してください:

void UART_ReceiveInterrupt()
{
    Qul::PlatformInterface::deviceLinkBytesReceived(&receivedByte, 1);
}

転送プロトコルに干渉するため、シリアルポートへのその他のデータの書き込みは避けてください。確実を期すために、printf などが使用する低レベルの書き込み関数を再実装し、その内容をデバイスリンクプロトコル経由で送信するようにしてください。

ほとんどのプラットフォームにおいて、再実装が必要な低レベルの書き込み関数は以下の通りです:

void putChar(char &character);
int _write(int file, char *ptr, int len);

以下の実装例は、これらそれぞれに合わせて調整する必要があります。Qt Quick のUltraliteロギングシステムを通じて出力されるすべてのメッセージは、アクティブになっている場合、自動的にデバイスリンク経由で転送されます。

int _write(char *message, int len) {
    auto deviceLink = Qul::Platform::DeviceLink::instance();
    if (deviceLink)
        deviceLink->printMessage(message, len);
    else
        sendDataDirectlyToSerialPort();
}

プラットフォームライブラリが CMake でビルドされている場合は、$<TARGET_PROPERTY:Qul::Platform,QUL_PLATFORM_UART_BAUD_RATE> を使用して設定されたボーレートを取得するか、QUL_PLATFORM_UART_BAUD_RATE のコンパイル定義が設定された platform_config.h をインクルードし、それに応じて UART シリアルポートを設定してください。

QUL_PLATFORM_UART_BAUD_RATE も参照してください。

ロギングの実装の更新

前の手順で実装したconsoleWrite 関数を修正し、デバイスリンク転送も使用するようにします。

void ExamplePlatform::consoleWrite(char character) {
    if (deviceLink) {
        // You should think about collecting several characters and send them in chunks
        // instead of 1 by 1 because this will be slow.
        deviceLink->printMessage(&character, 1);
    } else {
        // Write the charactor to your boards output device
        sendDataDirectlyToSerialPort();
    }
}

プラットフォームの再構築に必要な要件

デバイスリンクを有効にしてプラットフォームを再構築するには、protobuf およびgrpcio-tools Python パッケージをインストールしてください:

pip install protobuf==4.23.4 grpcio-tools==1.60.0 "setuptools<80"

特定のQtライセンスの下で利用可能です。
詳細はこちら。