跳到内容

嵌入式 Linux

来自维基教科书,开放书籍,开放世界


嵌入式 Linux 系统 涵盖从智能手机和智能电视等消费电子产品到工业机械、医疗设备、汽车系统、通信设备等等。Linux 为这些资源受限的设备带来了强大的功能、灵活性和稳定性。

嵌入式 Linux 系统的核心组件是 引导加载程序、定制的 Linux 内核根文件系统。源代码由 GCC 交叉编译器 编译。常见的引导加载程序是 Das U-Boot,即通用引导加载程序。根文件系统通常基于 BusyBox,这是一个将许多 Unix 实用程序打包到单个可执行文件中的软件套件。本地调试通常受到限制,因此可以使用 gdbserver

基本的嵌入式 Linux 系统可以从上面的模块手动编译。有一些工具可以从旧的、简单的 Buildroot 到庞大的 Yocto 项目 生成完整的系统,Yocto 项目会创建定制的嵌入式 Linux 发行版。PC 发行版如 DebianUbuntu 等等都已为 ARM 处理器构建。

树莓派BeagleBoard英伟达 Jetson 是支持嵌入式 Linux 的流行 单板计算机 的例子。

与常规的桌面或服务器版 Linux 发行版不同,这些版本的 Linux 通常包含更少的库和应用程序,固件 更小,通常从 闪存SD 卡 引导。


构建框架和环境

[编辑 | 编辑源代码]
Wear OS,智能手表和其他可穿戴设备的 Android。
AOSP,Android 开放源代码项目
Buildroot,基于旧的简单的补丁和 make 的构建环境
Yocto 项目OpenEmbedded,一个基于 BitBake 的构建框架和环境
BitBake,类似 make 的构建工具
OpenWrt,开放无线路由器
嵌入式 Linux 内核子集,适用于古老的 16 位 x86 机器和模拟器


Linux 内核
"init" 实现:OpenRCrunit
GUI:LXQtLXDEXfceFLTK
coreboot,轻量级 BIOS


通用 GNU C 库 glibc,7.9 MB
uClibc,560 KB
musl,527 KB
dietlibc,185 KB
Newlib
klibc,主要用于引导 Linux 系统
Bionic,最初由 Google 为 Android 嵌入式系统操作系统开发


进一步阅读

Linux C/POSIX 标准库实现比较
选择系统 C 库

发行版

[编辑 | 编辑源代码]

用于 ARM 处理器

Arch Linux ARMArch Linux 针对 ARM 处理器的移植版本
Armbian,基于 DebianUbuntu
RedSleeveRed Hat Enterprise Linux 的移植版本
emteria.OS,专有的基于 Android 的系统


轻量级云面向系统

Alpine Linux,使用 muslBusyBoxOpenRC
Fedora CoreOS
RHCOS,Red Hat Enterprise Linux CoreOS,适用于 OpenShift 容器平台
https://MicroShift.io/,轻量级 Kubernetes 发行版,专为边缘和物联网计算环境而设计


轻量级多平台发行版

Gentoo Linux
Tiny Core Linux
Kali Linux
Lubuntu
Slackware
Void Linux
Xubuntu


通用多平台发行版

Debian
Fedora
openSUSE
Ubuntu

嵌入式系统 Linux 内核的功能

[编辑 | 编辑源代码]
I/O 和总线
GPIO
drivers/gpio srctools/gpio src通用输入/输出 doc
SPI
drivers/spi src, tools/spi src, 串行外设接口 doc
I2C
⚲ UAPI: 从用户空间实例化 I2C 设备 doc
drivers/i2c src, https://i2c.wiki.kernel.org
I2C/SMBus 子系统 doc
drivers/net/can src控制器局域网络总线
drivers/mfd src多功能设备
drivers/usb/gadget src – 外设 USB 设备实现
drivers/iio src – 工业 I/O
drivers/pwm src脉冲宽度调制
drivers/regulator src – 通用电压和电流调节器支持
drivers/fpgasrc
drivers/slimbussrc
SLOB – 简单块列表内存分配器
设备树 – 描述内核的硬件组件


