C

移植DeviceLink通信

目的

设备链组件可以为主机与设备之间提供通信功能。它允许它们交换触摸、截图、性能或日志数据,以用于调试或测试。

自定义设备链的实现在协议设施和硬件之间提供接口。以下两个函数必须实现:

以下是对上面提到的函数的示例实现:

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
    {
        // Layer engine enabled?
        if (layer)
            return Qul::Platform::ExampleLayerEngine::framebufferFormat(layer);

        // 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;
    }
};

如果启用了层支持,下面函数Qul::Platform::DeviceLinkInterface::framebufferFormat() 将转发到ExampleLayerEngine。

Qul::Platform::FramebufferFormat ExampleLayerEngine::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;
}

示例实现还定义了另一个函数,它返回您设备的设备链接口。

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

另请参阅 QUL_PLATFORM_DEVICELINK_ENABLED

硬件设置

初始化所需通道的硬件,通常是串口,然后检查是否启用了设备链并初始化它。

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

在您的串行接收函数中,将接收到的数据转交给设备链组件进行解码。

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

重新实现低级写入函数,使其内容通过设备链协议传递,避免干扰串口协议。

在大多数平台上需要重新实现的低级写入函数是:

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

以下示例实现应针对每个这些进行修改。

auto deviceLink = Qul::Platform::DeviceLink::instance();
if (deviceLink)
    deviceLink->printMessage(message, len);
else
    sendDataDirectlyToSerialPort();

更新日志实现

修改您之前看到的logFlush函数的实现,以使用设备链组件的printMessage函数直接写入串口。

平台重建的要求

安装protobufgrpcio-tools Python包以启用设备链接重建平台。

适用于某些Qt许可。
了解更多信息。