经过网上辛苦搜索,我们可以了解到 PersimmonUI
官方简介:RT-Thread/ Persimmon是国内主导开发的实时线程操作系统RT-Thread中的图形用户界面,是一款面向嵌入式系统的,具备多窗口,多线程的,类似Android界面效果的C++ GUI,构建于RT-Thread物联网操作系统之上。目前也已经发展到了RT-Thread/Persimmon 2.0,支持设计器及脚本方式开发尽管稍逊于安卓系统显示效果,但其资源占用率相比Linux方案低一个数量级,比安卓系统更是低几个数量级,成本也不高,适用于基于arm Cortex-M7/M4内核MCU、基于arm 9/arm 11/Cortex-A7内核的应用处理器/AI芯片之上。目前在NXP、全志等芯片上均有采用RT-Thread/Persimmon产品,在智能家居、楼宇自动化系统/设备以及音视频系统中得到了广泛应用。
目测,它可以在很多 arm 架构平台上运行。虽然是闭源库,但终究是提供对应平台上的库文件的吧。那么,是不是随便选一款芯片,但凡是相同架构就存在支持的理论基础了?
下面在 STM32F767 芯片上摸索一下怎么使用 PersimmonUI。原始过程见论坛问题
首先,在 env 开发环境里,使用 scons --pyconfig
命令,打开 RT-Thread 配置工具。定位到 “RT-Thread online packages -> system packages -> Persimmon UI”,可以看到,它支持这么几类 arm 核心架构。depends on ARCH_ARM_CORTEX_M4 || ARCH_ARM_CORTEX_M7 || ARCH_ARM_CORTEX_A || ARCH_MIPS_XBURST || ARCH_ARM_ARM9
然后,当我们下载了 Persimmon UI 源码之后,在它的源码目录下,打开 SConscript 文件,我们还会发现它支持 BOARD_X1000_REALBOARD SOC_LPC54608 SOC_IMXRT1052 SOC_NUC972 这几类。和上面的分类方式截然不同,一时间慌乱了。
其次,经过百度,我们又会发现,如下对应关系(未找到 CORTEX_A 架构对应的 PersimmonUI 库):
序号 | 芯片 | 架构 |
---|---|---|
1 | X1000 | ARCH_MIPS_XBURST |
2 | LPC54608 | ARCH_ARM_CORTEX_M4 |
3 | IMXRT1052 | ARCH_ARM_CORTEX_M7 |
4 | NUC972 | ARCH_ARM_ARM9 |
以上为准备工作,接下来,再次百度芯片 STM32F767 ,了解到它也是 CM7 架构芯片。那么问题来了,可以在 STM32F767 上像 IMXRT1052 那样使用 PersimmonUI 吗?
第一步、使用 scons --pyconfig
命令,选用 “PersimmonUI ”、dfs(为了选用posix,可能从 4.1.0 不是这个样子了)、libc、C++ features(不用选c++11 threading 支持)
第二步、编辑 PersimmonUI 源码目录下的 SConscript 文件添加如下代码:
elif GetDepend('SOC_SERIES_STM32F7'):
LIBPATH = [cwd + '/arm/imxrt1052']
if rtconfig.CROSS_TOOL == 'gcc':
LIBS = ['Persimmon_gcc']
elif rtconfig.CROSS_TOOL == 'keil':
LIBS = ['Persimmon_rvds']
else :
LIBS = []
第三步、编辑 STM32F767 的 rtconfig.py 文件:
if PLATFORM == 'gcc':
...
# 在 PLATFORM == 'gcc' 这个 if 分支最后添加如下一行,增加编译选项。
# module setting
CXXFLAGS += ' -Woverloaded-virtual -fno-exceptions -fno-rtti '
如果不修改这一步,会出现如下错误,或许只添加 -fno-rtti
一个新选项就够了。
build\packages\persimmon-latest\examples\images-animation\animation.o:(.rodata._ZTI12AnimationWin+0x8): undefined reference to `typeinfo for Persimmon::Window'
collect2.exe: error: ld returned 1 exit status
scons: *** [rt-thread.elf] Error 1
scons: building terminated because of errors.
第四步、scons
经过以上几步之后,反正我可以在 STM32F767 平台上编译 PersimmonUI 应用了。
通过添加 STM32F767 支持的过程,我们发现,PersimmonUI 对 arm 架构支持姿势有点儿不够友好。它开发的本意是支持某几种特定的 arm 核架构,但是使用的时候我们需要根据芯片型号进行选择。类似 STM32F767 本可以无缝支持的,但也需要我们对它进行修改。
进行第五步修改,非必须但很有必要,再次编辑 PersimmonUI 源码目录下的 SConscript 文件如下:
if GetDepend('ARCH_MIPS_XBURST'):
LIBPATH = [cwd + '/mips/xburst']
if rtconfig.CROSS_TOOL == 'gcc':
LIBS = ['Persimmon_gcc']
elif rtconfig.CROSS_TOOL == 'keil':
LIBS = ['Persimmon_rvds']
else :
LIBS = []
elif GetDepend('ARCH_ARM_ARM9'):
LIBPATH = [cwd + '/arm/arm9']
if rtconfig.CROSS_TOOL == 'gcc':
LIBS = ['Persimmon_gcc']
elif rtconfig.CROSS_TOOL == 'keil':
LIBS = ['Persimmon_rvds']
else :
LIBS = []
elif GetDepend('ARCH_ARM_CORTEX_M4'):
LIBPATH = [cwd + '/arm/cortex-m4']
if rtconfig.CROSS_TOOL == 'gcc':
LIBS = ['Persimmon_gcc']
elif rtconfig.CROSS_TOOL == 'keil':
LIBS = ['Persimmon_rvds']
else :
LIBS = []
elif GetDepend('ARCH_ARM_CORTEX_M7'):
LIBPATH = [cwd + '/arm/cortex-m7']
if rtconfig.CROSS_TOOL == 'gcc':
LIBS = ['Persimmon_gcc']
elif rtconfig.CROSS_TOOL == 'keil':
LIBS = ['Persimmon_rvds']
else :
LIBS = []
else :
LIBPATH = []
LIBS = []
把 arm 和 mips 目录下,以芯片型号为文件夹名命名改为芯片核心架构命名方式。如 '/mips/xburst' '/arm/arm9' '/arm/cortex-m4' '/arm/cortex-m7' 等等。
这样一来,换成其它芯片,只有核心一样,就可以无缝启用 PersimmonUI 了
以上修改在 stm32f767-atk-apollo imxrt1052-atk-commander 测试 cortex-m7 版本成功。
在stm32f429-atk-apollo lpc54608-LPCXpresso 测试 cortex-m4 版本出现错误,还是有一些未定义符号错误。这个不知道是不是库文件的问题。以下是 lpc54608-LPCXpresso 编译错误信息。
build\packages\persimmon-latest\examples\images-animation\animation.o: In function `AnimationWin::AnimationWin()':
D:\rt-thread-4\bsp\lpc54608-LPCXpresso/packages\persimmon-latest\examples\images-animation/animation.cpp:26: undefined reference to `Persimmon::ImageBox::ImageBox(Persimmon::Image*)'
build\packages\persimmon-latest\examples\images-animation\animation.o:(.rodata._ZTV12AnimationWin+0x48): undefined reference to `Persimmon::Window::dealCmd(rtgui_event_command*)'
packages\persimmon-latest\arm\cortex-m4\libPersimmon_gcc.a(pm_rect.o): In function `Persimmon::Rect::moveto(int, int)':
E:\rt-thread\bsp\lpc54608-LPCXpresso/persimmon_src/pm_rect.cpp:110: undefined reference to `rtgui_rect_moveto'
👍👍👍👍