overview of major emabedded linux software stacks
overview of major emabedded linux software stacks
D-Bus
D-Bus是什么?
D-Bus是一种应用程序之间进行通信的消息总线进程间通信(interprocess communication,即IPC)系统。
D-Bus架构图:
- 面向消息的中间件机制,允许在同一台机器上同时运行的多个进程之间进行通信
- 依靠守护进程在应用程序之间传递消息
- 主要由系统守护进程使用,为客户端应用程序提供服务
- 示例:以 root 身份运行的网络配置守护程序提供 D-Bus API,CLI 和 GUI 客户端可以使用它来
配置网络 - 多条总线
- 一条系统总线,所有用户均可以访问,用于系统服务
- 一条会话总线,供每个登录用户使用
- 对象模型:interface、object、method、signal
一个很典型的蓝牙应用:BlueZ,就是基于D-Bus实现多个客户端与bluetoothd通信。
以BlueZ项目,对D-Bus的一些概念进行简单的说明:
BlueZ项目提供关键的两个应用是:bluetoothd 和 bluetoothctl。
bluetoothd应用连接dbus-daemon,在dbus上注册bus name为 org.bluez
的服务, 紧接着注册object path name 为 /org/bluez/hci0
的对象路径,并在该对象路径下注册interface name 为 org.bluez.Adapter1
的接口,该接口下绑定了方法和属性。
bluetoothctl应用连接dbus-daemon,接着就可以向 org.bluez
下 /org/bluez/hci0
下 org.bluez.Adapter1
下的 StartDiscovery
方法发送请求。
systemd
systemd是什么?
在基于UNIX的计算机操作系统中,init 是操作系统启动期间启动的第一个进程。init 是一个守护进程,它会持续运行直到系统关闭。它是所有其他进程的直接或间接祖先,并自动接收所有孤儿进程。在Linux系统中,进程的结构也是呈现树形,启动第一个进程就是 init (根),它的进程ID号是 1。
上一代关于初始化程序是SysV init 或 BSD init,而现在是Systemd。
几乎所有 Linux 桌面/服务器发行版都使用现代 init 系统,即systemd
systemd比 Busybox init 复杂得多,但也功能更强大
仅支持glibc,不支持 uClibc 和 Musl
提供如下功能:
- 并行启动服务,同时考虑依赖关系
- 服务监控
- 通过套接字激活按需启动服务
- 服务的资源管理:CPU限制、内存限制
基于单元的配置文件
- 声明性语言,而不是其他 init 系统中使用的 shell 脚本
其他
journald:日志daemon,替换了syslogd
networkd:用于网络配置管理
udevd:热插拔和 /dev 管理
logind:登录管理
systemctl:控制和监控 systemd 的工具
other
基于单元的配置文件
示例1:/etc/systemd/system/sshd.service
1 | [Unit] |
示例2:/usr/lib/systemd/system/wpa_supplicant.service
1 | [Unit] |
systemctl
systemctl status
查询所有服务的状态systemctl status <service>
查询指定服务的状态systemctl [start|stop|restart] <service>
启动或停止或重启指定服务systemctl [enable|disable] <service>
启用或禁用指定服务开机自启动systemctl is-enabled <service>
查看指定服务是否开机启动systemctl daemon-reload
刷新service配置文件生效systemctl list-units
以表格形式打印所有可用的服务单元
journalctl
journalctl 是用来查询systemd-journald 服务收集到的日志的工具。
journalctl -a
查询所有日志journalctl -f
显示最后一个日志,并且实时打印新增的日志journalctl -u <unit_name>
显示指定服务单元的日志
示例1:查询wpa_supplicant.service的日志
1 | $ journalctl -f -u wpa_supplicant.service |
linux graphics stack overview
display controller support
fddev 是一个 Linux 子系统,用于在计算机显示器上(通常在系统控制台上)显示图形。不过已经被弃用了,但仍有一些旧的图形驱动程序仅在此子系统中可用。
DRM 是Linux 内核的一个子系统,负责与现代显卡的GPU进行交互。
支持 SoC 或显卡的显示控制器,以及所有类型的显示面板和桥接器:并行、LVDS、DSI、HDMI、DisplayPort 等。当然,也支持通过I2C或者SPI连接的小型显示面板。设备在linux系统中暴露出来的路径为:/dev/fri/cardX
。
DRM对应的库:libdrm,提供了一个好用的测试工具:modetest。
GPU support: OpenGL
OpenGL是什么?
开源
OpenGL是DRM 子系统中的内核驱动程序,用于向 GPU 发送命令并管理内存。
mesa3d 用户空间库实现了各种 OpenGL API,包含大量GPU 特定逻辑
支持越来越多的GPU
所有权
- 许多嵌入式 GPU 过去仅通过专有 blob 获得支持 –> 长期维护问题
- 供应商提供的内核驱动程序 –> 如果用户空间是闭源的,则上游不会接受它们
- 一个(巨大的)闭源用户空间二进制 blob,实现各种 OpenGL API
Concept of display serviers
Linux 内核不处理应用程序之间的显示和输入设备的多路复用
- 只有一个用户空间应用程序可以使用显示器和一组给定的输入设备
显示服务是特殊的用户空间应用程序,它由如下显示/输入复用构成
- 允许多个客户端 GUI 应用程序提交其窗口内容
- 根据应用程序提交的内容、窗口可见性和分层,组成屏幕上可见的最终帧
- 根据焦点将输入事件传播到适当的客户端
X11 and X.org
X.org是什么?
X.org是UNIX系统的历史显示服务,包括Linux系统
X11协议被用于客户端和服务器结构
- 本地客户端使用UNIX套接字,远程客户端使用TCP
在现代 Linux 上,在 DRM 或 fbdev 之上处理图形,输入子系统处理输入事件
仍保留,但已是遗留
X11许可
Wayland
Wayland是什么?
- 指定显示服务器与其客户端之间通信的通信协议,以及该协议的 C 库实现
- 使用 Wayland 协议的显示服务称为 Wayland 合成器
- X11 协议的现代替代品
- 更多地基于 OpenGL 技术
Wayland compositors
Concept of graphics toolkits
X11 和 Wayland 协议是非常低级的协议
虽然可以使用X11和wayland,但直接使用这些协议或相应的客户端库开发应用程序会很麻烦
toolkits工具
- 其中一些只能在显示服务上运行:X11 或 Wayland
- 其中一些可以直接在 DRM + 输入 之上工作,适用于单个全屏应用程序
面向小部件的工具包,具有用于创建窗口、按钮、文本字段、下拉列表等的 API
面向游戏/多媒体的工具包,没有预定义的小部件 API
Qt
Qt是什么?
- 非常受欢迎且文档丰富的开发框架,提供如下:
- 核心库:数据结构、事件处理、XML、数据库、网络等
- 图形库:小组件和其他
- 标准 API 是 C++,但可以绑定到其他语言
- 可以作为:
- 具有 DRM 和 OpenGL 的单个应用程序,或没有加速的 fbdev
- X11 或 Wayland 上的多个应用程序
- 多平台:Linux、MacOS、Windows
- 许可有点复杂,混合了 LGPLv3、GPLv2、GPLv3 和(昂贵的)商业许可
Gtk
Gtk是什么?
作为 GNOME 桌面环境基础的工具包,GNOME 桌面环境是 Linux 桌面发行版中最流行的桌面环境,但在嵌入式项目中逐渐失去吸引力
由 glib(核心库)、pango(文本处理)、cairo(矢量图形)、gtk(小组件库) 组成
C 中的标准 API,但许多语言都存在绑定
需要显示服务支持:X11 或 Wayland
LGPLv2许可
当前最流行的开发版本是v 3.x,接下来的版本是v 4.x
多平台:Linux、MacOS、Windows
Flutter
Flutter是什么?
- 跨平台 UI 应用程序开发:Linux、Android、iOS、Windows、MacOS
- 由Google负责开发和维护
- 应用开发必须使用 Dart 编程语言
- 应用程序可以在 Dart 虚拟机中运行,也可以进行本地编译以获得更好的性能
- BSD-3-Clause认证许可
SDL
- 跨平台开发库,旨在提供对音频、键盘、鼠标、操纵杆和图形硬件的低级访问
- 使用C语言实现,轻量级
- 没有提供小组件库
- 游戏、媒体播放器、自定义 UI
- zlib认证许可
Other graphical toolkits
- Enlightenment Foundation Libraries (EFL) / Elementary
- 轻量且强大,但不是那么流行
- 运行在X11 或 Wayland之上
- LGPLv2.1认证
- LVGL
- 非常轻量,主要用于微控制器,但也能运行在Linux上
- MIT认证许可
Linux multimedia stack overview
Audio stack
- 内核侧:ALSA子系统,Advanced Linux Sound Architecture
- 包括音频接口和音频编解码器的驱动程序
- 暴露的音频设备接口 /dev/snd/
- 用户空间库:alsa-lib
- 音频服务
- 当多个应用程序共享音频设备时需要:混合音频流,将音频流从特定应用程序路由到特定设备
- JACK:主要用于专业音响
- pulseaudio:主要用于常规桌面 Linux 音频
- pipewire:pulseaudio 和 JACK 的现代替代品,已被一些 Linux 发行版采用
Video stack
- 内核侧:Video4Linux 子系统(简称V4L)
- 支持摄像头设备:网络摄像头以及 SoC 和摄像头传感器的摄像头接口(并行、CSI 等)
- 还用于支持视频编码/解码硬件加速器:H264、H265等
- 暴露的视频设备接口 /dev/videoX
- 传统用户空间库:libv4l
- 新的用户空间库,更现代,具有更多功能,正在采用:libcamera
- 许多多媒体堆栈/软件都支持:GStreamer、ffmpeg、VLC 等
GStreamer
Gstreamer是什么?
- 用于构建媒体处理组件图表的库
- 允许创建管道来转换、转变、流式传输、显示、捕获多媒体流(包括音频和视频)
- 由大量插件组成:视频捕获/显示、音频捕获/播放、编码/解码、缩放、过滤等
- 一个有趣的替代方案是 ffmpeg
Linux networking stack
Web accessible UI
- 在嵌入式系统中,使用 Web 界面进行设备配置/监控非常常见
- 需要 web 服务器:Busybox httpd可以满足简单的需求、lighttpd、nginx、apache可以满足复杂的需求
- 可以使用 PHP、NodeJS 或其他解释型语言,或者简单的 CGI shell 脚本
Web browsers: rendering engines
向你的设备添加 HTML 呈现功能:
- WebKit
- 由Apple发起,在 iOS 和 Safari 中被使用
- 开源项目许可:LGPLv2.1 和 BSD-2-Clause
- 在Gtk中集成方式:WebKitGtk
- 在Qt中的集成方式:QtWebKit
- 针对嵌入式设备优化的端口:WPE WebKit
- Blink
- 从WebKit中分支出来的
- 由Google开发,并被用在Chrome中
- 在Qt中的集成方式:QtWebEngine
- 被 Electron 使用
Web-based UIs
原生 GUI 应用程序的替代方案是创建基于 Web 技术的 GUI
全屏运行 Web 浏览器,并使用流行的 Web 技术开发应用程序
一些可用选项:
- Cog:适用于 WPE Webkit 端口的简单启动器
- Electron:将 NodeJS 应用程序与 Web 渲染引擎打包成一个独立应用程序的方法
注意占用空间和性能影响:Web 渲染引擎是一个庞大且耗费资源的软件
Programming languages
- 可用的语言和框架种类繁多,不仅限于 C/C++
- 注意空间和性能的影响
- 编译型语言
- C/C++
- Rust
- Go
- Ada
- Fortran
- 解释型语言
- Python
- Javascripts,NodeJS
- Lua
- Shell scripts
- Perl,Ruby,PHP