0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

全网疯传!树莓派GUI开发竟然可以这么轻量?

上海晶珩电子科技有限公司 2025-04-05 09:36 次阅读
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

嘿,各位树莓派的发烧友们!今天我要和大家分享一个超酷的技巧——如何在没有桌面环境的情况下,在树莓派上开发GUI应用。想象一下,你的树莓派就像一个超级英雄,而我们要给它装上一个炫酷的“面甲”,让它不仅能跑,还能飞!而且,这个“面甲”不会拖慢它的速度,因为我们不装笨重的桌面环境!

71b953ec-11be-11f0-9434-92fbcf53809c.png

framebuffer:树莓派的“魔法画布”

首先,得聊聊framebuffer这个神奇的东西。framebuffer就像是Linux系统给我们的一个魔法画布,你可以直接在上面画画。在树莓派上,HDMI接口对应的是/dev/fb0这个魔法画布。如果你接的是普通的显示器或者电视,直接往这个文件里写数据,屏幕上就会出现你画的内容,简直不要太神奇!

如果你用的是SPI接口的屏幕,那你就有了第二个魔法画布/dev/fb1。这时候,你需要在/boot/config.txt文件里设置一下分辨率,让这两个画布的大小一样。不然的话,就像给一个方形的画布硬塞进一个圆形的框里,画面会变形,看着就别扭!

framebuffer_width=480framebuffer_height=320

在/boot/config.txt中,我们创建一个自定义的HDMI模式并设置分辨率。同样,为你的屏幕选择合适的分辨率。如果你希望同时在LCD屏幕和外部显示器上以不同分辨率显示,请不要这样做。

# 当LCD连接时,有两个framebuffer:## - /dev/fb0 - 代表HDMI输出。这个输出支持硬件加速,# 因此应该是GUI的目标。# - /dev/fb1 - 代表LCD输出。## 以下设置启用了一个自定义模式(模式87),将HDMI# 输出设置为与LCD相同的分辨率。这很有用,因为应用程序# 可以以硬件加速的输出为目标,然后使用raspi2fb工具将输出镜像到LCD。## HDMI组强制DMT输出,即使在HDMI输出上也是如此。DMT是显示器的标准,# 而CEA是电视的标准。hdmi_cvt480320601000hdmi_mode=87hdmi_group=2

低级操作:直接往framebuffer上画画

如果你是编程大神,可以直接用C语言操作framebuffer。想象一下,你手里拿着一支魔法画笔,直接在画布上画画。不过,这个过程有点复杂,需要你用ioctl这个魔法咒语来获取画布的信息,比如宽度和高度。然后,你就可以用魔法画笔在画布上涂颜色了。不过,这个过程对新手来说有点难,别担心,后面我会介绍一个更简单的工具。

71e77dd0-11be-11f0-9434-92fbcf53809c.png

通过framebuffer显示图形的步骤如下:

1. 打开对应于你想要使用的显示设备的/dev/fbX文件。

2. 使用ioctl(这是一个允许与某些设备通信的Linux系统调用)来获取有关framebuffer的信息。具体方式是设备特定的,但framebuffer允许获取诸如宽度和高度等信息。

3. 写入字节到文件。确切的字节序列取决于framebuffer的颜色深度。

有一个关于使用framebuffer的绝佳指南,我强烈推荐阅读。在按照示例操作时,我需要记住以下几点:

要访问framebuffer,你需要以root身份运行。这并不理想,我们可以通过放松这一要求来解决,但目前请使用sudo运行代码示例。我将在下一节讨论替代方案。

该指南假设你正在显示到/dev/fb0。因为我正在使用基于SPI的屏幕,所以我实际上想要显示到/dev/fb1,所以我相应地修改了代码示例。

framebuffer的颜色深度将取决于你正在使用的屏幕,但通常HDMI输出(/dev/fb0)将运行在32bpp(每像素位数),而许多(所有?)SPI屏幕将运行在16bpp。

镜像魔法:让两个framebuffer同步显示

如果你有两个framebuffer,比如一个HDMI和一个SPI屏幕,你可以用raspi2fb这个魔法工具,把一个画布上的内容复制到另一个画布上。就像用魔法镜子把一个画布上的画面反射到另一个画布上一样。不过,别忘了先设置好分辨率,否则画面会像被挤扁的气球一样变形。

如果你尝试运行raspi2fb,你会遇到权限错误。原因是当前用户没有权限与framebuffer交互。我们可以通过查看framebuffer文件的所有者和组来查看这一点:

$ls-l /dev/fb*crw-rw---- 1 root video 29, 0 Jan 1 22:48 /dev/fb0crw-rw---- 1 root video 29, 1 Jan 13 21:52 /dev/fb1

