Linux
图形用户界面
嵌入式系统
MCU

有哪些好的嵌入式操作系统界面库(GUI library)?

类似Qt 、minigui等等
关注者
436
被浏览
594,418

14 个回答

20190809上面答案没提到的,个人认为好用的

1.LittlevGL

LittlevGL 是一个开源免费(MIT许可)的GUI,支持触摸屏操作,移植简单方便,开发者一直在不断完善更新。LittlevGL 自带了丰富的控件:窗口、按键、标签、list、图表等,还可以自定义控件;支持很多特效:透明、阴影、自动显示隐藏滚动条、界面切换动画、图标打开关闭动画、平滑的拖拽控件、分层显示、反锯齿、仅耗少量内存的字体等等。

LittlevGL 常见于 MCU级别的设备,支持各类输入输出接口与芯片,支持使用GPU,以C编写,对于 资源紧张的MCU来说十分适合。


2.TouchGFX

TouchGFX以界面华丽,流畅以及强劲的 TouchGFX Designer著称。 现在已经被ST收购,在ST MCU、MPU可免费使用。官方地址: http://touchgfx.com/en/。

TouchGFX在MCU系统上运行的界面非常炫,堪比手机的APP界面.

使用TouchGFX开发STM32界面,有2种方法:一是利用TouchGFX Designer软件,支持图片和控件拖拽、可快速生成在KEIL或IAR等IDE中可打开的项目工程;另一种方法是,STM32CUBEMX 5.0版本增加了对TouchGFX的支持,可以使用CubeMX开发TouchGFX应用。

3. AWTK

AWTK全称 Toolkit AnyWhere,是 ZLG 开发的开源 GUI 引擎,旨在为嵌入式系统、WEB、各种小程序、手机和 PC 打造的通用 GUI 引擎,为用户提供一个功能强大、高效可靠、简单易用、可轻松做出炫酷效果的 GUI 引擎。

AWTK源码仓库:

  • 主源码仓库: github.com/zlgopen/awtk
  • 镜像源码仓库: gitee.com/zlgopen/awtk

运行效果截图:

4.Microchip MPLAB® Harmony图形设计器

如果需要设计一款具有简单且优雅嵌入式GUI的应用,选择Microchip的MCU总是没错的。并且Microchip官方还推出了很多优秀的入门教程,大大降低使用门槛。

当然 MPLAB® Harmony仅仅能够在MicroChip芯片上使用。

5. emWin

emWin大名鼎鼎的德国Segger公司开发的嵌入式图形界面库,用于构造设计图形化用户界面(GUI)。GUI以“C”源代码的形式提供。

emWin的功能


绘制2D图形:绘制圆、椭圆、多边形、弧线、线图、饼形图;

显示位图文件:显示BMP、JPEG、GIF、PNG格式的图片文件;

显示文字:支持显示多国语言的文字,如中英文;

处理用户输入:如键盘、鼠标、触摸屏的人机交互输入处理;

提供各种窗口对象(图形控件):菜单控件、窗口控件、按键控件、复选框、框架窗口控件;

运行效果图




Emwin功能牛逼,图形炫酷,当然是收费的了。
uc/GUI是Segger公司为Micrium公司(ucos所属公司)定制的emWin;使用的时候都需要向该公司交纳版权费。

STemWin是Segger公司为ST公司定制的emWin;如果我们使用的ST的芯片,则可以免费使用STemWin

segger.com/products/use

6. EmbeddedWizard

Embedded Wizard是德国TARA System公司开发的一个使用舒适、灵活的嵌入式系统GUI开发工具。

主要特性:1)简化GUI开发 2)强大的模拟器,所见即所得编辑 3)图形很漂亮,2D、3D均能够支持,媲美Android界面 4)支持Broadcom、ST、TI等各家MCU 5)支持远程Web UI ,在任何常见的Web浏览器中作为单页面应用程序运行嵌入式GUI 6)收费贵

运行效果图

embedded-wizard.de/

7. Qt for MCU

Qt for MCU 将能够在没有操作系统的设备上运行,允许开发人员在具有成本效益的单片机上创建流畅的用户界面,基于 Qt 的应用程序现在可以部署在运行传统操作系统的系统以及基于 ARM Cortex M7 的微控制器上。

目前,Qt forMCU 是专门为 ARM Cortex-M 单片机开发的,目前支持测试硬件平台:

