37、JTK 库:实时嵌入式系统的低级别任务支持与性能优化

JTK 库:实时嵌入式系统的低级别任务支持与性能优化

1. 信号管理

信号管理是提升 POSIX 线程功能的关键问题。GNARL 管理信号的方式非常独特,在很多方面与 POSIX 线程的方式类似。GNARL 几乎自主完成所有工作,以最小模式使用底层支持。而 POSIX 线程无法实现这种精简使用,导致大量冗余处理,对 Ada 应用没有益处。

JTK 试图适应这种精简功能。它为任务请求的所有信号使用一个唯一的信号处理程序。当任务等待一个信号时,会在一个表中注册,表中对应请求信号的位置存储任务标识符,等待任务和相关信号一一对应。然后阻塞任务,直到信号到达。需要注意的是,GNARL 实现只允许任务等待单个信号(中止信号是特殊情况,后面会解释)。因此,JTK 方法中信号等待请求的执行非常简单直接。

POSIX 线程实现允许线程一次等待一组信号,所以在 POSIX 模型中,必须根据相当复杂的信号传递模型来确定接收线程。

信号发送机制更复杂一些。为了维护内部数据的完整性,必须注意异步信号的处理位置,信号管理器可能会延迟。信号管理根据是否访问受保护数据而有所不同。通过 Enter_Kernel Leave_Kernel 两个过程实现保护,这两个过程界定了不能传递信号的代码区域。当执行受保护代码时信号到达,信号会存储在待处理信号列表中。离开内核时,如果列表不为空,则处理这些延迟的信号。信号处理只需将等待任务放入调度器的就绪队列中唤醒即可。

虽然前面说任务只等待单个信号,但不完全正确,因为中止信号可以发送给任何任务,无论该任务是否正在等待信号。如果任务正在等待信号,通过唤醒它并传递中止信号标识符来发送中止信号,接收任务可以识别到达的信号。GNARL 提供的等待不同信号的不同任务知道接收到中止信号时该怎么做。

2. 异步控制转移

GNARL 通过在任何指定任务中引发特殊异常来实现 Ada ATC(异步控制转移)。当 GNARL 基于 POSIX 线程时,使用每个线程的信号来实现此操作。在不支持每个线程信号的操作系统上,ATC 的效果会延迟到执行到达轮询点。后者导致 ATC 效果不即时,前者是非常耗时的操作。

JTK 知道,除非任务试图自行中止(如果中止不延迟,它可以立即开始处理中止),否则它必须已经抢占了目标任务。如果要中止的任务正在等待信号,只需发送中止信号。但在其他情况下,无需使用任何信号操作(如虚假调用),只需修改目标任务的保存状态来重定向控制,目标任务下次调度执行时将开始处理中止。

3. 移植到裸机 PC

下一步工作是将 JTK 库和 GNAT 运行时系统移植到裸机 PC 目标。目的是获得一个交叉编译器平台,用于开发实时嵌入式软件,符合最小实时系统配置文件。这将为实时嵌入式系统的语言、编译器和运行时支持提供一个免费的实验测试平台。

Ada 的要求非常特殊,通用操作系统或内核不太可能以 Ada 程序可以直接使用的形式提供其服务。而且,基于传统操作系统的实现很难实现高效紧凑的实时性能,这些系统存在由于中断处理程序和操作系统进程抢占导致的不可预测延迟。

因此,为了为 GNARL 和 JTK 提供易于预测的底层支持,正在从硬件层面开发一个新的实时内核。这个内核旨在尽可能紧密地符合 Ada 任务语义,不支持多进程(将在单虚拟地址空间中运行),也没有文件系统。开始时,仅支持定时器和串行端口。这些简化消除了由于页面错误、等待 I/O 完成和 I/O 完成中断处理导致的不可预测时间延迟。

这个实现的设计可以分为三个主要组件:
- 机器特定支持 :包括保存和恢复上下文切换的寄存器窗口的代码、启动内核以及提供计时服务。启动代码涉及初始化内存映射硬件和安装陷阱处理程序。
- 环境接口支持 :包括内存分配、信号和中断管理、最小定时器服务以及与用户通信的 I/O 例程,为上层(GNARL 和 JTK)提供基本接口。
- 平台支持 :实现将内核代码传输到目标机器的机制以及应用程序的远程调试支持。目前,系统可以直接从软盘启动,使用引导加载程序(如 LILO 或 GRUB)或网络引导。调试方法通过串行线进行,但此功能仍在测试中。

