このページでは

C

デバイスリンク通信の移植

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

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 パッケージをインストールします。

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