· STM32F769i-DISCO

· STM32F7508-DK

· I.MX RT1050-EVKB

· Renesas RH850

除了示例和技术文档之外,Qt forMCU 还提供了 Qt QuickControls,以帮助开发人员的开发。Qt 的设计和开发工具 QT Design Studio 和 Qt Creator,将支持新的图形化工具包的开发。Qt 团队还确保 Qt 的当前用户能够继续使用他们现有的工作流来开发用于单片机的应用程序,该公司预计在 9 月中旬发布评估版本,供用户下载。

qt.io/qt-for-mcu

8.其他

1)Minigui是由北京飞漫软件技术有限公司创办的开源Linux图形用户界面支持系统,经过近些年的发展,MiniGUI已经发展成为比较成熟的性能优良的、功能丰富的跨操作系统的嵌入式图形界面支持系统。“小”是MiniGUI的特色,它目前已经广泛应用于通讯、医疗、工控、电子、机顶盒、多媒体等领域。目前,MiniGUI的最新版本为MiniGUI 3.0。MiniGUI对中文的支持很友好。它支持GB2312与BIG5字符集,其他字符集也可以轻松加入。

minigui.org/

2)LearningGUI,国内一小伙开发的,完全开源的。LearningGUI高度可裁剪,可配置,库大小从20多K到200多K。占用内存小。Basic版实行静态内存管理,占用10多K RAM. Windows版实行动态内存管理,占用内存与建立控件多少相关。支持内置GB2312—80标准汉字库。提供开放式字库访问接口。提供开放式颜色转换接口。提供消息驱动机制。

LearningGUI-GPLv3-0-3_tar.gz

编辑于 2022-05-04 23:43
  1. emWin: SEGGER - The Embedded Experts
  2. NanoX(旧称MicoroWindows): microwindows.org/
  3. OpenGUI(旧称FastGL): Official OpenGUI home page
  4. Qt / Embedded: trolltech.com/
    1. 为了不让别人误会,把我帖子里面的解释粘贴过来: ”

      == Qt library TrollTech

      TrollTech已被Nokia收购,所以之前主页:

      trolltech.com/

      会跳转到:

      qt.nokia.com/


  5. MiniGUI: MiniGUI :: Home

更多内容,我会陆续整理到我的帖子里的:

【整理】嵌入式Linux中常用的GUI(图形用户界面)系统

编辑于 2014-03-15 23:44

如果是MCU,或者单片机,可以试试 giveda.com提供的嵌入式图形引擎,那是一个可以跑在MCU上的图形库,提供的API类似Qt。

编辑于 2019-05-31 15:55

关注火娃一起学嵌入式,一起学习,一起成长~


本系列为:MCU 的 TOP 15 图形GUI库(共三篇)

(1)MCU 的 TOP 15 图形GUI库:选择最适合你的图形用户界面(一)


在嵌入式系统开发中,选择一个合适的图形用户界面(GUI)库是至关重要的。在屏幕上显示的时候,使用现成的图形库,这样开发人员就不需要弄清楚底层任务,例如如何绘制像素、线条、形状,如果再高级一点,则可以绘制某些对象,例如窗口、按钮等。

下面将介绍15个备受欢迎的嵌入式GUI库,分析它们的特点、优缺点、使用场景以及生态系统,以便开发人员能够更好地选择适合自己项目的GUI库。

1、LVGL

https://lvgl.io/

LittlevGL(LVGL) 是一款开源的嵌入式图形用户界面(GUI)库,专为嵌入式系统设计。LVGL以其轻量级、灵活性和强大的功能而备受开发者青睐,资源够的情况下可移植到所有MCU。



LVGL 是完全开源的,可以查看、修改、编译和调试底层源代码,附带 30 多个内置小部件,绘制画面非常的方便,配备强大的软件渲染引擎,可以使用最少的资源以矢量图形方式绘制抗锯齿小部件。

特点:

轻量级:LVGL以其卓越的轻量级设计而著称,适用于资源受限的嵌入式系统。即便在内存和处理器资源有限的情况下,LVGL也能够提供流畅的用户体验

开源:LVGL是一款开源的GUI库,基于MIT许可,使其成为开发者们的理想选择。用户可以自由修改、使用和分发LVGL,促进了广泛的社区支持。