多媒体

[edit | edit source]
音频
ASoC – ALSA 系统芯片
snd_soc_cardid
ASoC – ALSA SoC 层 doc
https://www.alsa-project.org/wiki/ASoC
TFT (LCD) – 薄膜晶体管液晶显示器
fbtft_displayid


文件系统和存储

[edit | edit source]
UBIFS – 未排序块映像文件系统
SquashFS – 一个压缩的只读文件系统,具有低 开销
drivers/mtd src内存技术设备 块设备
更多: YAFFS, JFFS2


无 MMU

[edit | edit source]

Linux 最初是在具有 内存管理单元 (MMU) 的处理器上设计的。大多数嵌入式系统都没有 MMU,正如我们之前讨论过的 (嵌入式系统/内存),被称为 微控制器。没有 MMU 的微控制器更便宜,功耗更低。


使用具有 MMU 的处理器的优势

可以将运行的“不受信任”的机器代码与运行的“关键”代码隔离,因此“不受信任”的代码保证(在没有硬件故障的情况下)不会干扰“关键”代码
使操作系统更容易呈现虚拟内存的假象
可以运行“普通”Linux(也可以运行“μClinux”,但这有什么意义呢?)


μClinux – “微控制器 Linux” 是 Linux 内核的一个版本,它支持 Altera NIOS、ARM、Freescale M68K(包括 DragonBall、ColdFire、PowerQUICC 等)、Hitachi H8、MIPS 和 Xilinx MicroBlaze 处理器。

禁用参数 CONFIG_MMU 使能 nommu 模式。


实时

[edit | edit source]

人们使用各种方法将 实时 任务与 Linux 结合起来

  1. 在专用微控制器上运行实时任务;与处理非实时任务的(非实时)PC 通信。如果您需要低于 1 微秒的实时响应时间,这几乎是您的唯一选择。
  2. 在“底层”专用实时操作系统中运行实时任务;在实时操作系统之上在一个低优先级任务中运行 Linux 作为“嵌套操作系统”。其中一些系统声称实时响应时间低于 500 微秒。
  3. 使用旨在强调实时任务的 Linux 内核,并在高优先级(甚至可能是内核线程)下运行实时任务。

RT 发行版的示例

Xenomai
RTAI
RTLinux
MontaVista Linux
Red Hat Enterprise Linux for Real Time
实时 Ubuntu


几个 RT 功能提供了实时功能

RT抢占
RT调度
CPU 分区和隔离
Dynticks (Tickless, nohz)

RT抢占

[edit | edit source]

PREEMPT_RT 补丁已部分合并到 mainline Linux 内核中,从 5.15 版本开始 [1]。这意味着实时功能现在作为 mainline Linux 内核的一部分可用,从而使使用 Linux 部署和维护实时系统变得更加容易。

延迟抢占 (CONFIG_PREEMPT_LAZY) 仍然存在于外部补丁集中。

然而,Linux 的实时功能仍在不断发展,并且正在不断努力进一步提高实时性能和降低延迟。 Linux 基金会的实时 Linux (RTL) 协作项目 致力于改善 Linux 的实时功能,并在航空航天、汽车、机器人和电信等各个行业推广实时 Linux 的应用。

总之,实时 Linux 现在是 mainline Linux 内核的一部分,并且正在不断努力进一步提高实时性能和降低延迟。


参数 CONFIG_PREEMPT_RT id 使能实时抢占。

RT 调度策略

[edit | edit source]

RT 的调度策略

SCHED_FIFO id, SCHED_RR id
实现于 kernel/sched/rt.c src
SCHED_DEADLINE
实现于 kernel/sched/deadline.c src


API

man 1 chrt – 操作进程的实时属性
man 2 sched_rr_get_interval – 获取指定进程的 SCHED_RR 间隔
man 2 sched_setscheduler, sched_getscheduler – 设置和获取调度策略/参数
man 2 sched_get_priority_min, sched_get_priority_max – 获取静态优先级范围

测试 RT 功能

[edit | edit source]