文件由root拥有,因此需要使用sudo运行。然而,这存在安全问题,因为你不想让你的应用程序以root身份运行!幸运的是,framebuffer文件的组是video,所以你只需要将用户添加到该组。例如,对于我的用户:

usermod -a-Gvideoavik

现在你可以无需root权限运行raspi2fb。

如上所述,如果你设置了SPI屏幕,并将系统配置为将控制台显示到fb1。当raspi2fb将HDMI屏幕镜像到fb1时,控制台和raspi2fb(以及因此在HDMI屏幕上运行的任何内容)都在更新同一个framebuffer。这会导致文本光标出现在屏幕上。

一个framebuffer感知的应用程序应该禁用文本光标,但它只能在控制台显示在与应用程序相同的framebuffer上时这样做。但是,如果应用程序显示在fb0,而控制台显示在fb1,文本光标仍然存在。解决方法是将控制台显示在fb0,与应用程序一起。

你可以通过编辑/boot/cmdline.txt来实现这一点,但我想只在运行raspi2fb时切换控制台的输出。幸运的是,你可以使用con2fbmap在系统运行时切换控制台显示。因此,你可能会执行以下操作:

con2fbmap10 # 将控制台切换到fb0raspi2fb # 将fb0镜像到fb1# 在单独的窗口或SSH会话中,运行一个显示到fb0的应用程序。# 应用程序完成后,停止raspi2fb,然后:con2fbmap11 # 将控制台切换回fb1

注意,con2fbmap也需要访问framebuffer,因此要么你需要以root身份运行,要么你需要是video组的成员。

Raylib:让GUI开发变得简单又有趣

说到这儿,我得隆重介绍一下Raylib这个神器。它就像一个魔法工具箱,让你不用直接操作framebuffer,也能画出漂亮的图形界面。而且,它支持硬件加速,就像给你的树莓派装上了火箭助推器,速度超快!

它具有以下优势:

Raylib支持多个平台。这意味着我可以在笔记本电脑上开发应用程序,渲染到屏幕上的窗口,然后在树莓派上部署该应用程序,无需任何更改。

没有外部依赖项。这使得在树莓派上编译变得容易,也可以理解库代码本身,因为该库非常自包含。

Raylib支持硬件加速,提供出色的性能。

Raylib包含功能,例如文本渲染支持,而这些功能我本来需要自己开发。

7253b2a2-11be-11f0-9434-92fbcf53809c.png

构建Raylib:魔法工具箱的组装

要使用Raylib,你需要先在树莓派上构建它。想象一下,你正在组装一个魔法工具箱,需要按照说明书一步一步来。构建过程中,你可能需要修改一些配置文件,比如把SUPPORT_BUSY_WAIT_LOOP这行注释掉,这样你的应用就不会占用100%的CPU,而是像一个聪明的魔法师,只在需要的时候才使用魔法。

使用Raylib开发应用

默认情况下,Raylib使用“忙等待”循环。这意味着,在你的应用程序完成渲染后,对于该帧的其余时间,Raylib会不断检查是否已经过去足够的时间以开始下一帧。这会导致高CPU使用率。

多个GitHub作者提到现在支持“睡眠”等待。在这种实现中,库设置一个计时器,并要求操作系统在经过一定时间后唤醒应用程序。

需要注意的是,这种实现不是默认的,你必须注释掉一行并重新构建库:

// 在raylib/src/config.c中注释掉以下行:#defineSUPPORT_BUSY_WAIT_LOOP

(但如果你使用CMake而不是Make,你可能需要在src/config.c.in中进行此更改。)

通过此更改,我发现我的应用程序在没有进行任何密集计算的情况下,CPU使用率为1-3%。

如果你查看用于构建Raylib示例应用程序的Makefile,你会发现许多平台特定的选项。因为Raylib支持如此多的平台,Makefile相当大。

当你构建自己的应用程序时,你需要指定几个选项。因为我没有运行任何make install类型的命令来构建Raylib,所以库的必要文件位于我下载Raylib的目录中。

我从官方Makefile开始,移除了我不需要的平台支持,只剩下以下必要的选项。

首先,我们定义一些编译器标志:

-std=c99:定义C语言模式(1999年修订版的标准C)

-D_DEFAULT_SOURCE:与-std=c99一起在Linux上使用,用于timespec,这是用于与时间相关的功能。

CFLAGS= -std=c99 -D_DEFAULT_SOURCE

接下来,我们需要告诉编译器在哪里找到定义库的数据结构和函数的Raylib头文件。这里,RAYLIB_PATH指的是你下载Raylib的位置。