这个新内核的接口有一个重要优势,由于在内核接口设计上没有限制,选择提供与 Linux 相同的接口,因此无论在 Linux 之上还是在这个专用内核之上,都无需对 JTK 系统进行修改。

4. 性能评估

为了评估此实现的性能和可行性,设计了一个简单测试。测试由两个任务组成,它们仅通过调用 System.Task_Primitives.Operations 包中的 Yield 过程进行上下文切换。图 1 显示了上下文切换所需的时间,报告的时间是每个任务 100000 次迭代的平均值。测试在同一台机器(233 MHz 的奔腾 II)上执行,测量了三种不同的 GNAT 移植情况:
- GNAT 3.10p 在使用嵌入式内核的 JTK 上
- GNAT 3.10p 在使用 FSU 实现的 Pthreads 的 Linux 上
- GNAT 3.10p 在使用 FSU 实现的 Pthreads 的 DOS 上

上下文切换时间是实时系统中非常重要的特性,对定时行为有很大影响。Pthreads 及相关工作中一直存在廉价并发的概念,试图提供轻量级进程。

5. JTK 调度器结构
package Schedulers is
    -- Sched_Task is the foundation for the class of types used as
    -- low-level tasks.
    type Sched_Task is abstract tagged record
       ...
    end record;
    -- Sched_Task_CA is the low-level task descriptor.
    type Sched_Task_CA is access all Sched_Task'Class;
    -- Scheduler contains the list of ready tasks and the
    -- descriptor of the task that is executing currently.
    type Scheduler is abstract tagged limited record
        Ready_List : Sched_List;
        Current    : Sched_Task_CA;
    end record;
    procedure Insert (A_Sched_Task : Sched_Task_CA; Sched : in out Scheduler) is abstract;
    procedure Remove (A_Sched_Task : Sched_Task_CA; Sched : in out Scheduler) is abstract;
    procedure Change_Priority (A_Sched_Task : Sched_Task_CA; Prio : System.Any_Priority; Sched : in out Scheduler) is abstract;
    procedure Next (Sched : in out Scheduler) is abstract;
    type Scheduler_FIFO_Prio is new Scheduler with null record;
   ...
end Schedulers;

package Schedulers.Basic is
   ...
    type Basic_Sched_Task is new Sched_Task with null record;
   ...
end Schedulers.Basic;

package Schedulers.RoundRobin is
   ...
    type Timed_Sched_Task is new Sched_Task with record
        Time_Slice : Duration := Default_Slice;
    end record;
   ...
end Schedulers.RoundRobin;
6. 结论与可用性

JTK 旨在严格满足 GNAT 运行时系统的需求,这种设计标准导致了非常简单高效的实现。该库还实现了灵活性,基于 Ada 中的面向对象技术,建立了一种简单的扩展功能的方法。例如,设计新的调度器是一种类型扩展,可以通过继承重用许多原语操作。

任务处理是 Ada 的优势之一,但人们仍然因担心复杂性而放弃在安全关键方案中使用它。因此,为提高任务处理实现的效率、可靠性,尤其是简单性和全面性所做的所有工作,可能会导致 Ada 任务处理在更广泛的环境中得到更多使用,因为人们更容易信任简单、可读和可理解的实现。它与成功的 Ravenscar 配置文件的设计目的有一些相似之处,但方法截然不同。

总之,JTK 为 GNARL 提供了所有低级任务处理功能:具有抢占和动态优先级支持的优先级驱动调度、动态任务创建、异步控制转移(ATCs)支持、具有立即优先级上限协议的互斥对象、信号管理和简单定时器管理。

JTK 已在以下架构中进行了测试:
- Linux/i386,2.x 内核,使用 GNAT - 3.10p(1.x 内核也应该可以工作)
- MS/DOS,使用 GNAT - 3.10

JTK 可从 ftp://ftp.dit.upm.es/str/software/jtk/ 获取,并遵循修改后的 GPL 许可证。有关 JTK 库的更多信息可在 http://www.dit.upm.es/~jfruiz/jtk.html 查阅。