丰富的图形元素和主题:LVGL提供了丰富的图形元素,包括按钮、标签、文本框等,以及可定制的主题支持。这使得开发者能够轻松创建出各种风格独特的用户界面。通过 30 多个小部件、抗锯齿、动画、多语言、阿拉伯语和波斯语文本、编码器和键盘使用等,使 UI 开发变得更容易。

跨平台:LVGL不仅支持多种硬件平台,还可以在不同操作系统上运行,提供了出色的可移植性。



使用场景:

资源受限的嵌入式系统:由于其轻量级设计,LVGL非常适用于那些资源受限的嵌入式系统,例如微控制器(MCU)和嵌入式Linux系统。

高度定制的GUI需求:LVGL的灵活性使其能够满足对GUI高度定制的需求。开发者可以轻松地调整和定制界面元素,以适应特定项目的设计要求。

学习难易程度:

尽管LVGL是一款功能强大的GUI库,但其学习曲线相对较陡峭。初学者可能需要一些时间来熟悉其API和功能,但一旦掌握,LVGL将成为一个强大而高效的工具。

生态支持:

LVGL拥有一个活跃的社区,提供广泛的文档、教程和示例代码。这为开发者提供了丰富的资源,以便更好地利用LVGL的功能和特性。

LVGL是一款出色的嵌入式GUI库,适用于各种嵌入式系统和应用。其轻量级设计、开源许可、跨平台支持以及丰富的图形元素和主题,使其成为开发者们构建现代、具有吸引力的嵌入式用户界面的理想选择。尽管学习曲线较陡峭,但通过社区的支持和文档的积累,LVGL的使用变得更加便捷。

2、MiniGUI

https://minigui.fmsoft.cn/zh

MiniGUI 是一款轻量级的开源图形用户界面(GUI)库,专为嵌入式系统设计。MiniGUI以其高度可定制适应性强的特点而备受开发者推崇。资源够的情况下可移植到所有MCU。免费用于非商业用途,使用部分指定的SOC可免费使用。



MiniGUI项目于1998年启动,既可以运行在30MHz主频的低端设备上,也可用于带GPU的高端设备上,广泛应用于消费电子于工业仪器仪表领域。

特点

轻量级设计:MiniGUI是一款轻量级的GUI库,专为嵌入式系统而设计。其小巧的体积使其适用于资源受限的环境,例如单片机和嵌入式Linux系统,最低

高度可定制:MiniGUI提供了高度可定制的皮肤和界面元素,使开发者能够轻松地适应项目的外观和感觉需求。

多平台支持:MiniGUI不仅支持嵌入式Linux系统,还可以运行在其他嵌入式平台上。eCos 和其他传统 RTOS (RT-Thread、RTEMS、FreeRTOS、VxWorks、ThreadX、Nucleus、pSOS、uC/OS-II、OSE 等),特别是 MiniGUI 作为 HybridOS 的窗口系统运行,这使得MiniGUI成为一个具有广泛可移植性的选择。



使用场景:

嵌入式系统:MiniGUI主要面向嵌入式系统,特别是那些资源有限、需要轻量级GUI的项目。它适用于多种硬件平台,包括一些较为简单的单片机。

定制UI需求:MiniGUI的高度可定制性使其非常适合需要特定外观和交互风格的项目。开发者可以根据项目需求自由调整皮肤和界面元素。

学习难易程度:

MiniGUI的学习曲线相对较平缓,这使得初学者能够较为迅速地上手使用。尽管文档可能相对较少,但其简洁的设计有助于用户快速理解和使用。

生态支持:

MiniGUI拥有一个积极的社区,提供了一些基础的文档和示例代码。虽然社区规模不如一些大型的GUI库,但对于MiniGUI的问题,仍然能够得到一定的支持。

MiniGUI作为一款轻量级开源嵌入式GUI库,注重于适应资源受限的环境,特别适合嵌入式系统和一些简单的项目。其高度可定制的特性使其在定制UI方面表现出色。虽然文档相对较少,但其简单直接的设计有助于开发者迅速上手。对于那些需要轻量级GUI的项目,MiniGUI是一个值得考虑的选择

3、uGUI

http://embeddedlightning.com/ugui/

uGUI 是一款轻量级的开源图形用户界面(GUI)库,专为资源受限的嵌入式系统设计。其注重简洁性和易用性,使其成为开发者在嵌入式环境下构建用户友好界面的理想选择。资源够的情况下可移植到所有MCU。



