QNX-9—QNX官网文档翻译—Resource Managers—What is a resource manager?

发布时间 2023-07-09 18:45:47作者: Hello-World3

注:本文翻译自
QNX Software Development Platform --> Programming --> Getting Started with QNX Neutrino --> Resource Managers
http://www.qnx.com/developers/docs/7.1/index.html#com.qnx.doc.neutrino.getting_started/topic/s1_resmgr_What_is.html

1. 概述

资源管理器只是一个具有一些明确定义的特征的程序。

该程序在不同的操作系统上有不同的名称——有些称为“device drivers”、“I/O managers”、“filesystems”、“drivers”、“devices”等等。 然而,在所有情况下,该程序(我们将其称为资源管理器)的目标是呈现某些服务的抽象视图。

此外,由于 QNX Neutrino 是一个符合 POSIX 规范的操作系统,因此该抽象是基于 POSIX 规范的。

(1) Examples of resource managers

在我们得意忘形之前,让我们看几个例子,看看它们是如何“抽象”一些“服务”的。 我们将看看一个实际的硬件(串行端口)和更抽象的东西(文件系统)。

(2) Characteristics of resource managers

正如我们在上面的示例中看到的,资源管理器灵活性的关键在于,资源管理器的所有功能都是使用标准 POSIX 函数调用来访问的 ———— 在与串行通信时,我们没有使用“特殊”函数。 但是,如果您需要做一些“特殊”的事情,一些非常特定于设备的事情,该怎么办?


2. Examples of resource managers

在我们得意忘形之前,让我们看几个例子,看看它们是如何“抽象”一些“服务”的。 我们将看看一个实际的硬件(串行端口)和更抽象的东西(文件系统)。

(1) Serial port

在典型的系统中,程序通常存在某种方式来传输输出并从串行 RS-232 类型的硬件接口接收输入。 该硬件接口由一堆硬件设备组成,其中包括一个 UART(通用异步接收器发送器)芯片,该芯片知道如何将 CPU 的并行数据流转换为串行数据流,反之亦然。

在这种情况下,串行资源管理器提供的“服务”是程序在串行端口上发送和接收字符的能力。

我们说发生了“抽象”,因为客户端程序(最终使用该服务的程序)不知道(也不关心)UART 芯片及其实现的细节。 客户端程序只知道要发送一些字符,它应该调用 fprintf() 函数,要接收一些字符,它应该调用 fgets() 函数。 请注意,我们使用标准 POSIX 函数调用来与串行端口交互。

(2) Filesystem

作为资源管理器的另一个示例,让我们检查一下文件系统。 它由许多协作模块组成:文件系统本身、块 I/O 驱动程序和磁盘驱动程序。
这里提供的“服务”是程序在某种介质上读写字符的能力。 发生的“抽象”与上面的串行端口示例相同 - 客户端程序仍然可以使用完全相同的函数调用(例如 fprintf() 和 fgets() 函数)来与存储介质交互,而不是串行端口。 事实上,客户端确实不知道或不需要知道它正在与哪个资源管理器交互。


3. Characteristics of resource managers

正如我们在上面的示例中看到的,资源管理器灵活性的关键在于,资源管理器的所有功能都是使用标准 POSIX 函数调用来访问的 —— 在与串口通信时,我们没有使用“特殊”函数。 但是,如果您需要做一些“特殊”的事情,一些非常特定于设备的事情,该怎么办?

例如,设置串口的波特率是串口资源管理器特有的操作,对于文件系统资源管理器来说完全没有意义。 同样,通过 lseek() 设置文件位置在文件系统中很有用,但在串行端口中毫无意义。 POSIX 为此选择的解决方案很简单。 某些函数(例如 lseek())只会在不支持它们的设备上返回错误代码。 然后是“包罗万象”(和非 POSIX)设备控制函数,称为 devctl(),它允许提供特定于设备的功能。 不理解特定 devctl() 命令的设备只会返回错误,就像不理解 lseek() 命令的设备一样。

由于我们已经提到 lseek() 和 devctl() 作为两个常用命令,因此值得注意的是,资源管理器支持几乎所有文件描述符(或 FILE * 流)函数调用。

这自然使我们得出这样的结论:资源管理器将几乎专门处理基于文件描述符的函数调用。 由于 QNX Neutrino 是一个消息传递操作系统,因此 POSIX 函数会被转换为消息,然后发送到资源管理器。  正是这种“POSIX 函数到消息传递”的转换技巧让我们能够将客户端与资源管理器解耦。 资源管理器所要做的就是处理某些明确定义的消息。客户端所要做的就是生成资源管理器期望接收和处理的相同的明确定义的消息。

由于客户端和资源管理器之间的交互基于消息传递,因此使这个“转换层”尽可能薄是有意义的。 例如,当客户端执行 open() 并获取文件描述符时,该文件描述符实际上是 connection ID!  此 connection ID(文件描述符)在客户端的 C 库函数(例如 read())中使用,在该函数中创建消息并将其发送到资源管理器。