7. MetaScribe:基于 Ada 的转换引擎构建工具

MetaScribe 是一个转换引擎生成器,旨在帮助实现程序生成器或将一种规范转换为另一种规范。它定义了一种元数据描述方案,适用于各种图形和层次描述的内部表示。

MetaScribe 完全用 Ada 实现,利用语言特性来强制进行类型检查和处理操作描述中的错误。

软件工程方法依赖于各种复杂的图形表示,如 OMT、UML 等。与旨在处理必须遵守的约束的 CASE(计算机辅助软件工程)工具结合使用时,这些表示更加有用。现在,CASE 工具已被 CASE 环境所取代,CASE 环境可以适应对设计方法的特定理解。

CASE 环境是一组协作工具,构建在允许工具插入的平台上,需要研究工具之间的通信和协作。实现 CASE 环境是一项复杂的任务,因为它们需要各种功能,如图形用户界面、数据库和通信设施。大型项目的实验表明,维护这些环境很困难,特别是当工具来自不同来源时。

为了实现方法并在大型案例研究中进行实验,开发了 FrameKit,这是一个用于快速实现 CASE 环境的框架。它是参数化的,为定制特定方法的 CASE 环境提供框架。FrameKit 主要集成在 Ada 中(少量使用 C 来接口 Unix)。

以下是一个简单的 mermaid 流程图,展示了 JTK 信号等待和处理的基本流程:

graph TD;
    A[任务请求等待信号] --> B[在表中注册任务标识符];
    B --> C[阻塞任务];
    C --> D{信号到达};
    D -- 受保护代码 --> E[存储在待处理信号列表];
    D -- 非受保护代码 --> F[将任务放入就绪队列唤醒];
    E --> G{离开内核};
    G -- 列表非空 --> F;
    G -- 列表为空 --> H[无操作];

通过以上内容可以看出,JTK 在实时嵌入式系统的任务处理和信号管理方面具有独特的优势,并且 MetaScribe 为软件工程中的规范转换提供了有效的工具支持。这些技术对于提高软件的开发效率和质量具有重要意义。

JTK 库:实时嵌入式系统的低级别任务支持与性能优化

8. 技术对比分析

为了更清晰地了解 JTK 在实时嵌入式系统中的优势,我们将其与 POSIX 线程在信号管理和任务处理方面进行详细对比,如下表所示:
| 对比项 | JTK | POSIX 线程 |
| — | — | — |
| 信号处理方式 | 为所有请求信号使用唯一信号处理程序,任务仅等待单个信号(中止信号除外),处理简单直接 | 允许线程一次等待一组信号,需根据复杂信号传递模型确定接收线程,存在大量冗余处理 |
| 实时性能 | 新内核设计消除不可预测延迟,提供易于预测的底层支持 | 基于传统操作系统,存在因中断处理程序和操作系统进程抢占导致的不可预测延迟 |
| 功能扩展性 | 基于 Ada 面向对象技术,可通过类型扩展和继承轻松扩展功能,如设计新调度器 | 扩展性相对较弱,功能实现较为固定 |
| 任务处理语义 | 紧密符合 Ada 任务语义,支持动态任务创建、异步控制转移等 | 任务处理语义与 Ada 任务语义不完全匹配,可能需要额外适配 |

从上述对比可以看出,JTK 在信号管理、实时性能、功能扩展性和任务处理语义等方面都具有明显优势,更适合实时嵌入式系统的开发需求。

9. 应用场景探讨

JTK 的特性使其在多个实时嵌入式系统应用场景中具有广泛的应用前景:
- 航空航天领域 :在航空航天设备中,如飞行控制系统、航空电子设备等,对实时性和可靠性要求极高。JTK 的高效任务调度和信号管理机制可以确保系统在复杂环境下的稳定运行,及时响应各种指令和事件。例如,在飞行控制系统中,JTK 可以精确控制各个子系统的任务执行顺序和时间,保证飞机的飞行安全。
- 工业自动化领域 :工业自动化生产线需要对各种设备进行实时监控和控制,以提高生产效率和产品质量。JTK 的动态任务创建和优先级驱动调度功能可以根据生产需求灵活调整任务执行顺序,实现对设备的高效管理。例如,在自动化装配线上,JTK 可以根据产品类型和生产进度动态分配任务给不同的机器人和设备,确保生产线的高效运行。
- 医疗设备领域 :医疗设备如心脏起搏器、监护仪等对实时性和安全性要求非常严格。JTK 的简单可靠的任务处理机制可以确保设备在关键时刻能够准确响应,保障患者的生命安全。例如,在心脏起搏器中,JTK 可以根据患者的心率变化实时调整起搏信号的输出,保证心脏的正常跳动。

