嵌入式 Linux
嵌入式 Linux 系统 涵盖从智能手机和智能电视等消费电子产品到工业机械、医疗设备、汽车系统、通信设备等等。Linux 为这些资源受限的设备带来了强大的功能、灵活性和稳定性。
嵌入式 Linux 系统的核心组件是 引导加载程序、定制的 Linux 内核 和 根文件系统。源代码由 GCC 交叉编译器 编译。常见的引导加载程序是 Das U-Boot,即通用引导加载程序。根文件系统通常基于 BusyBox,这是一个将许多 Unix 实用程序打包到单个可执行文件中的软件套件。本地调试通常受到限制,因此可以使用 gdbserver。
基本的嵌入式 Linux 系统可以从上面的模块手动编译。有一些工具可以从旧的、简单的 Buildroot 到庞大的 Yocto 项目 生成完整的系统,Yocto 项目会创建定制的嵌入式 Linux 发行版。PC 发行版如 Debian、Ubuntu 等等都已为 ARM 处理器构建。
树莓派、BeagleBoard 和 英伟达 Jetson 是支持嵌入式 Linux 的流行 单板计算机 的例子。
与常规的桌面或服务器版 Linux 发行版不同,这些版本的 Linux 通常包含更少的库和应用程序,固件 更小,通常从 闪存 或 SD 卡 引导。
- Wear OS,智能手表和其他可穿戴设备的 Android。
- AOSP,Android 开放源代码项目
- Buildroot,基于旧的简单的补丁和 make 的构建环境
- Yocto 项目 和 OpenEmbedded,一个基于 BitBake 的构建框架和环境
- BitBake,类似 make 的构建工具
- OpenWrt,开放无线路由器
- 嵌入式 Linux 内核子集,适用于古老的 16 位 x86 机器和模拟器
- 通用 GNU C 库 glibc,7.9 MB
- uClibc,560 KB
- musl,527 KB
- dietlibc,185 KB
- Newlib
- klibc,主要用于引导 Linux 系统
- Bionic,最初由 Google 为 Android 嵌入式系统操作系统开发
进一步阅读
用于 ARM 处理器
- Arch Linux ARM,Arch Linux 针对 ARM 处理器的移植版本
- Armbian,基于 Debian 和 Ubuntu
- RedSleeve,Red Hat Enterprise Linux 的移植版本
- emteria.OS,专有的基于 Android 的系统
轻量级云面向系统
- Alpine Linux,使用 musl、BusyBox 和 OpenRC。
- Fedora CoreOS
- RHCOS,Red Hat Enterprise Linux CoreOS,适用于 OpenShift 容器平台
- https://MicroShift.io/,轻量级 Kubernetes 发行版,专为边缘和物联网计算环境而设计
轻量级多平台发行版
通用多平台发行版
- I/O 和总线
- 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) – 薄膜晶体管液晶显示器
文件系统和存储
[edit | edit source]
无 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 结合起来
- 在专用微控制器上运行实时任务;与处理非实时任务的(非实时)PC 通信。如果您需要低于 1 微秒的实时响应时间,这几乎是您的唯一选择。
- 在“底层”专用实时操作系统中运行实时任务;在实时操作系统之上在一个低优先级任务中运行 Linux 作为“嵌套操作系统”。其中一些系统声称实时响应时间低于 500 微秒。
- 使用旨在强调实时任务的 Linux 内核,并在高优先级(甚至可能是内核线程)下运行实时任务。
RT 发行版的示例
几个 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 的调度策略
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, 源代码
- 一些 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
- 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 支持
- 特定于架构的初始化
- 学习 vi 编辑器
- ↑ "实时抢占锁定核心合并".
{{cite journal}}
: Cite journal requires|journal=
(帮助)