[MCU] 【HC32F460开发板测评】NO.5 GUIX的移植和应用

yang377156216   2021-5-3 21:23 楼主

Azure GUIX简介

GUIX是微软的高级工业级GUI解决方案,专门针对深度嵌入式,实时和IoT应用程序而设计。微软还提供了名为GUIX Studio的桌面开发工具,该工具允许开发人员在桌面上设计其GUI并生成GUIX代码,然后可以将其导出到目标。

GUIX通过了医疗认证IEC-62304 Class C,汽车认证IEC-61508 ASIL D,工业认证IEC-61508 SIL 4和运输/铁路认证EN50128。表明GUIX可用于安全关键型系统。

【直观一致的API】 

  1.   名词动词命名约定。
  2.   所有API都有gx_前缀,方便识别GUIX的函数。
  3.   事件驱动模式。
  4.   需要时,支持直接canvas画布绘制。
  5.   方便与GUIX Studio交互。
  6.   API支持绘制直线,矩形,多边形等。
  7.   API支持圆圈,圆弧,饼图,弦图和椭圆绘制。
  8.   API支持文本绘制和位置调整。
  9.   支持抗锯齿,纹理填充和实体填充。
  10.   支持创建和修改屏幕和控件。

【控件库】

  1.   预定义,但是可以自定义的一组通用接口元素。
  2.   小巧,紧凑且高效。
  3.   库包括按钮、仪表、列表,窗口,滚动条,滑块,进度条等
  4.   完全可定制的绘制和外挂。
  5.   完全可定制的操作和事件管理。
  6.   只有控件的使用与应用代码关联。

【数学和实用功能】

  1.   支持sin,cos,arcsin,arccos,tan和平方根、
  2.   支持操作屏幕区域。
  3.   系统配置和启动
  4.   内存池定义。
  5.   定时器管理、
  6.   动画管理。
  7.   Dirty列表维护(即需要绘制的区域)

【图像处理】

  1.   支持jpeg和png解码。
  2.   支持抖动和颜色格式转换。
  3.   支持图像旋转。
  4.   支持图像放缩。
  5.   支持图像混合。

【事件处理】

  1.   空闲时自动挂起GUIX线程。
  2.   UI设计中流行的事件驱动编程模型。
  3.   将驱动程序与GUIX绘制任务隔离。
  4.   发送和接收事件功能。
  5.   所有GUIX小控件的预定义事件类型。
  6.   用户自定义事件。

Canvas画布处理】

  1.   裁剪和Z序处理。
  2.   控件和硬件隔离。
  3.   应用和硬件隔离。
  4.   自动刷新Dirty区域。
  5.   支持多图层画布的混合。
  6.   可以由应用程序直接调用。

【输入设备驱动】

  1.   定制硬件支持,GUIX和硬件隔离。
  2.   支持电阻式,电容式和实体键盘。
  3.   输入事件传递到GUIX事件队列。

【显示驱动和目标硬件】

  1.   各种颜色格式和颜色深度支持。
  2.   可以定制图形加速,通过底层接口函数实现。
  3.   几乎任何支持图形输出的屏,都可以使用GUIX。
  4.   支持多屏显示。

【内存需求】

对于集成了内部GRAM和自刷新技术的显示屏,可以不需要canvas画布支持。这种情况下,GUIX需要的最小Flash是13.2KB,RAM是4KB。

所需画布大小的计算公式如下:

Canvas RAM (bytes) = (x * y * (bpp/8))

其中x和y分别是画布的长和宽,而bpp是画布的颜色深度,比如RGB565,颜色深度bpp就是16bit,即两字节。

另外大多数应用还会用到图形资源和字库,这个占用大小由实际应用而定。

 GUIX Studio简介

使用GUIX Studio,完全可以让美工前期做好各种界面效果,后期工程师添加操作流程和触发事件。的确是做的非常成熟,可以添加设置各种主题,各种界面效果,各种字体展示,各种图片格式设置,使用GUIX Studio,基本可以实现GUI设计一条龙。

GUIX Studio生成的文件:

  1.   自动生成ANSI C文件。
  2.   让用户应用设计与界面设计隔离开。
  3.   包含设计所需的字体和图像。
  4.   生成的代码可以和用户应用代码一起编译。
  5.   界面更新不影响用户应用逻辑。
  6.   资源ID保证创建的语言和主题独立性。
  7.   用户可以提供自定义绘图和事件处理能力。

GUIXHC32F460上的移植

GUIX的体系结构的一个优势是,很容易移植到新的芯片体系结构。现在拿前一节准备好的并且测试正常的Theadx工程,直接移植,以下是过程。

OLED的绘制原理

OLED是单色屏,使用一个bit就可以表示是1个像素点,比如1表示亮,0表示灭。我们这里驱动的实现是定义了一个显存空间uint8_t s_ucGRAM[8][128],占用1K字节, 共8行,每行128像素。用户绘制的都是绘制到这个显存里面,需要刷新的时候整体刷新OLED界面即可。这里要注意的是显存每个字节反应到OLED显示屏实际坐标上表示的那些位置的像素点。下面是整体布局:

image.png

 高是64个COM,宽是128个SEG,每8个COM组成一个Page,共计8个Page。然后再看每个Page的细节,以Page2为例:

image.png

每个Page的扫描方式可以认为是从上到下,从左到右,第1列的8个像素值对应的显存变量是s_ucGRAM[2][0],第2列就是s_ucGRAM[2][1],以此类推,这一点非常重要,因为我们后面要用到的GUIX Studio生成界面扫描方式不是这样的,它是从左到右,从上到下。

了解了这些知识点就够用了。

OLED底层驱动实现

OLED的底层驱动实现如下:

/*

*********************************************************************************************************

*   函 数 名: hc32_monochrome_buffer_toggle

*   功能说明: I2C屏绘制,直接做整个屏的重绘

*   形    参: 无

*   返 回 值: 无

*********************************************************************************************************

*/

static void hc32_monochrome_buffer_toggle(GX_CANVAS *canvas, GX_RECTANGLE *dirty)

{

    uint8_t *p;



    /* 防止警告 */

    (void)canvas;

    (void)dirty;



    /* 获得OLED画布的地址 */

    p = (uint8_t *)display_1_canvas_memory;

//    OLED_DrawBMP(0, 0, 128, 32, p);

    /* 将画布的内容绘制到OLED显存 */

    for (int y = 0; y < 32; y++)

    {

        for (int x = 0; x < 128; x += 8)

        {

            OLED_PutPixel(x, y, (p[16 * y + x / 8] & (0x80)) >> 7);

            OLED_PutPixel(x + 1, y, (p[16 * y + x / 8] & (0x40)) >> 6);

            OLED_PutPixel(x + 2, y, (p[16 * y + x / 8] & (0x20)) >> 5);

            OLED_PutPixel(x + 3, y, (p[16 * y + x / 8] & (0x10)) >> 4);

            OLED_PutPixel(x + 4, y, (p[16 * y + x / 8] & (0x08)) >> 3);

            OLED_PutPixel(x + 5, y, (p[16 * y + x / 8] & (0x04)) >> 2);

            OLED_PutPixel(x + 6, y, (p[16 * y + x / 8] & (0x02)) >> 1);

            OLED_PutPixel(x + 7, y, (p[16 * y + x / 8] & (0x01)) >> 0);

        }

    }

    /* 将OLED显存的内容实际绘制到OLED */

    OLED_EndDraw();

}

/*

*********************************************************************************************************

*   函 数 名:hc32_graphics_driver_setup_monochrome

*   功能说明:单色屏驱动接口

*   形    参: 无

*   返 回 值: 无

*********************************************************************************************************

*/

UINT hc32_graphics_driver_setup_monochrome(GX_DISPLAY *display)

{

    _gx_display_driver_monochrome_setup(display, (VOID *)HC32_SCREEN_HANDLE, hc32_monochrome_buffer_toggle);

    return (GX_SUCCESS);

}

这里要注意两点:

  1.   驱动OLED单色屏要使用函数_gx_display_driver_monochrome_setup。
  2.   函数stm32_monochrome_buffer_toggle里代码的实现是关键。

由于GUIX Studio生成的界面扫描方式与OLED的扫描方式不同,这里的代码实现就是第3步中扫描方式的切换。具体实现的操作是将canvas画布通过函数OLED_PutPixel(注,此函数不是直接往OLED绘制的)绘制到OLED显存,然后调用函数OLED_EndDraw将OLED显存的内容实际绘制到OLED。

添加驱动接口到GUIX

上面的函数要通过函数gx_studio_display_configure做配置,这样GUIX就会调用OLED驱动:

 /* 配置显示屏 */

    gx_studio_display_configure(DISPLAY_1, hc32_graphics_driver_setup_monochrome,

                                LANGUAGE_ENGLISH, DISPLAY_1_THEME_1, &root);

添加GUIX源码

接着需要将GUIX的源码程序移植到TheadX_OLED 测试工程中,并且添加好对应的头文件路径,如下图

image.png

GUIX Studio单色屏设计

需要使用设计器进行显示应用设计,新建工程并且配置如下:

image.png

这里需要注意,我们使用静态内存分配方式,所以所有控件都不能选则动态分布:

image.png

GUIX Studio 的具体使用方法和流程请参见以下链接:https://www.cnblogs.com/armfly/p/14189864.html

GUIX OLED 应用测试

TheadX 的调度中,新建 gui_task 任务,用来测试上面新建的 HelloWorld 静态显示应用,实际结果如下图:

image.png

到这里,已经完成了TheadX+GUIX+OLED 的测评任务,希望在之后的应用中将Azure RTOS 全家桶带到产品中去,使整个系统更加安全。

image.png

回复评论 (3)

HC32F460_template_ThreadX_GUIX_OLED.rar (2.71 MB)
(下载次数: 33, 2021-5-3 21:39 上传)


 

点赞  2021-5-3 21:39

厉害了!GUIX都弄上去了,可否详细说一下移植过程?

默认摸鱼,再摸鱼。2022、9、28
点赞  2021-5-6 16:22

gui居然是微软的?才知道!这玩意移植起来困难吗?

点赞  2021-5-7 10:28
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复