只要显示器能够显示图形,μGUI就不受特定显示技术的限制。因此,支持 LCD、TFT、E-Paper、LED 或 OLED 等显示技术。整个模块由两个文件组成:ugui.c和ugui.h,所以移植起来非常的方便

特点

轻量级设计:uGUI的设计目标是在资源有限的环境中运行,因此具有小巧的体积和较低的内存占用。这使其适用于单片机等资源受限的嵌入式系统。

易于集成和使用:uGUI的API设计简单直观,易于学习和使用。开发者可以迅速集成uGUI到他们的项目中,并通过简单的API调用实现基本的GUI功能。

可扩展性:虽然uGUI的核心设计简单,但它仍提供了一些可扩展的特性,如支持多种字体和颜色配置。这使得开发者可以通过简单的配置满足一些基本的定制需求。



使用场景:

简单嵌入式系统:uGUI适用于资源有限的简单嵌入式系统,特别是那些对内存和处理器资源有严格要求的项目。

快速原型设计:由于其易于集成和使用的特性,uGUI也可以用于快速原型设计,帮助开发者迅速搭建界面并验证概念。

学习难易程度:

uGUI的学习曲线相对较平缓,尤其适合初学者。其简单的API设计和清晰的文档使得开发者能够快速上手并开始构建GUI界面。

生态支持:

uGUI虽然规模相对小,但仍有一定的社区支持。用户可以在社区中获取一些基础的文档和示例代码,尽管相较于一些大型GUI库,支持和社区参与度相对较低。

uGUI是一款适用于资源受限嵌入式系统的轻量级GUI库。其简洁的设计和易用的API使其在简单项目或需要快速原型设计的情况下表现出色。然而,对于一些复杂的GUI需求,可能需要考虑更为功能丰富的GUI库。对于初学者或对资源有严格要求的项目,uGUI是一个简单而可靠的选择

4、GUISlice

https://github.com/ImpulseAdventure/GUIslice

GUISlice 是一款轻量级的开源嵌入式图形用户界面(GUI)库,专为资源受限的系统设计。它注重简洁性和易用性,旨在帮助开发者快速实现基本的嵌入式用户界面。资源够的情况下可移植到所有MCU。



特点

轻量级设计:GUISlice以小巧的体积低内存占用著称,纯C库,无动态内存分配,有一个用于生成布局的跨平台GUIslice Builder应用程序

易于使用:GUISlice的API设计简单直观,易于学习和使用。它提供了一些基本的图形元素,如按钮、文本框等,使得开发者能够迅速构建简单的用户界面。

支持触摸屏和非触摸屏:GUISlice支持触摸屏和非触摸屏设备,为开发者提供了更多的输入选项。



使用场景:

资源受限嵌入式系统:由于其轻量级设计,GUISlice非常适用于资源受限的嵌入式系统,如一些简单的MCU项目。

简单嵌入式用户界面:GUISlice适用于对用户界面要求相对简单的嵌入式项目,如温度计、遥控器等。

学习难易程度:

GUISlice的学习曲线相对较平缓。由于其专注于提供基本的图形元素和易用的API,开发者可以比较迅速地上手使用,特别是对于有一定嵌入式经验的开发者而言。



生态支持:

GUISlice的社区相对较小,但仍然提供了一些基本的文档和示例代码。用户可以在社区中获取支持,但相较于一些大型GUI库,社区参与度可能相对有限

GUISlice是一款专注于轻量级和简单嵌入式GUI的库,适用于一些对资源有限和用户界面需求相对简单的嵌入式项目。其易用性和小巧的体积使其成为一些简单嵌入式系统中的合适选择。然而,对于需要更复杂、功能丰富的用户界面的项目,可能需要考虑使用其他更全面的GUI库。

5、µGFX

https://ugfx.io/index

µGFX 是一个用于显示器和触摸屏的轻量级嵌入式库,提供构建功能齐全的嵌入式 GUI 所需的一切。该库非常小而且速度很快,因为每个未使用的功能都被禁用并且没有链接到完成的二进制文件中



µGFX设计注重性能可移植性,使得开发者能够轻松地在各种硬件平台上实现优秀的图形用户界面(GUI)。资源够的情况下可移植到所有MCU。免费版本可用于非商业用途。

