3. 分区概念与模型

在 INTEGRITY 这样的分区化实时操作系统中,“分区”不是一个抽象的管理名词,而是整个系统隔离与调度的基本单位。理解分区,需要先把它与普通 RTOS 中的“任务”区分开:任务是最小的执行单元,而分区是承载任务、分配资源、实施隔离的容器。一个分区可以包含一个或多个任务,但分区本身拥有独立的地址空间、独立的调度预算和独立的故障边界。换句话说,任务决定“谁在跑”,分区决定“在哪里跑、能跑多久、出错后影响谁”。

分区的定义与核心属性

从工程角度看,一个 INTEGRITY 分区至少包含以下可配置属性:唯一的分区 ID、独立的虚拟地址空间(由 MMU 或 MPU 保护)、一组属于该分区的任务、分配给该分区的 CPU 时间预算(以时间片或周期窗口表示)、内存配额(代码段、数据段、堆栈、堆)、以及允许访问的设备或共享资源句柄。分区之间不能直接读写对方内存,必须通过内核提供的受控通信机制(如通道、队列、信号量或共享内存区)交换数据。这种“默认拒绝、显式授权”的模型,正是分区能够实现高可靠性的根本原因。

需要特别强调的是,分区的隔离不仅体现在空间上,也体现在时间上。INTEGRITY 的调度器通常采用时间触发或预算驱动的分区调度:每个分区在一个主时间帧(Major Time Frame)内获得固定的执行窗口。即使某个分区内的任务出现死循环或异常,只要它的时间预算耗尽,调度器就会强制切换到下一个分区,从而保证其他分区仍能获得确定的执行机会。这种空间与时间双重隔离,是分区模型区别于普通多任务模型的关键。

分区类型:内核分区、用户分区与共享分区

按功能与权限,INTEGRITY 中的分区通常划分为三类。内核分区(Kernel Partition)运行内核自身及最核心的系统服务,拥有最高特权级,负责调度、中断处理、分区切换和底层资源管理。它不参与普通应用的业务逻辑,也不应被用户代码直接调用。用户分区(User Partition)承载具体的应用任务,运行在非特权模式,只能通过系统调用访问内核服务。每个用户分区有独立的地址空间和预算,是隔离的主要对象。共享分区(Shared Partition)则用于多个分区需要共同访问的数据或服务,例如共享内存区、公共日志服务或跨分区通信代理。共享分区必须由内核严格管理访问权限,避免成为隔离链条中的薄弱环节。

三者的关系可以这样理解:内核分区是“裁判和场地管理者”,用户分区是“各自独立的运动员”,共享分区是“公共的计分板或休息区”。裁判不参与比赛,运动员不能闯入别人的赛道,公共区域必须有明确的进出规则。

分区生命周期

一个分区从创建到销毁,通常经历配置、加载、启动、运行、停止和回收六个阶段。配置阶段在系统构建时完成,确定分区 ID、内存布局、时间预算、任务列表和通信端口。加载阶段由内核将分区镜像映射到其虚拟地址空间,并初始化任务控制块和资源句柄。启动阶段由内核调度器将分区置为就绪态,等待其时间窗口到来。运行阶段分区内的任务按自身优先级调度,但整体受分区预算约束。停止阶段可由分区主动退出、预算耗尽或故障触发。回收阶段释放分区占用的内存、通道和句柄,确保资源不泄漏。

在实际工程中,生命周期管理最容易被忽视的是“停止后的状态清理”。如果分区异常终止后没有正确释放共享资源,其他分区可能因为等待一个永远不会到达的信号而挂起。因此,INTEGRITY 通常要求为每个分区配置健康监控(Health Monitoring)策略,明确异常时的重启、隔离或系统级恢复动作。

分区与任务的关系

分区与任务是一对多的包含关系,但调度层次是两层:分区级调度决定“哪个分区在什么时候获得 CPU”,任务级调度决定“分区内部哪个任务先运行”。这种两级调度带来的直接好处是,即使某个分区内部任务优先级配置不当,也不会影响其他分区的执行窗口。反过来,如果分区预算设置过小,分区内的任务即使优先级再高,也无法获得足够的执行时间。

因此,在配置分区时,必须同时考虑任务的最坏执行时间(WCET)和分区的时间预算。一个常用的经验是:分区预算应略大于其内部所有任务 WCET 之和,并留出中断处理和通信开销的余量。如果预算过紧,任务可能频繁错过截止时间;如果预算过松,则会浪费 CPU 带宽,降低系统整体利用率。

INTEGRITY 分区模型:类型、生命周期与任务关系 内核分区 Kernel Partition 调度器 / 中断 / MMU 最高特权级 不承载业务任务 用户分区 A User Partition 任务 T1 / T2 / T3 独立地址空间 预算:2ms / 10ms 帧 用户分区 B User Partition 任务 T4 / T5 独立地址空间 预算:1.5ms / 10ms 帧 共享分区 Shared Partition 共享内存 / 日志 / 通信代理 受控访问,显式授权 分区生命周期 配置 加载 启动 运行 停止 回收 分区 = 空间隔离 + 时间预算 + 故障边界;任务在分区内调度,分区在系统级调度

配置示例:一个典型的分区参数表

下面给出一个教学用的分区配置示例,用于说明实际工程中需要填写哪些关键字段。该示例为合理假设,不代表任何真实项目的实测数据。

分区名称       类型      预算(ms)  周期(ms)  任务数  优先级范围  共享资源
Kernel        内核      —         —         8       0-15       全部
Display       用户      2.0       10        3       20-30      帧缓冲通道
Control       用户      1.5       10        2       25-35      传感器队列
Logger        共享      0.5       10        1       40         日志缓冲区

在这个示例中,Display 和 Control 是两个用户分区,各自拥有独立的时间窗口和任务集合。Logger 是共享分区,只运行一个低优先级任务,负责接收其他分区写入的日志消息。Kernel 分区不参与业务调度,但负责在时间帧边界执行分区切换。如果 Control 分区内的任务因为传感器数据异常而超时,它的预算耗尽后会被挂起,Display 分区仍能在自己的窗口内正常刷新,Logger 分区也能继续记录故障事件。这就是分区模型在工程上最直接的价值:把故障限制在局部,而不是让整个系统崩溃。

在配置分区预算时,建议先用任务级 WCET 之和作为下限,再叠加 10%~20% 的中断与通信开销余量。预算过紧会导致任务频繁错过截止时间,预算过松则会降低 CPU 利用率。实际项目中应通过时间测量工具验证每个分区的实际占用,而不是仅凭估算。

分区与任务关系的工程判断

判断一个分区划分是否合理,可以从三个问题入手:第一,故障是否被限制在分区内部?如果某个任务崩溃会导致其他分区的任务也挂起,说明共享资源或通信路径没有做好隔离。第二,时间预算是否与任务的实际需求匹配?如果某个分区长期用不满预算,而另一个分区长期超时,说明预算分配需要调整。第三,共享分区的访问是否受控?如果任何用户分区都能直接读写共享内存而不经过内核仲裁,那么共享分区就失去了隔离意义。

分区模型不是把任务简单分组,而是把“隔离”作为第一设计目标,再在隔离的基础上安排任务、预算和通信。理解这一点,才能在后续的配置、调试和故障分析中做出正确的判断。