INCLUDE_PATHS=-isystem$RAYLIB_PATH/src \ -isystem$RAYLIB_PATH/src/external# 在树莓派上,你还需要指定在哪里找到一些头文件# 这些头文件在不同位置。这些头文件被Raylib使用。INCLUDE_PATHS+=-I/opt/vc/includeINCLUDE_PATHS+=-I/opt/vc/include/interface/vmcs_host/linuxINCLUDE_PATHS+=-I/opt/vc/include/interface/vcos/pthreads

然后,我们需要告诉编译器在哪里找到编译后的库。如果你查看Raylib发行版中的src目录,你会发现构建库已经创建了一个libraylib.a文件。这就是我们将链接的文件。

不同平台的附加依赖库有所不同。例如,在桌面Linux上,我们是使用X,但在树莓派上则不是。

告诉编译器在哪里找到libraylib.aLDFLAGS = -L$RAYLIB_PATH/srcLDFLAGS += -L/opt/vc/lib # 在树莓派上需要# 在桌面Linux上LDLIBS = -lraylib -lm -lpthread -ldl -lrt -lX11# 在树莓派上LDLIBS = -lraylib -lbrcmGLESv2 -lbrcmEGL -lpthread -lrt -lm -lbcm_host -ldl

现在,你可以调用编译器:

gcc-o app app.c$CFLAGS$INCLUDE_PATHS$LDFLAGS$LDLIBS

实际上,我指定了更多的标志,比如-Wall以发出更多的警告,但上述是最低要求。

触摸屏校准:让触摸屏听话

如果你的树莓派有触摸屏,那你就需要校准它,让触摸屏知道你的手指在哪儿。这个过程有点像训练一只小狗,基本方法是使用tslib库来获取原始触摸事件,根据一些过滤器和校准设置进行转换,然后创建一个新的触摸事件流,Raylib可以从中读取。

72920c50-11be-11f0-9434-92fbcf53809c.png

在我们开始之前,注意tslib操作的是/dev/input/eventX文件,就像framebuffer文件一样,这些文件用于与触摸屏设备交互。与framebuffer文件一样,要与触摸事件文件交互,我们需要必要的权限:

$ls-l /dev/input/event*crw-rw---- 1 root input 13, 64 Jan 1 22:48 /dev/input/event0

注意input组,所以我们将当前用户添加到该组。例如,对于我:

usermod -a-Ginputavik

接下来,tslib在Rasbian软件包仓库中可用,但版本太旧,无法满足我们的需求。因此,我们需要从源代码构建它:

sudo apt install automake libtoolgitclonegit://github.com/kergoth/tslib.gitcdtslib./autogen.sh./configuremakesudo make install

最后,我们需要校准触摸屏,测试它并创建一个新的事件流,Raylib可以从中读取。我发现这些命令需要稍作修改,与上面链接的指南中的命令有所不同。

#校准sudo \ LD_LIBRARY_PATH=/usr/local/lib \ TSLIB_FBDEVICE=/dev/fb1 \ TSLIB_TSDEVICE=/dev/input/event0 \ TSLIB_CALIBFILE=/etc/pointercal\ TSLIB_CONFFILE=/etc/ts.conf \ TSLIB_PLUGINDIR=/usr/local/lib/ts\ ts_calibrate# 测试sudo \ LD_LIBRARY_PATH=/usr/local/lib \ TSLIB_FBDEVICE=/dev/fb1 \ TSLIB_TSDEVICE=/dev/input/event0 \ TSLIB_CALIBFILE=/etc/pointercal\ TSLIB_CONFFILE=/etc/ts.conf \ TSLIB_PLUGINDIR=/usr/local/lib/ts\ ts_test# 创建新的事件流sudo \ LD_LIBRARY_PATH=/usr/local/lib \ TSLIB_FBDEVICE=/dev/fb1 \ TSLIB_TSDEVICE=/dev/input/event0 \ TSLIB_CALIBFILE=/etc/pointercal\ TSLIB_CONFFILE=/etc/ts.conf \ TSLIB_PLUGINDIR=/usr/local/lib/ts\ ts_uinput -v

最后一个命令将创建一个新的/dev/input/eventX文件,其编号比现有的文件更大。Raylib已经设置为从编号最大的文件读取,启动Raylib应用程序将开始从正确的事件流读取。

你还可以在运行最后一个命令时包含-d参数,以在后台以守护进程模式运行。