特点

跨平台支持:µGFX支持多种嵌入式系统和操作系统,包括裸机环境、FreeRTOS、ChibiOS等。这为开发者提供了广泛的硬件和软件平台选择。

硬件加速:µGFX充分利用硬件加速技术,提高了图形渲染性能,使其适用于一些对性能有高要求的嵌入式应用。

显示类型:单色、灰度、彩色、电阻式、电容式或根本没有触摸屏。µGFX 可使用的显示器类型没有限制

开放源代码:µGFX是一款开源图形库,基于MIT许可,开发者可以自由使用、修改和分发代码。这促进了社区的积极参与和贡献。

多操作系统支持:除了支持多种嵌入式系统外,µGFX还兼容多个主流的操作系统,包括Windows、Linux等,方便开发者在桌面环境进行GUI开发和调试。



使用场景:

跨平台嵌入式项目:µGFX适用于需要在不同硬件平台和操作系统上运行的嵌入式项目,为开发者提供了灵活的选择。

高性能要求的应用:µGFX的硬件加速特性使其非常适合对图形性能有高要求的嵌入式应用,如医疗设备、汽车仪表盘等。

学习难易程度:

µGFX的学习曲线相对较平缓,尤其是对有一定嵌入式开发经验的开发者而言。它提供了清晰的文档和范例,帮助用户快速上手。



生态支持:

µGFX拥有活跃的社区和强大的生态系统。用户可以在社区中获取支持、交流经验,并获得额外的文档和教程。社区的积极参与使µGFX得以不断改进和更新。

µGFX是一款强大而灵活的嵌入式图形库,适用于跨平台的嵌入式项目。其硬件加速和跨平台支持使其在各种应用场景中表现出色。对于需要高性能、多平台支持的嵌入式GUI项目,µGFX是一个强大的选择。

篇幅问题,本期介绍5个,下一期继续介绍。

往期推荐




发布于 2023-12-19 17:35

MINIGUI啊

发布于 2019-09-21 14:30

这个是根据你的平台选择的。要综合考虑硬件平台和软件平台。

1. 如果是单片机,考虑使用ucGUI或者其他一些轻量级的GUI(名字我忘了)

2. 如果是Linux且资源丰富的话,采用MiniGUI或者QT都可以。具体要看UI需求

发布于 2013-11-15 11:02
非常炫酷的嵌入式GUI ------ LVGL V8.1.0
1.3 万播放 · 6 赞同
LVGL值得你拥有
发布于 2021-12-27 20:05· 7372 次播放

1.信号量是什么

操作系统通常有3种的任务通信方式:

1、信号量,用于多任务之间的同步。
2、互斥量,用于避免多任务之间共享资源的竞争。
3、消息队列,用于多任务之间的收发消息机制。

信号量在操作系统中用于实现任务同步,通过同步机制可以实现多个任务合作,让多任务之间按照先后顺序执行。

这种机制就像我们生活中的交通红绿信号灯。汽车停在红绿信号灯路口,当红绿信号灯变成绿灯时,汽车启动并通过路口。这种行为逻辑并不是红绿信号灯亮的时候通过光电效应触发汽车的油门让汽车启动,而是因为司机看到了红绿信号灯变为绿灯,司机踩下油门启动汽车通过路口。司机看到红绿信号灯变为绿灯,随后踩下油门这个一组动作就是同步


信号量是在多任务环境下使用的一种机制, 它负责协调各个任务, 以实现多个任务合作。通常情况下信号量可以分为以下两类:

1、二进制信号量:只允许信号量取0或1值,其只能被一个任务获取。
2、整型信号量:信号量取值是整数,可以被多个任务同时获得,直到信号量的值变为0。

信号量通过一个计数器控制任务访问,如果信号量的值是一个非负整数,任务获取它后会将该整数减1。如果信号量的计数器大于0,则访问被允许,计数器减1;如果号量的计数器为0,则访问被禁止,所有试图获取它的任务都将处于等待状态。

2.信号量操作

信号量的两个基本操作:释放(发送)信号量,获取(等待)信号量。

释放信号量的流程如下:

1、判断是否有任务等待该信号量。
2、若有任务等待该信号量,则将任务从挂起表中移除加入就绪表,并根据优先级执行任务切换。
3、若无任务等待该信号量,则将该信号量设置为“有效”。

