受保护对象的形式化建模与分析
1. 原子性与转换
在系统运行过程中,有时需要进行一系列的转换,并且不被其他组件打断。例如,在自动机过程中,动作序列
Ef?Release!Pe!
的原子性可以通过要求其间的紧急位置必须立即离开来实现。紧急状态必须在零时间内离开,但这并不妨碍其他转换同时发生。如果从紧急状态进行转换无法立即执行,那么该转换将被视为无法执行。
2. 受保护对象的建模
受保护对象(PO)的建模可以分为两个步骤:环境建模和 PO 本身的建模。
2.1 环境建模
环境由三个任务组成,分别进行函数调用、过程调用和入口调用。使用的符号约定如下:
F
表示函数,
P
表示过程,
E
表示入口,
s
表示开始,
b
表示开始执行,
e
表示结束,
x
表示异常。
-
FunctionCall 自动机
:代表执行函数调用的任务。信号
Fs!
与
Function
自动机中的
Fs?
同步。之后,该自动机在
FunctionCall.B
状态挂起,直到锁被获取并在
UFb!
上进行同步。此时,时钟
TauF
重置,函数代码开始执行(最多 10 个时间单位)。执行完成后,根据是否有异常,通过
UFe!
或
UFx!
同步,释放锁,并向
FunctionCall
自动机发送
Fe!
或
Fx!
信号。
FunctionCall
FunctionCall
FunctionCall
FunctionCall
FunctionCall
FunctionCall
FunctionCall
FunctionCall
FunctionCall
FunctionCall
FunctionCall
FunctionCall
FunctionCall
FunctionCall
FunctionCall
FunctionCall
FunctionCall
AAAAAAAAAAAAAAAAA
BBBBBBBBBBBBBBBBB
CCCCCCCCCCCCCCCCC
(TauF<10)
(TauF<10)
(TauF<10)
(TauF<10)
(TauF<10)
(TauF<10)
(TauF<10)
(TauF<10)
(TauF<10)
(TauF<10)
(TauF<10)
(TauF<10)
(TauF<10)
(TauF<10)
(TauF<10)
(TauF<10)
(TauF<10)
DDDDDDDDDDDDDDDDD
EEEEEEEEEEEEEEEEE
GGGGGGGGGGGGGGGGG
FFFFFFFFFFFFFFFFF
Fs!
Fs!
Fs!
Fs!
Fs!
Fs!
Fs!
Fs!
Fs!
Fs!
Fs!
Fs!
Fs!
Fs!
Fs!
Fs!
Fs!
UFb?
UFb?
UFb?
UFb?
UFb?
UFb?
UFb?
UFb?
UFb?
UFb?
UFb?
UFb?
UFb?
UFb?
UFb?
UFb?
UFb?
TauF:=0
TauF:=0
TauF:=0
TauF:=0
TauF:=0
TauF:=0
TauF:=0
TauF:=0
TauF:=0
TauF:=0
TauF:=0
TauF:=0
TauF:=0
TauF:=0
TauF:=0
TauF:=0
TauF:=0
UFx!
UFx!
UFx!
UFx!
UFx!
UFx!
UFx!
UFx!
UFx!
UFx!
UFx!
UFx!
UFx!
UFx!
UFx!
UFx!
UFx!
UFe!
UFe!
UFe!
UFe!
UFe!
UFe!
UFe!
UFe!
UFe!
UFe!
UFe!
UFe!
UFe!
UFe!
UFe!
UFe!
UFe!
Fe?
Fe?
Fe?
Fe?
Fe?
Fe?
Fe?
Fe?
Fe?
Fe?
Fe?
Fe?
Fe?
Fe?
Fe?
Fe?
Fe?
Fx?
Fx?
Fx?
Fx?
Fx?
Fx?
Fx?
Fx?
Fx?
Fx?
Fx?
Fx?
Fx?
Fx?
Fx?
Fx?
Fx?
-
ProcedureCall 自动机
:开始时向
Procedure
自动机发送同步信号Ps!
,然后挂起直到过程获取锁。之后,发送同步信号UPb!
,重置时钟TauP
,开始执行用户代码(最多 100 个时间单位)。如果发生异常,发送UPx!
信号;否则,发送UPe!
信号。最后,根据是否传播异常,Procedure
自动机发送Px!
或Pe!
信号。 -
EntryCall 自动机
:与
ProcedureCall
自动机工作方式类似,只是信号名称不同,且信号与Entry
自动机同步。执行入口代码的最长时间限制为 50 个时间单位。
EntryCall
EntryCall
EntryCall
EntryCall
EntryCall
EntryCall
EntryCall
EntryCall
EntryCall
EntryCall
EntryCall
EntryCall
EntryCall
EntryCall
EntryCall
EntryCall
EntryCall
BBBBBBBBBBBBBBBBB
CCCCCCCCCCCCCCCCC
(TauE<50)
(TauE<50)
(TauE<50)
(TauE<50)
(TauE<50)
(TauE<50)
(TauE<50)
(TauE<50)
(TauE<50)
(TauE<50)
(TauE<50)
(TauE<50)
(TauE<50)
(TauE<50)
(TauE<50)
(TauE<50)
(TauE<50) u:D
u:D
u:D
u:D
u:D
u:D
u:D
u:D
u:D
u:D
u:D
u:D
u:D
u:D
u:D
u:D
u:D
AAAAAAAAAAAAAAAAA
EEEEEEEEEEEEEEEEE
FFFFFFFFFFFFFFFFF
GGGGGGGGGGGGGGGGG
HHHHHHHHHHHHHHHHH
UEb?
UEb?
UEb?
UEb?
UEb?
UEb?
UEb?
UEb?
UEb?
UEb?
UEb?
UEb?
UEb?
UEb?
UEb?
UEb?
UEb?
TauE:=0
TauE:=0
TauE:=0
TauE:=0
TauE:=0
TauE:=0
TauE:=0
TauE:=0
TauE:=0
TauE:=0
TauE:=0
TauE:=0
TauE:=0
TauE:=0
TauE:=0
TauE:=0
TauE:=0
Barrier:=1
Barrier:=1
Barrier:=1
Barrier:=1
Barrier:=1
Barrier:=1
Barrier:=1
Barrier:=1
Barrier:=1
Barrier:=1
Barrier:=1
Barrier:=1
Barrier:=1
Barrier:=1
Barrier:=1
Barrier:=1
Barrier:=1
Barrier:=0
Barrier:=0
Barrier:=0
Barrier:=0
Barrier:=0
Barrier:=0
Barrier:=0
Barrier:=0
Barrier:=0
Barrier:=0
Barrier:=0
Barrier:=0
Barrier:=0
Barrier:=0
Barrier:=0
Barrier:=0
Barrier:=0
UEe!
UEe!
UEe!
UEe!
UEe!
UEe!
UEe!
UEe!
UEe!
UEe!
UEe!
UEe!
UEe!
UEe!
UEe!
UEe!
UEe!
UEx!
UEx!
UEx!
UEx!
UEx!
UEx!
UEx!
UEx!
UEx!
UEx!
UEx!
UEx!
UEx!
UEx!
UEx!
UEx!
UEx!
Es!
Es!
Es!
Es!
Es!
Es!
Es!
Es!
Es!
Es!
Es!
Es!
Es!
Es!
Es!
Es!
Es!
Ee?
Ee?
Ee?
Ee?
Ee?
Ee?
Ee?
Ee?
Ee?
Ee?
Ee?
Ee?
Ee?
Ee?
Ee?
Ee?
Ee?
Ex?
Ex?
Ex?
Ex?
Ex?
Ex?
Ex?
Ex?
Ex?
Ex?
Ex?
Ex?
Ex?
Ex?
Ex?
Ex?
Ex?
2.2 PO 本身的建模
PO 的功能由四个自动机建模:
Function
、
Procedure
、
Entry
和
Lock
。
-
Function 自动机
:进行函数调用的任务在
Function.A
和
Function.C
之间通过信号
Fs?
同步。调用任务在
Function.C
状态挂起,直到锁可用(变量
Lockp
为
false/0
)。锁可用时,获取锁并在
UFb!
上同步。
Function
自动机在
Function.G
状态挂起,直到调用任务完成代码执行。接收到
UFe?
或
UFx?
信号后,释放锁,并根据是否有异常,进行
Fe!
或
Fx!
同步。
Function
Function
Function
Function
Function
Function
Function
Function
Function
Function
Function
Function
Function
Function
Function
Function
Function
AAAAAAAAAAAAAAAAA
CCCCCCCCCCCCCCCCC
u:E
u:E
u:E
u:E
u:E
u:E
u:E
u:E
u:E
u:E
u:E
u:E
u:E
u:E
u:E
u:E
u:E
GGGGGGGGGGGGGGGGG
u:F
u:F
u:F
u:F
u:F
u:F
u:F
u:F
u:F
u:F
u:F
u:F
u:F
u:F
u:F
u:F
u:F
u:B
u:B
u:B
u:B
u:B
u:B
u:B
u:B
u:B
u:B
u:B
u:B
u:B
u:B
u:B
u:B
u:B
u:D
u:D
u:D
u:D
u:D
u:D
u:D
u:D
u:D
u:D
u:D
u:D
u:D
u:D
u:D
u:D
u:D
u:H
u:H
u:H
u:H
u:H
u:H
u:H
u:H
u:H
u:H
u:H
u:H
u:H
u:H
u:H
u:H
u:H
Fs?
Fs?
Fs?
Fs?
Fs?
Fs?
Fs?
Fs?
Fs?
Fs?
Fs?
Fs?
Fs?
Fs?
Fs?
Fs?
Fs?
Lockp==0
Lockp==0
Lockp==0
Lockp==0
Lockp==0
Lockp==0
Lockp==0
Lockp==0
Lockp==0
Lockp==0
Lockp==0
Lockp==0
Lockp==0
Lockp==0
Lockp==0
Lockp==0
Lockp==0
Seize!
Seize!
Seize!
Seize!
Seize!
Seize!
Seize!
Seize!
Seize!
Seize!
Seize!
Seize!
Seize!
Seize!
Seize!
Seize!
Seize!
UFb!
UFb!
UFb!
UFb!
UFb!
UFb!
UFb!
UFb!
UFb!
UFb!
UFb!
UFb!
UFb!
UFb!
UFb!
UFb!
UFb!
UFx?
UFx?
UFx?
UFx?
UFx?
UFx?
UFx?
UFx?
UFx?
UFx?
UFx?
UFx?
UFx?
UFx?
UFx?
UFx?
UFx?
UFe?
UFe?
UFe?
UFe?
UFe?
UFe?
UFe?
UFe?
UFe?
UFe?
UFe?
UFe?
UFe?
UFe?
UFe?
UFe?
UFe?
Release!
Release!
Release!
Release!
Release!
Release!
Release!
Release!
Release!
Release!
Release!
Release!
Release!
Release!
Release!
Release!
Release!
Fe!
Fe!
Fe!
Fe!
Fe!
Fe!
Fe!
Fe!
Fe!
Fe!
Fe!
Fe!
Fe!
Fe!
Fe!
Fe!
Fe!
Fx!
Fx!
Fx!
Fx!
Fx!
Fx!
Fx!
Fx!
Fx!
Fx!
Fx!
Fx!
Fx!
Fx!
Fx!
Fx!
Fx!
Release!
Release!
Release!
Release!
Release!
Release!
Release!
Release!
Release!
Release!
Release!
Release!
Release!
Release!
Release!
Release!
Release!
-
Procedure 自动机
:通道
Ps?
上的输入请求过程调用。调用任务在Procedure.D
状态挂起,直到Lockp
为false
。锁可用时,立即获取锁,向ProcedureCall
自动机发送同步信号UPb!
,然后挂起直到接收到UPx?
或UPe?
信号。如果入口队列中没有任务等待或屏障为false
,则释放锁并进行Pe!
或Px!
同步;如果入口队列中有任务且屏障为true
,则通过Eg!
同步允许该任务执行,在Procedure.K
或Procedure.L
状态挂起,直到接收到Ef?
信号,然后释放锁并进行Pe!
或Px!
同步。 -
Entry 自动机
:接收
Es?
信号,根据锁的状态和屏障条件进行不同的处理。如果锁可用且屏障为true
,则发送Ef!
信号;如果屏障为false
,则将任务加入队列。接收到UEe?
或UEx?
信号后,释放锁,并根据是否有异常发送Ee!
或Ex!
信号。
2.3 系统变量
系统使用六个变量,其中三个是时钟,三个是状态变量。
| 变量名 | 类型 | 描述 |
| ---- | ---- | ---- |
| TauF | 时钟 | 读取函数的时间限制在 10 个时间单位以内 |
| TauE | 时钟 | 执行入口代码的时间总是少于 50 个时间单位 |
| TauP | 时钟 | 执行过程代码的时间总是少于 100 个时间单位 |
| Barrier | 布尔值 | 入口调用的动作由入口体提供,入口体有一个布尔屏障条件,必须为
true/1
才能执行入口体。其值由应用程序设置 |
| ECount | 整数 | 排队等待受保护入口的任务数量,Ravenscar 配置文件将每个入口的任务数量限制为 1,即其取值范围为
{0, 1}
|
| Lockp | 整数 | 每个 PO 关联一个概念锁,
Lockp
为 1 表示 PO 被锁定,否则为 0 |
2.4 系统流程图
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;
A([开始]):::startend --> B(FunctionCall):::process
A --> C(ProcedureCall):::process
A --> D(EntryCall):::process
B --> E(Function):::process
C --> F(Procedure):::process
D --> G(Entry):::process
E --> H(Lock):::process
F --> H
G --> H
H --> I{是否有异常?}:::decision
I -->|是| J(异常处理):::process
I -->|否| K(正常结束):::process
J --> L([结束]):::startend
K --> L
通过以上建模和分析,我们可以更深入地理解受保护对象的工作机制,以及各个组件之间的交互方式。这有助于我们在实际应用中更好地设计和实现相关系统。
3. 时钟与时间限制
3.1 时钟的作用
为了模拟受保护操作的最坏情况执行时间(WCET),系统使用了三个不同的时钟:
TauF
、
TauE
和
TauP
。这些时钟并非真正测量 CPU 时间,而是记录执行代码所需的实际时间。在示例中,函数、入口和过程的 WCET 是任意选择的,但在实际应用中,会使用实际的 WCET。
3.2 各时钟的时间限制
时钟名称 | 时间限制 | 说明 |
---|---|---|
TauF | 小于 10 个时间单位 | 读取函数的时间被限制在 10 个时间单位以内 |
TauE | 小于 50 个时间单位 | 执行入口代码的时间总是少于 50 个时间单位 |
TauP | 小于 100 个时间单位 | 执行过程代码的时间总是少于 100 个时间单位 |
这些时间限制在自动机的运行过程中起到了重要的约束作用。例如,在
FunctionCall
自动机中,当接收到
UFb?
信号后,时钟
TauF
被重置,函数代码开始执行,并且执行时间必须在 10 个时间单位以内。如果超过这个时间,可能会导致系统出现异常情况。
4. 变量的作用与状态变化
4.1 Barrier 变量
Barrier
变量用于控制入口调用的执行。入口调用的动作由入口体提供,入口体有一个布尔屏障条件,必须为
true/1
才能执行入口体。其值由应用程序设置。如果屏障为
false/0
,则调用任务会被排队,直到屏障被设置为
true
且锁(
Lockp
)打开。
在
EntryCall
自动机中,当接收到
UEb?
信号后,会根据不同的情况设置
Barrier
的值。例如,在某些状态下会将
Barrier
设置为
1
,而在其他状态下会将其设置为
0
。
4.2 ECount 变量
ECount
变量记录排队等待受保护入口的任务数量。Ravenscar 配置文件将每个入口的任务数量限制为 1,即其取值范围为
{0, 1}
。当有任务请求进入受保护入口时,如果入口的屏障为
false
,则该任务会被加入队列,
ECount
的值会变为
1
;当入口的屏障变为
true
且锁可用时,队列中的任务会被允许执行,
ECount
的值会变为
0
。
4.3 Lockp 变量
Lockp
变量表示每个 PO 关联的概念锁的状态。当
Lockp
的值为
1
时,表示 PO 被锁定;否则,
Lockp
等于
0
,表示 PO 可用。在各个自动机中,锁的获取和释放操作都与
Lockp
变量密切相关。例如,在
Function
自动机中,调用任务在
Function.C
状态挂起,直到
Lockp
为
false/0
,即锁可用时,才会获取锁并继续执行。
5. 自动机的详细交互过程
5.1 FunctionCall 与 Function 自动机的交互
-
FunctionCall
自动机发送Fs!
信号,与Function
自动机的Fs?
信号同步。 -
调用任务在
Function.C
状态挂起,等待锁可用(Lockp
为false/0
)。 -
锁可用时,
Function
自动机获取锁,发送UFb!
信号,FunctionCall
自动机接收到UFb?
信号后,重置时钟TauF
并开始执行函数代码。 -
函数代码执行完成后,
FunctionCall
自动机根据是否有异常,发送UFe!
或UFx!
信号。 -
Function
自动机接收到UFe?
或UFx?
信号后,释放锁,并根据是否有异常,发送Fe!
或Fx!
信号给FunctionCall
自动机。
5.2 ProcedureCall 与 Procedure 自动机的交互
-
ProcedureCall
自动机发送Ps!
信号,与Procedure
自动机的Ps?
信号同步。 -
调用任务在
Procedure.D
状态挂起,等待锁可用(Lockp
为false
)。 -
锁可用时,
Procedure
自动机立即获取锁,发送UPb!
信号,ProcedureCall
自动机接收到UPb!
信号后,重置时钟TauP
并开始执行过程代码。 -
过程代码执行过程中,如果发生异常,
ProcedureCall
自动机发送UPx!
信号;否则,发送UPe!
信号。 -
Procedure
自动机接收到UPx?
或UPe?
信号后,根据入口队列和屏障的状态进行不同的处理。如果入口队列中没有任务等待或屏障为false
,则释放锁并发送Px!
或Pe!
信号;如果入口队列中有任务且屏障为true
,则同步Eg!
信号,允许该任务执行,然后在Procedure.K
或Procedure.L
状态挂起,直到接收到Ef?
信号,再释放锁并发送Px!
或Pe!
信号。
5.3 EntryCall 与 Entry 自动机的交互
-
EntryCall
自动机发送Es!
信号,与Entry
自动机的Es?
信号同步。 -
根据锁的状态和屏障条件,
Entry
自动机进行不同的处理。如果锁可用且屏障为true
,则发送Ef!
信号;如果屏障为false
,则将任务加入队列,ECount
变为1
。 -
当入口的屏障变为
true
且锁可用时,队列中的任务被允许执行,EntryCall
自动机接收到UEb?
信号,重置时钟TauE
并开始执行入口代码。 -
入口代码执行完成后,
EntryCall
自动机根据是否有异常,发送UEe!
或UEx!
信号。 -
Entry
自动机接收到UEe?
或UEx?
信号后,释放锁,并根据是否有异常,发送Ee!
或Ex!
信号给EntryCall
自动机。
graph LR
classDef startend fill:#F5EBFF,stroke:#BE8FED,stroke-width:2px;
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
classDef decision fill:#FFF6CC,stroke:#FFBC52,stroke-width:2px;
A(FunctionCall):::process -->|Fs!| B(Function):::process
B -->|Lockp==0| C(获取锁):::process
C -->|UFb!| A
A -->|执行函数代码| D{是否有异常?}:::decision
D -->|是| E(UFx!):::process
D -->|否| F(UFe!):::process
E --> B
F --> B
B -->|Release!| G(释放锁):::process
G -->|Fx!或Fe!| A
H(ProcedureCall):::process -->|Ps!| I(Procedure):::process
I -->|Lockp==0| J(获取锁):::process
J -->|UPb!| H
H -->|执行过程代码| K{是否有异常?}:::decision
K -->|是| L(UPx!):::process
K -->|否| M(UPe!):::process
L --> I
M --> I
I -->|判断队列和屏障| N{是否有任务在队列且屏障为true?}:::decision
N -->|是| O(Eg!):::process
N -->|否| P(Release!并发送Px!或Pe!):::process
O --> Q(等待Ef?):::process
Q --> P
R(EntryCall):::process -->|Es!| S(Entry):::process
S -->|判断锁和屏障| T{锁可用且屏障为true?}:::decision
T -->|是| U(Ef!):::process
T -->|否| V(加入队列):::process
U --> R
R -->|UEb?| W(重置TauE并执行入口代码):::process
W --> X{是否有异常?}:::decision
X -->|是| Y(UEx!):::process
X -->|否| Z(UEe!):::process
Y --> S
Z --> S
S -->|Release!| AA(释放锁):::process
AA -->|Ex!或Ee!| R
6. 总结
通过对受保护对象的形式化建模和分析,我们详细了解了系统中各个组件的工作机制和交互方式。时钟的使用确保了受保护操作的执行时间在合理范围内,变量的状态变化控制了任务的排队和执行顺序,自动机之间的同步和交互实现了系统的功能。
在实际应用中,我们可以根据这些模型和分析结果,更好地设计和实现相关系统,提高系统的可靠性和性能。例如,可以根据实际的 WCET 调整时钟的时间限制,根据系统的需求合理设置变量的初始值和状态变化规则,以及优化自动机之间的交互过程,减少任务的等待时间和异常情况的发生。
同时,这种形式化建模和分析方法也可以应用于其他类似的系统,帮助我们更好地理解和设计复杂的系统。通过建立精确的模型,我们可以在系统开发的早期阶段发现潜在的问题,并进行相应的优化和改进,从而提高系统的质量和稳定性。