实时 Linux 的测试过程通常涉及几个关键方面。首先,至关重要的是验证系统计时机制的准确性和稳定性。精确的时间管理是实时应用的基础,任何不准确都会导致计时错误并损害系统的实时功能。

测试的另一个重要方面是评估系统的调度算法。实时 Linux 采用高级调度策略来优先处理关键任务并确保其及时执行。测试调度器涉及评估其有效分配资源、正确处理任务优先级以及防止资源争用或优先级反转情况的能力。

此外,延迟测量是实时 Linux 测试中的一个关键部分。延迟是指事件发生与系统对其做出响应之间的时间延迟。在实时应用中,最小化延迟对于实现及时和可预测的行为至关重要。测试延迟涉及测量系统对各种刺激做出响应所需的时间,以及识别任何延迟或不可预测性的来源。

此外,压力测试在评估系统在繁重工作负载下的健壮性中发挥着重要作用。它涉及将实时 Linux 系统置于高水平的并发活动、密集的计算负载和输入/输出操作中,以评估其性能、响应能力和稳定性。压力测试有助于识别潜在的瓶颈、资源限制或可能降低系统实时行为的问题。


RTLA – 实时 Linux 分析工具:
rtla timerlat 文档 – 内核 timerlat 追踪器 文档 的 CLI
rtla osnoise 文档 – 内核 osnoise 追踪器 文档 的 CLI。内核函数 run_osnoise id 在循环中使用函数 trace_clock_local id 测量时间。
rtla hwnoise 文档 – 禁用中断的 osnoise 追踪器 文档 的 CLI
实现: tools/tracing/rtla 源代码kernel/trace/trace_osnoise.c 源代码
Linux 调度延迟调试和分析
RT-Tests, 源代码
cyclictest
一些 RT-Tests 手册页
cyclictest – 测量 手册 2 clock_nanosleep手册 2 nanosleep 延迟
hackbench – 调度器基准测试/压力测试
hwlatdetect/sys/kernel/tracing/hwlat_detector 文档 / kernel/trace/trace_hwlat.c 源代码 的 CLI。内核函数 kthread_fn id 在循环中使用函数 trace_clock_local id 测量时间延迟。
oslat – 使用 RDTSC 在繁忙循环中测量延迟
使用 eBPF 的实时追踪工具
realtime ltp


关于实时 Linux 的进一步阅读

linux/spinlock_rt.h 包含文件 通过 linux/spinlock_types.h 包含文件 使用
linux/rtmutex.h 包含文件 通过 linux/mutex_types.h 包含文件 使用
linux/rwbase_rt.h 包含文件 通过 linux/rwlock_types.h 包含文件 使用
实时 Linux 入门: 释放确定性计算
Linux 内核中的电源管理和调度 (OSPM)
实时 Linux wiki
CPU 分区和隔离
Realtime@LWN
linux-stable-rt.git
linux-rt-devel.git
实时内核补丁集,Arch Linux
https://www.kernel.org/pub/linux/kernel/projects/rt/ - 上游内核的 RT 补丁
高精度事件定时器 (HPET)
揭秘实时 Linux 调度延迟
RHEL 9 中的实时内核调优
与实时相关的 Linux 子系统
Linux 内核调度和抢占
中断
延迟工作
不可屏蔽中断处理程序 (NMI)
系统管理中断 (SMI)
手册 7 sched
延迟 @ LKML
PREEMPT_RT @ LKML
关于 PREEMPT_RT 的问答,LPC'23, 洋葱状态,pdf


关于嵌入式 Linux 的进一步阅读

嵌入式 Linux 大会 (ELC) @ EOSS 2023
https://elinux.org
类别:嵌入式 Linux
Linux 内核接口
ARM 支持
arch/arm 源代码, ARM 架构 文档
https://lwn.net/Kernel/Index/#Architectures-ARM
arch/arm64 源代码, ARM64 架构 文档
特定于架构的初始化
学习 vi 编辑器
  1. "实时抢占锁定核心合并". {{cite journal}}: Cite journal requires |journal= (帮助)
华夏公益教科书