【HC32F460开发板测评】NO.5 GUIX的移植和应用
[复制链接]
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保证创建的语言和主题独立性。
- 用户可以提供自定义绘图和事件处理能力。
GUIX在HC32F460上的移植
GUIX的体系结构的一个优势是,很容易移植到新的芯片体系结构。现在拿前一节准备好的并且测试正常的Theadx工程,直接移植,以下是过程。
OLED的绘制原理
OLED是单色屏,使用一个bit就可以表示是1个像素点,比如1表示亮,0表示灭。我们这里驱动的实现是定义了一个显存空间uint8_t s_ucGRAM[8][128],占用1K字节, 共8行,每行128像素。用户绘制的都是绘制到这个显存里面,需要刷新的时候整体刷新OLED界面即可。这里要注意的是显存每个字节反应到OLED显示屏实际坐标上表示的那些位置的像素点。下面是整体布局:
高是64个COM,宽是128个SEG,每8个COM组成一个Page,共计8个Page。然后再看每个Page的细节,以Page2为例:
每个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);
}
这里要注意两点:
- 驱动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驱动:
/* 配置显示屏 */
gx_studio_display_configure(DISPLAY_1, hc32_graphics_driver_setup_monochrome,
LANGUAGE_ENGLISH, DISPLAY_1_THEME_1, &root);
添加GUIX源码
接着需要将GUIX的源码程序移植到TheadX_OLED 测试工程中,并且添加好对应的头文件路径,如下图:
GUIX Studio单色屏设计
需要使用设计器进行显示应用设计,新建工程并且配置如下:
这里需要注意,我们使用静态内存分配方式,所以所有控件都不能选则动态分布:
GUIX Studio 的具体使用方法和流程请参见以下链接:https://www.cnblogs.com/armfly/p/14189864.html
GUIX OLED 应用测试
在 TheadX 的调度中,新建 gui_task 任务,用来测试上面新建的 HelloWorld 静态显示应用,实际结果如下图:
到这里,已经完成了TheadX+GUIX+OLED 的测评任务,希望在之后的应用中将Azure RTOS 全家桶带到产品中去,使整个系统更加安全。
|