SnailWillow

  • 62 主题
  • 229 帖子
  • 1218 积分
  • 身份:版主
  • 论坛新秀
  • E币:1439

【原创】国产M4开发板移植GUIX

2021-6-3 18:05:18 显示全部楼层
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】

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

【控件库】

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

【数学和实用功能】

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

【图像处理】

  •   支持jpeg和png解码。
  •   支持抖动和颜色格式转换。
  •   支持图像旋转。
  •   支持图像放缩。
  •   支持图像混合。

【事件处理】

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

Canvas画布处理】

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

【输入设备驱动】

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

【显示驱动和目标硬件】

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

【内存需求】

对于集成了内部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生成的文件:

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

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

OLED的绘制原理

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

212101txvdh7lg0yjb7xzt.png.thumb.jpg


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

212110fvlpqqq7kz7kqkvk.png.thumb.jpg


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

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

OLED底层驱动实现

OLED的底层驱动实现如下:

  1. /*

  2. *********************************************************************************************************

  3. *   函 数 名: hc32_monochrome_buffer_toggle

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

  5. *   形    参: 无

  6. *   返 回 值: 无

  7. *********************************************************************************************************

  8. */

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

  10. {

  11.     uint8_t *p;



  12.     /* 防止警告 */

  13.     (void)canvas;

  14.     (void)dirty;



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

  16.     p = (uint8_t *)display_1_canvas_memory;

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

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

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

  20.     {

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

  22.         {

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

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

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

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

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

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

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

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

  31.         }

  32.     }

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

  34.     OLED_EndDraw();

  35. }

  36. /*

  37. *********************************************************************************************************

  38. *   函 数 名:hc32_graphics_driver_setup_monochrome

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

  40. *   形    参: 无

  41. *   返 回 值: 无

  42. *********************************************************************************************************

  43. */

  44. UINT hc32_graphics_driver_setup_monochrome(GX_DISPLAY *display)

  45. {

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

  47.     return (GX_SUCCESS);

  48. }

这里要注意两点:

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

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

添加驱动接口到GUIX

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

  1. /* 配置显示屏 */

  2.     gx_studio_display_configure(DISPLAY_1, hc32_graphics_driver_setup_monochrome,

  3.                                 LANGUAGE_ENGLISH, DISPLAY_1_THEME_1, &root);
添加GUIX源码

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

212224lww0wnlrynyary72.png.thumb.jpg


GUIX Studio单色屏设计

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

212231bxqbytnaaqsblrrt.png.thumb.jpg


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

212240apkpzpvxzk6iaypp.png.thumb.jpg


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

GUIX OLED 应用测试

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

212311juzhd7e7iihsuys7.png.thumb.jpg


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


HC32F460_template_ThreadX_GUIX_OLED.rar (2.71 MB, 下载次数: 2)

最新评论

楼层直达:

电子阔少

  • 150 主题
  • 653 帖子
  • 1577 积分
  • 身份:版主
  • 论坛新秀 灌水之王
  • E币:1688

二哲科技

  • 171 主题
  • 507 帖子
  • 1837 积分
  • 身份:版主
  • 论坛新秀 灌水之王
  • E币:1048
二哲科技 2021-6-11 08:52:56 显示全部楼层
666,不过如果有彩屏的话更好~因为OLED没触摸看不出太好的效果。
快速回复
2
6
广告
关闭 热点推荐上一条 /6 下一条