总之,通过这些魔法工具和技巧,你可以在树莓派上开发出轻量级的GUI应用,而且不会拖慢它的速度。这就像给你的树莓派装上了一个轻便的“面甲”,让它既能跑得快,又能看起来很酷!如果你有任何问题或者想法,欢迎在评论区留言,我们一起探讨!

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • GUI
    GUI
    +关注

    关注

    3

    文章

    699

    浏览量

    44027
  • 树莓派
    +关注

    关注

    122

    文章

    2086

    浏览量

    110942
收藏 人收藏
加入交流群
微信小助手二维码

扫码添加小助手

加入工程师交流群

    评论

    相关推荐
    热点推荐

    树莓可以做什么?

    ``树莓是一款基于ARM的微型电脑主板,迄今为止,出货已达300万块。然而很多人拿到树莓,却突然不知道要用它来做什么了。现在我就来汇总
    发表于 06-29 09:42

    树莓驱动程序开发求解

    本人菜鸟一枚,刚入门linux,买了一块树莓二代B+的板子来学习驱动程序的开发,但现在网上很多都是用python库写的代码,与以前学的s3c6410驱动过程不一样,请问大神们有没驱动方面的资料或者
    发表于 05-08 15:45

    树莓基础功能设置

    登录的是pi也是同样的操作 启示:我们可以通过修改~/.bashrc添加任何其他的命令别名。或者-allh比较好用 3、通过sftp文件给树莓使用FileZilla工具的快
    发表于 03-02 09:10

    STM32和树莓进行串口通信

    目录树莓环境串口透STM32环境串口透最近做一个项目需要STM32和树莓进行串口通信,实
    发表于 08-11 07:34

    树莓与STM32是如何去实现串口透

    树莓与STM32是如何去实现透的?有哪些操作流程呢?
    发表于 12-02 08:08

    请问树莓与STM32如何实现透

    请问树莓与STM32如何实现透
    发表于 02-18 07:56

    浅谈香蕉树莓的不同

    目前有许多人在学习嵌入式开发,对于嵌入式开发板也有了一定的了解,比如树莓、香蕉等。这些以水果称呼的嵌入式
    发表于 10-30 16:09 2.8w次阅读

    树莓资料软件FileZilla_win64下载

    树莓资料软件FileZilla_win64下载
    发表于 06-07 10:03 1次下载

    Ros(树莓)& STM32通讯的实现

    Ros(树莓)& STM32通讯的实现1. 参考1实现原理如下:第一步:使用USB转TTL分别调试STM32和树莓的串口透,确保
    发表于 12-24 18:56 26次下载
    Ros(<b class='flag-5'>树莓</b><b class='flag-5'>派</b>)& STM32通讯的实现

    树莓IO扩展板的技术规格 树莓扩展板该怎么用

    树莓IO扩展板是著名开源硬件商DFRobot专为树莓开发的IO扩展板,IO扩展板支持PWM、ADC、读取模拟
    的头像 发表于 05-17 15:18 4937次阅读
    <b class='flag-5'>树莓</b><b class='flag-5'>派</b>IO扩展板的技术规格 <b class='flag-5'>树莓</b><b class='flag-5'>派</b>扩展板该怎么用

    Xbox树莓开发PCB

    电子发烧友网站提供《Xbox树莓开发PCB.zip》资料免费下载
    发表于 08-02 10:53 7次下载
    Xbox<b class='flag-5'>树莓</b><b class='flag-5'>派</b><b class='flag-5'>开发</b>PCB

    树莓gui开发用什么ide

    树莓(Raspberry Pi)是一款功能强大的微型计算机,可以运行多种操作系统,如Raspbian、Ubuntu等。在树莓派上进行GUI
    的头像 发表于 08-30 16:49 3042次阅读

    ARM开发板与树莓的比较

    ARM开发板和树莓都是基于ARM架构的单板计算机,它们在教育、工业控制、物联网等领域有着广泛的应用。 硬件配置 ARM开发板和树莓
    的头像 发表于 11-05 11:11 2569次阅读

    树莓GUI应用开发:从零到炫酷的魔法之旅!

    GUI应用开发有多好玩、多实用!树莓+GUI:不只是“好看”那么简单!你可能已经知道,树莓
    的头像 发表于 04-04 09:03 1354次阅读
    <b class='flag-5'>树莓</b><b class='flag-5'>派</b><b class='flag-5'>GUI</b>应用<b class='flag-5'>开发</b>:从零到炫酷的魔法之旅!

    树莓操作系统:版本、特性及设置完整指南!

    桌面环境的版本和轻量级、仅用于命令行的最小安装版本。该操作系统设计高效且资源友好,是树莓设备的理想选择。树莓操作系统的优势√
    的头像 发表于 07-28 18:26 2043次阅读
    <b class='flag-5'>树莓</b><b class='flag-5'>派</b>操作系统:版本、特性及设置完整指南!