获取信号量的流程如下:

1、判断该信号量是否为“有效”。
2、若该信号量为“无效”,将任务从就绪表中移除加入挂起表,切换任务。
3、若该信号量为“有效”,则继续运行。

例如任务A需要等待信号甲再执行一个特定操作,当信号甲为“无效”时任务A进入休眠状态,操作系统让任务B运行,假设任务A优先级高于任务B,当任务B释放信号甲后(信号为“有效”),操作系统会暂停任务B运行任务A,使得任务A的特定动作得以执行,运行图如下:

3.工程实例分析

假设现在有这样一个项目:利用光电开关实现一个药品流水线上的电子计数仪。当药品经过传感器时仪表计数值加一,显示器显示计数数值,同时使用ESP8266模块将数据发送给服务器。


光电开关的工作原理就是当有障碍物挡住光信号时光电开关输出高电平,当无障碍物挡住光信号时光电开关输出低电平


软件使用了分模块的设计方法,每个功能独立成一个模块,提高了软件系统的扩展性。每个功能模块采用了3层的分层设计,底层处理硬件相关操作,中间层用来进行驱动控制和逻辑控制,顶层的用来处理与其他业务模块的数据交互,分层设计提高了软件系统的移植性。


程序分为3个任务

1、显示任务,完成显示计数的数值的功能。
2、WIFI任务,通过WIFI模块将计数数值发送给服务器。
3、GPIO任务,使用中断功能捕获光电开关的电平信号。

3个任务的优先级如下:


软件设计思路:当有药品经过光电开关时,产生一个上升沿信号,MCU捕获上升沿中断信进入中断程序更新计数数值(计数值加一),同时中断程序发送信号量给WIFI任务,WIFI任务将计数数值发给服务器,软件系统在空闲时间内执行显示任务。运行时序图如下:


由时序图可系统运行时,WIFI任务优先级较高先运行,WIFI任务等待信号时进入休眠状态,操作系统进行任务切换执行低优先级显示任务。当光电开关产生有效电平信号后GPIO中断程序开始执行,中断程序将计数值加一(全局变量),然后向WIFI任务发送信号,WIFI任务被执行,WIFI任务向服务器发送计数数值后等待信号量,WIFI任务进入休眠状态,操作系统进行任务切换执行低优先级显示任务。

4.信号量代码分析

参考FreeRTOS源码(删减部分代码),分析发送信号量函数和获取信号量函数的源码,这两个函数名如下:

#define xSemaphoreGive( xSemaphore )  xQueueGenericSend( ( QueueHandle_t ) ( xSemaphore ), NULL, semGIVE_BLOCK_TIME, queueSEND_TO_BACK )
xSemaphoreGive( xSemaphore )
 
#define xSemaphoreTake( xSemaphore, xBlockTime )  xQueueSemaphoreTake( ( xSemaphore ), ( xBlockTime ) )
xSemaphoreTake( xSemaphore, xBlockTim )

发送信号量函数分析如下(删减部分代码):

BaseType_t xQueueGenericSend( QueueHandle_t xQueue, const void * const pvItemToQueue, TickType_t xTicksToWait, const BaseType_t xCopyPosition )
{
 BaseType_t xEntryTimeSet = pdFALSE, xYieldRequired;
 TimeOut_t xTimeOut;
 Queue_t * const pxQueue = xQueue;
 /* 循环判断 */
 for( ;; )
 {
  taskENTER_CRITICAL();
  {
   /* 判断该信号量数值 */
   if( ( pxQueue->uxMessagesWaiting < pxQueue->uxLength ) || ( xCopyPosition == queueOVERWRITE ) )
   {
    traceQUEUE_SEND( pxQueue );
    /* 读取信号量数值  */
    UBaseType_t uxPreviousMessagesWaiting = pxQueue->uxMessagesWaiting;
    xYieldRequired = prvCopyDataToQueue( pxQueue, pvItemToQueue, xCopyPosition );
    /* 判断列表是否为空 */
    if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToReceive ) ) == pdFALSE )
    {
     /* 将任务从挂起表中移除,并将任务加入就绪表 */
     if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToReceive ) ) != pdFALSE )
     {
      /* 设置任务切换标志 */
      queueYIELD_IF_USING_PREEMPTION();
     }
     else
     {
      mtCOVERAGE_TEST_MARKER();
     }
    }
    else if( xYieldRequired != pdFALSE )
    {
     queueYIELD_IF_USING_PREEMPTION();
    }
    else
    {
     mtCOVERAGE_TEST_MARKER();
    }
   }
   taskEXIT_CRITICAL();
 
 
   vTaskSuspendAll();
   prvLockQueue( pxQueue );
  } 
 }
}

