在通用计算中,操作系统是一种提供计算机基本功能的软件。它确保计算机能够检测并响应外围设备(如键盘、屏幕、移动设备、打印机等),并管理内存和驱动器空间。
尽管现代操作系统使人们觉得多个程序同时运行,但 CPU 内核一次只能运行一个线程。每个任务都执行得非常快,并且以如此快的速度连续执行,以至于结果看起来像是大规模的多任务处理。这由一个称为调度器的子程序管理。
操作系统通常用于计算机。操作系统安装在您的硬盘驱动器上,并管理计算机的任务。
为什么 RTOS 对嵌入式系统至关重要
我在 2008 年发现了嵌入式软件,当时我是一名学生,正在学习在 MCS-51 芯片上进行编程。因为我主修计算机科学,所以我在其他课程中做的所有程序都在 PC 上执行。但是,在芯片上编程是一种完全不同的体验。我第一次看到我的程序在裸机板上运行,我仍然记得我的第一个循环灯程序成功运行时,我的激动之情。
不过,这种激动之情是相对短暂的。我编写的裸机程序越多,遇到的问题就越多。我并不孤单地感到沮丧。直接对芯片进行编程是很困难的,而且 PC 使用操作系统是有充分理由的。不幸的是,计算机芯片(嵌入式系统)通常没有操作系统。它们是用代码“硬编码”的,没有操作系统来帮助管理代码的执行方式。
以下是您在硬编码计算机芯片时可能遇到的问题
并发
您在芯片上没有守护进程来管理执行。对于裸机程序,不可避免地会有一个巨大的 while (1)
循环,其中包含几乎整个项目的事务逻辑。每个事务都会调用一个或多个延迟函数。当 CPU 正在运行延迟函数时,这些函数会串行执行。没有任何东西可以抢占不必要的延迟,因此事务重置必须等待。因此,大量的 CPU 时间浪费在空循环上,这对并发不利。
模块化
从软件项目的角度来看,在开发过程中始终强调高内聚和低耦合的原则。然而,裸机软件中的模块通常彼此高度依赖。如上所述,大多数函数都收集在一个巨大的 while (1)
循环中,这很难划分为模块。设计低耦合的软件很不方便,这使得在裸机板上开发大型项目变得困难。
此外,当涉及到看门狗定时器时,开发人员必须小心使用延迟函数。如果延迟时间过长,那么主函数就没有机会重置看门狗,因此看门狗会在执行期间被触发。对于裸机开发,即使在调用延迟函数时,也有太多事情需要考虑。项目越复杂,您需要注意的就越多。想象一下,试图将这一系列精确定时的交互解耦成模块。
生态系统
许多高级软件组件依赖于底层操作系统的实现。例如,我开发了一个基于 FreeModbus 的开源项目,我计划将其移植到各种平台,甚至裸机。但与将其适配到不同操作系统的便利性相比,某些功能太复杂,无法在所有裸机板上实现。更糟糕的是,由于缺乏通用性,许多实现必须在不同的硬件平台上从头开始设计。
目前,我的 Modbus 协议栈实现仍然无法在裸机板上运行。
许多大型公司(如 Realtek、TI 和 MediaTek)提供的 WiFi 软件开发工具包只能在操作系统上运行。他们不发布其固件的源代码供用户修改,因此您无法在裸机环境中使用它们。
实时能力
实时能力对于某些应用领域是必要的。对于某些用例,必须在特定时间触发关键的软件步骤。例如,对于工业控制,机械设备必须按照预定的顺序和时间完成动作。如果不确保实时能力,就会出现故障,可能会危及工人的生命。在裸机平台上,当所有功能都塞进一个大的 while (1)
循环中时,不可能保持实时能力。
可重用性
可重用性取决于模块化。没有人愿意一遍又一遍地做同样的工作,尤其是当这项工作是编写代码时。这不仅浪费时间,而且使代码维护呈指数级复杂化。然而,在具有不同芯片的各种硬件平台上,相同的函数必须适应不同的硬件,因为实现取决于底层硬件。重新发明轮子是不可避免的。
RTOS 的优势
幸运的是,有为芯片编写的操作系统:它们被称为实时操作系统 (RTOS),与大多数操作系统一样,它们都有一个调度器来确保代码执行的可预测顺序。
我第一次将 RTOS 用于裸机是在 2010 年。STM32 系列微控制器 (MCU) 开始流行起来,因为它们功能强大且功能丰富,所以很多人都在其上运行操作系统。我使用了 RT-Thread 操作系统,它有许多可用的、即用型组件构建在其上。它在 Apache 2.0 许可证下可用,与其他操作系统相比,我使用它感觉更舒服。我已经基于它开发了 10 年。
对于裸机编程,RTOS 解决了我们面临的大多数最大问题。
模块化
借助操作系统,整个软件可以分为多个任务(称为线程)。每个线程都有自己独立的执行空间。它们彼此独立,从而提高了模块化。
并发
当线程调用延迟函数时,它会自动将 CPU 让给其他需要运行的线程,从而提高了整个 CPU 的利用率,并最终提高了并发性。
实时
RTOS 旨在提供实时功能。每个线程都分配了指定的优先级。更重要的线程设置为更高的优先级,不太重要的线程设置为较低的优先级。这样,整个软件的实时性能就得到了保证。
开发效率
操作系统提供了一个统一的抽象接口层。这有助于可重用组件的积累,并提高开发效率。
操作系统是一群软件极客智慧的结晶。许多常见的软件功能,如信号量、事件通知、邮箱、环形缓冲区、单向链表、双向链表等等,都被封装和抽象,使其可以随时使用。
像 Linux 和 RT-Thread 这样的操作系统为碎片化的硬件实现了一组标准的硬件接口。这被称为设备驱动程序框架。因此,软件工程师可以专注于开发,而无需担心底层硬件或重新发明轮子。
软件生态系统
RT-Thread 生态系统的丰富性带来了量变到质变的过程。操作系统在模块化和可重用性方面的改进,使程序员能够封装基于 RTOS 的、嵌入式友好的可重用组件。这些组件可以用于项目,也可以与其他需要最大化软件价值的嵌入式应用程序开发人员共享。
例如,LkdGui 项目是一个专为单色显示器设计的开源图形库。您可能会在工业环境中看到它用于控制面板的简单、美观的图形界面。LkdGui 提供了图形功能,例如绘制点、线、矩形、文本显示、按钮小部件和进度条。

(Armink,CC BY-SA 4.0)
重用像 LkdGui 这样广泛而强大的库的能力意味着程序员可以在同行的工作基础上进行构建。如果没有 RTOS,这根本不可能实现。
尝试 RT-Thread
我是一个开源爱好者,并且我在 GitHub 上开源了一些嵌入式软件。在创建开源软件之前,我很少与他人谈论我的项目,因为人们不可避免地使用不同的芯片或硬件平台,所以我们的代码几乎无法在彼此的硬件上运行。像 RT-Thread 这样的 RTOS 大大提高了软件的可重用性,因此世界各地许多不同的专家可以就同一个项目相互交流。这鼓励越来越多的人分享和谈论他们的项目。如果您正在进行裸机编程,请在您的下一个项目上尝试 RT-Thread。
5 条评论