10. 未来发展展望

随着实时嵌入式系统的不断发展,JTK 也有很大的发展空间。未来可以从以下几个方面进行改进和扩展:
- 多核支持 :随着多核处理器的广泛应用,JTK 可以进一步扩展以支持多核环境下的任务调度和并行处理。通过优化任务分配和同步机制,充分发挥多核处理器的性能优势,提高系统的整体处理能力。
- 安全性增强 :在安全关键领域,如航空航天、医疗设备等,对系统的安全性要求越来越高。JTK 可以引入更严格的安全机制,如形式化验证、安全审计等,确保系统在各种情况下都能安全可靠地运行。
- 与新兴技术融合 :随着物联网、人工智能等新兴技术的发展,JTK 可以与这些技术进行融合,为实时嵌入式系统带来更多的功能和应用场景。例如,结合物联网技术,实现设备之间的远程通信和协同工作;结合人工智能技术,实现智能任务调度和故障诊断。

11. 操作步骤总结

在实际应用中,使用 JTK 进行实时嵌入式系统开发可以按照以下步骤进行:
1. 环境搭建 :根据目标平台选择合适的开发环境,如在 Linux 或 MS/DOS 上安装 GNAT 编译器和 JTK 库。可以从 ftp://ftp.dit.upm.es/str/software/jtk/ 下载 JTK 库,并按照相关文档进行安装和配置。
2. 任务设计 :根据系统需求设计任务,确定任务的优先级、执行周期和通信方式等。可以使用 JTK 提供的任务创建和调度接口来实现任务的动态创建和管理。
3. 信号管理 :使用 JTK 的信号处理机制来处理异步事件,如信号等待、信号发送和信号处理等。注意在访问受保护数据时,使用 Enter_Kernel Leave_Kernel 过程来确保数据的完整性。
4. 性能测试 :使用类似文中提到的简单测试方法,对系统的性能进行测试和优化。可以通过调整任务优先级、信号处理方式等参数来提高系统的实时性能。
5. 系统调试 :使用 JTK 提供的调试接口和工具,对系统进行调试和故障排除。可以通过串行线进行远程调试,确保系统在实际运行中稳定可靠。

12. 总结与展望

综上所述,JTK 作为一种专门为实时嵌入式系统设计的低级别任务支持库,在信号管理、任务处理和实时性能等方面具有显著优势。通过与 POSIX 线程的对比,我们可以看到 JTK 在满足 Ada 任务语义和提高系统效率方面的独特之处。同时,MetaScribe 作为基于 Ada 的转换引擎构建工具,为软件工程中的规范转换提供了有效的支持。

未来,随着实时嵌入式系统的不断发展和应用需求的不断提高,JTK 和 MetaScribe 有望在更多领域得到广泛应用,并不断进行技术创新和功能扩展。我们期待这些技术能够为实时嵌入式系统的开发带来更多的便利和可能性,推动软件行业的发展。

以下是一个 mermaid 流程图,展示了使用 JTK 进行实时嵌入式系统开发的整体流程:

graph TD;
    A[环境搭建] --> B[任务设计];
    B --> C[信号管理];
    C --> D[性能测试];
    D --> E{性能达标};
    E -- 是 --> F[系统部署];
    E -- 否 --> G[参数调整];
    G --> B;
    F --> H[系统调试];
    H --> I{调试通过};
    I -- 是 --> J[系统上线];
    I -- 否 --> K[问题修复];
    K --> H;

通过以上内容,我们对 JTK 和 MetaScribe 的技术原理、应用场景和未来发展有了更深入的了解。希望这些信息能够为实时嵌入式系统的开发人员提供有益的参考和指导。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值