软件组件从产生到消费的过程分5个步骤:描述 (Specification),实现(Implementation),封装(Pakaging),配置( Configuration),分析(Analysis). 如下图所示:
从图中可以看出这一过程与C语言函数库编译链接过程很像,因为RTSC的目的是增强C,而不是取代C!
1. 描述( specification)
RTSC引入了一种C风格的描述语言(specification language)用来定义生产者与消费者之间的界限,这种方式比C语言头文件更清晰稳定。
RTSC推出了3种重要的C语言不支持的编程结构,目的就是让C语言也能实现组件:
module
module是常量,类型和函数的集合,该集合有一个公有的描述( specification)和一个私有的实现( implementation)
interface
interface是一个抽象module
package
pacakage是一个更高一级的程序名字空间,其作用域包含modules/interfaces
现代编程语言例如Java和C#本身就支持上面所描述的更高一级的编程结构,而C则需要一个“伴侣”——描述语言。
2. 实现( Implementation)
作为组件生产者,需要用C语言(亦可用C++或汇编)实现上面所描述的RTSC模块。一般而言,RTSC模块的实现分为两个互补的部分:
target-implementation
内容是基于C的target-content,提供给消费者用于嵌入式硬件平台目标程序。简单理解就是模块下位机部分的实现。
meta-implementation
内容是更高级的meta-content,用于指导下游程序的配置和目标程序的分析。简单理解就是模块上位机部分的实现。
基于C的target-content运行于资源受限的嵌入式平台, meta-content运行于资源丰富的上位机平台。RTSC提供了基于工业标准JavaScript的meta-language。
3. 封装(Pakaging)
RTSC包(pacakges)充当着物理和逻辑容器。除了提供RTSC模块/接口的名字空间,每个RTSC包都有一个文件系统目录,该目录下存有组件生产者提供的各种文件——描述文件、头文件、库、脚本、文档甚至其他RTSC包。为了保持RTSC包的内部完整性,每个RTSC包在构建、发行和最终部署的时候都是作为一个不可分割元素( indivisible element ),也就是说在组件的生命周期里,RTSC包的内容保持不变。
为了帮助应对组件生产者的扇出挑战,RTSC包在用多个C编译器构建多个库的时候采用流水线操作,即借助于一个target的多个实例,该target描述了如何使用一个特定的编译器工具链针对特定的指令集和存储器模型来编译C源文件。
在组件消费者这一边,通过将RTSC包作为传递的单元来应对扇入挑战。RTSC包通过一个已证明的设计模式(模仿Java)来标准化内容部署的方式。该设计模式基于以下三个基本概念:
包目录(package directory)
该目录的相对路径名同包名字符合,并且包含包的内容。
包仓库(package repository)
该目录名字任意,包含包目录。
包路径(package path)
包仓库排序列表,通过相对路径名来定位包和它们的内容。
4. 配置( Configuration)
对于组件消费者而言,RTSC配置(Configuration)就是把不同组件生产者提供的各种组件集成起来构建嵌入式程序。
配置过程首先需要一个用meta-language写的配置脚本,该脚本确定了目标嵌入式程序的组成。如图中所示,脚本还需要指定组件应用的目标和平台。
这里可以将嵌入式程序分两部分:运行于嵌入式平台的target-program和运行于上位机的meta-program。配置脚本其实就是meta-program。
还有,配置过程实际上是自动进行的,在运行target-program之前先运行meta-program,可以提前发现一些错误。
5. 分析( Analysis)
进行RTSC分析的时候,RTSC分析工具通过仿真器获取目标程序状态并保存至硬盘,然后将保存的目标程序状态结构转换成等同的JavaScript对象,然后进行各种性能分析。这种分析方式叫面向状态的分析。
作为面向状态分析的补充,另一种分析方式是基于事件的,通过RTSC自带的Log模块,组件的生产者和消费者可以用同样的方式在C程序任何地方发出事件。程序运行的过程中,事件可以被存储在目标设备里或实时上传至上位机。