获取信号量函数分析如下(删减部分代码):

BaseType_t xQueueSemaphoreTake( QueueHandle_t xQueue, TickType_t xTicksToWait )
{
 BaseType_t xEntryTimeSet = pdFALSE;
 TimeOut_t xTimeOut;
 Queue_t * const pxQueue = xQueue;
 /* 循环判断 */
 for( ;; )
 {
  taskENTER_CRITICAL();
  {
   /* 读取信号量数值  */
   const UBaseType_t uxSemaphoreCount = pxQueue->uxMessagesWaiting;
   /* 信号量数值大于0 */
   if( uxSemaphoreCount > ( UBaseType_t ) 0 )
   {
    traceQUEUE_RECEIVE( pxQueue );
    /* 信号量数值减一 */
    pxQueue->uxMessagesWaiting = uxSemaphoreCount - ( UBaseType_t ) 1;
    /* 判断列表是否为空 */
    if( listLIST_IS_EMPTY( &( pxQueue->xTasksWaitingToSend ) ) == pdFALSE )
    {
     /* 将挂起表中的第一个任务加入就绪表 */
     if( xTaskRemoveFromEventList( &( pxQueue->xTasksWaitingToSend ) ) != pdFALSE )
     {
      /* 设置任务切换标志 */
      queueYIELD_IF_USING_PREEMPTION();
     }
     else
     {
      mtCOVERAGE_TEST_MARKER();
     }
    }
    else
    {
     mtCOVERAGE_TEST_MARKER();
    }
 
    taskEXIT_CRITICAL();
    
    return pdPASS;
   }
 
  }
  taskEXIT_CRITICAL();
 
  vTaskSuspendAll();
  prvLockQueue( pxQueue );
 } 
}

未完待续…
实时操作系统系列将持续更新
创作不易希望朋友们点赞,转发,评论,关注。
您的点赞,转发,评论,关注将是我持续更新的动力
作者:李巍
Github:liyinuoman2017
CSDN:liyinuo2017
今日头条:程序猿李巍

发布于 2023-09-18 20:27

建议关注: slint-ui.com/

slint-ui 是rust基金会银级会员,同时与几家嵌入式相关的平台厂商有合作关系。开发之初就原生支持多种语言,主要支持rust/c++/NodeJs。

另专写了一篇文章做了更详细的介绍: Slint ui介绍。

开发人员来自QT;界面开发语言类似qt的qml;开发方式类似QT的qml+cpp, 采用slint+cpp/slint+rust方式; 官网有运行在stm32上的视频,以及以wasm方式运行在浏览器上的在线体验demo。slint与qml不同的是,slint最终是全部转换成了本地语言代码,而qml到目前为止,也只能做到一小部分转换成cpp代码。

基本控件完备,目前版本0.3.4(2023.02),下一版本1.0正式版。版本正在快速迭代。但缺点是控制细粒度赶QT还有较大差距。

slint rust:文档: slint-ui.com/releases/0

slint c++文档: slint-ui.com/releases/0

建议rust/cpp文档对比着看,个人感觉,c++文档更易懂一些,可能与本人更熟悉cpp有关。

当前已经支持的控件(下面图片引用自cpp的文档页面)

slint架构:

举例:main.slint:

import {    
    GroupBox, LineEdit, Button, 
    Slider, SpinBox,
    StandardTableView    
} from "std-widgets.slint";

MainWindow := Window{
    title: "Main Window";
    width: 600px;
    height: 500px;
    VerticalLayout { 
        // line comment
        /* this is a 
            /* single */ 
            comment 
        */
        spacing: 5px;
        padding-left: 25px;
        padding-right: 25px;
        alignment: center;
        Button {
            text: "Click Me";
            clicked => { self.text = "Clicked"; }
        }
        Text { 
            height: 50px;
            font-size: 27px;
            font-weight: 700;
            color: #6776FF;  
            text: "line text";
         }
        HorizontalLayout {  
            width: parent.width;
            height: 25px;  
            alignment: center; 
            spacing: 5px;   
            
            Rectangle { 
                width: 24px;
                height: 24px;
                border-radius: width / 2;
                background: red;
                
                Rectangle { 
                    width: 12px;
                    height: 12px;
                    border-radius: width / 2;
                    background: white;
                    x: parent.width/4;
                    y: parent.height/4;
                    
                }
             }         
            Slider {
                //width: parent.width * 3 / 8;
                height: parent.height;
                value: 42;
            }
            SpinBox {
                //width: parent.width * 3 / 8;
                height: parent.height;
                value: 42;
            }
        }
        GroupBox{
            title:"Group Box";
            height: 100px;            
            LineEdit {
                placeholder-text: "enter text";
            }
        }
        
        Rectangle  {
            width: parent.width * 3 / 4;
            height: 202px;
            border-color: #86e086;
            border-width: 1px;
            StandardTableView {
                width: parent.width;
                height: 200px;
                columns: [
                    { title: "colum 1" },
                    { title: "colum 2" },
                ];
                rows: [
                    [{ text: "item 11" }, { text: "item 12" },],
                    [{ text: "item 21" }, { text: "item 22" },],
                    [{ text: "item 31" }, { text: "item 32" },]
                ];
            }
        }  
                  
           
        HorizontalLayout {
            spacing: 5px;
            height: 30px;
            Rectangle { background: red; width: 20px; }
            Rectangle { background: blue; min-width: 10px; }
            Rectangle { background: yellow; horizontal-stretch: 1; }
            Rectangle { background: green; horizontal-stretch: 2; }
        }
    }
}

main.rs

slint::include_modules!();

fn main() {
    MainWindow::new().run();
}

build.rs

fn main() {
    slint_build::compile("ui/main.slint").unwrap();
}

cargo.toml

[package]
name = "mytest"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
slint = "0.3.4"
[build-dependencies]
slint-build = "0.3.4"

执行命令:cargo run,运行效果如下图,以上所有程序开发均在vs code下完成(依赖slint官方插件)


rust还不怎么会,slint怎么与rust/c++交互还没有研究

slint这种写界面的方式谁不喜欢呢。最重要的是,界面最终转换成了rust/cpp,而不是简单的脚本解释运行,也没用到v8之类的浏览器、 虚拟机技术。

slint-ui是嵌入式开发的福音,抛开rust不说,由于支持cpp,从此再也不用忍受lvgl/ minigui之类各种各样的一大票用c搞出来的杂七杂八蹩脚又折磨人的UI框架(c框架心智负担太重,且很少也很难做到界面与逻辑分离,一旦需求变动几乎是灾难)。也许有人会说既然用cpp了为什么不用QT, QT太庞大,不适合没有操作系统的单片机。那为什么不用QT for mcu呢? qt for mcu 我没用过,但它是商业软件不开源,slint-ui支持GPLv3许可证。

MCU支持:

当前版本下mcu相关API只在rust中可用,以后会开发c++版本的api,官方是这样说的:

These new platform abstraction and rendering APIs are only available for the Rust programming language today; C++ is in our future plans

关于移植到MCU相关的信息可以看一下官方文章及项目例程:

slint::docs::mcu - Rust

Porting the Slint UI Toolkit to a Microcontroller with 264K RAM — Slint Blog

slint-mcu-rust-template.git

stm32芯片-有DMAhttps://www.zhihu.com/video/1606593661797572608

编辑于 2023-02-08 17:44

就我所了解的,简单的并且flash容量不大,就用directfb,界面丰富flash资源宽松的用qt,目前我们搞的产品中这两者都在用。

发布于 2013-04-21 20:28

emwin如何呢?

发布于 2014-03-10 22:53

Qt跨平台

发布于 2013-11-14 17:05

什么叫嵌入式操作系统界面库

发布于 2019-09-30 15:24

把Android的Java层砍掉,用本地框架层的图形库libskia.so和显示服务器SurfaceFlinger(调用libgui.so库实现客户端)。Skia内置了一套界面 UI 库,组件包括 Window,Menu, TextBox, ListView, ProgressBar, Widget, ScrollBar,TagList,Image 等,也可以根据自己的需要对其进行扩展。这个方案经过了全球几十亿用户的考验!

编辑于 2014-03-24 15:05