这里描述 DBDT 程序主控层状态机设计和编码实现方式。本状态机是主控层程序的核心。程序的几乎所有功能代码都是通过事件触发状态机的状态迁移(transition)操作实现。
接口类型和标识:
* 外部系统到 =>主控API标识为S1;
* 主控到 => 业务API标识为S2;
* 业务 => 波形API标识为S3;
* 主控 => 硬件模块API标识为S4。
状态(state)和状态变迁(transition):
* [*] 为初始状态,根据初始化后是否需要切换到其它状态,命名为 Initial 或 Initting。
* 复合(composite)状态本身是抽象(abstract)的(可以定义通用的 ENTRY / EXIT 事件处理),任何时候状态机都会处于某个叶子节点状态。最终叶子节点状态名使用父状态名 + "_" 前缀。
* <<choice>> 定义的分支选择类型 state 作为 transition 处理,并非实际状态。
* 所有 transition 均为同步(sync)短暂(transient)原子(atomic)执行模式。所有向外部接口发送消息或调用接口操作均位于transition里。所有异步(async)操作均使用消息和多种状态处理。
* 暂定:⇒ 开头的 transition 表示该 state 的 ENTRY (setup)系统事件,执行 init 初始化并切换到工作状态。
编码实现:
* 编码实现使用 [HSM](<https://github.com/howard-chan/HSM>) (Hierarchical State Machine) 模型。复合状态与其中的子状态是 hierarchical 从属关系。
* 如果某个状态只有一个来源状态,或者其所有来源状态transition里执行的操作相同或类似,则将这些 "setup" 操作放在目标状态的 ENTRY 系统事件里统一处理。
* 类似的,如果某个状态只有一个退出状态,或者其到所有退出状态transition里执行的操作相同或类似,则将这些 "teardown" 操作放在该状态的 EXIT 系统事件里统一处理。
* 说明:
* setup: 某个状态的通用的初始操作。例如进入 Initing 状态时会向各业务层发送 init() 指令。
* teardown: 某个状态的通用的卸载操作。例如进入 EXITING 状态时会向业务层发送终止发射流程指令。
超时(timeout)处理:
所有与外部接口和业务层的交互接口均为异步模式,即发送消息或调用接口后通过未来的消息获取回复和响应。系统会定期触发 TIMER 事件,各个状态的 handler 通过此事件处理超时异常。
整个电台的所有工作模式和状态由单一状态机管理。定频、QALE等工作模式属于复合状态。工作模式的进入(Entry)和退出(Exit)通过接收到的 S1 0xFC工作模式设置命令里的与当前工作模式不同的工作模式指令驱动。
stateDiagram-v2
state received_work_mode_msg <<choice>>
# 收到 S1 的 0xFC工作模式设置,保存所有信息到内存
[*]--> received_work_mode_msg : 0xFC工作模式设置
received_work_mode_msg --> FIXED:模式=0(定频)
received_work_mode_msg --> QALE :模式=1
state FIXED {
# 调用 S2 S2_init_module 初始化定频模块参数
[*] --> Initting : ⇒定频业务初始化:S2_init_module
# 收到 S2 定频参数初始化完成消息。发送 S2_set_work_mode 工作模式设置 0 定频
Initting --> WorkModeConfiging: 初始化完成:设置工作模式为定频
# 收到工作模式设置完成消息, 调用S2 set_work_type 设置业务类型(模拟话/声码话/数据链)
WorkModeConfiging--> WorkTypeConfiging: 工作模式设置完成:设置业务类型
# 收到业务类型设置完成消息,调用S2各个工作参数设置接口(速率,明/密,密钥分区,带宽,呼叫地址,工作指令)
WorkTypeConfiging --> WorkParamsConfiging : 业务类型设置完成:设置各参数
# 收到0xFC切换业务类型,再次调用 set_work_type
WorkTypeConfiging --> WorkTypeConfiging :0xFC切换业务类型
state received_work_param_msg <<choice>>
WorkParamsConfiging --> WorkTypeConfiging :0xFC切换业务类型
WorkParamsConfiging --> received_work_param_msg : 0xfc参数设置
received_work_param_msg --> WorkParamsConfiging : 尚有参数未设置完成
received_work_param_msg --> Running : 所有参数设置完成
Running --> WorkTypeConfiging :0xFC切换业务类型
Running --> WorkParamsConfiging :0xFC切换工作参数
}
# 0xFC 切换工作模式时,调用S2 set_send _control 终止发射流程
FIXED--> FIXED_Exiting : 0xFC 切换工作模式:关闭发射流程
# 收到发射流程关闭完成后,根据目标工作模式,进入相应模式的状态流程里。
FIXED_Exiting --> QALE: 关闭成功:切换到目标工作模式
stateDiagram-v2
state received_work_mode_msg <<choice>>
# 收到 S1 的 0xFC工作模式设置,保存所有信息到内存
[*]--> received_work_mode_msg : 0xFC工作模式设置
received_work_mode_msg --> FIXED:模式=0(定频)
received_work_mode_msg --> QALE :模式=1
state QALE {
# 调用 S2 S2_init_module 初始化 QALE模块参数
[*] --> Initting : ⇒QALE业务初始化:S2_init_module
# 收到 S2 QALE 参数初始化完成消息。发送 S2_set_work_mode 工作模式设置 1 QALE
Initting --> WorkModeConfiging: 初始化完成:设置工作模式为QALE
# 收到工作模式设置完成消息, 调用S2 set_work_type 设置业务类型(模拟话/声码话/数据链)
WorkModeConfiging--> WorkTypeConfiging: 工作模式设置完成:设置业务类型
# 收到业务类型设置完成消息,调用S2各个工作参数设置接口(波道号,速率,明/密,密钥分区,带宽,QALE呼叫地址)
WorkTypeConfiging --> WorkParamsConfiging : 业务类型设置完成:设置各参数
# 收到0xFC切换业务类型,再次调用 set_work_type
WorkTypeConfiging --> WorkTypeConfiging :0xFC切换业务类型
state received_work_param_msg <<choice>>
WorkParamsConfiging --> WorkTypeConfiging :0xFC切换业务类型
WorkParamsConfiging --> received_work_param_msg : 0xfc参数设置
received_work_param_msg --> WorkParamsConfiging : 尚有参数未设置完成
state work_order_type <<choice>>
received_work_param_msg --> work_order_type : 参数设置完成,根据工作指令类型
# 所有参数设置完成,根据工作指令类型
# 以下所有 transition 均向外部接口发送 0xDC 工作状态上报
work_order_type --> Scanning: 1(扫描)
# 工作指令为单呼或组呼:调用 S2_set_qale_link 开始建链
work_order_type --> Linking : 2(单呼)/3(组呼):开始建链
# 建链成功消息
Linking--> Running : 建链成功
Linking --> Scanning : 建链失败
Linking--> Unlinking: 外部指令设置扫描模式(Unlink同时代表拆链和取消建链)
#Linking--> WorkTypeConfiging :0xFC切换业务类型
#Running --> WorkTypeConfiging :0xFC切换业务类型
Running --> Unlinking : 0xFC(工作指令=1扫描),开始拆链
# 拆链成功消息,向外部接口回复 0xDC 工作状态上报
Unlinking --> Scanning : 拆链成功
Scanning --> Linking : 0xFC(工作指令=2/3)
Scanning --> Running : 被呼建链消息
# 0xF3 本机地址加载:调用 set_work_self_address
Running --> Running :0xF3
Running --> Scanning : 被动拆链消息
# 收到S2当前本机地址消息:更新内存,发送0xD3本地地址上报
Running --> Running :本机地址消息
Running --> WorkTypeConfiging :0xFC切换业务类型
Running --> WorkParamsConfiging :0xFC切换工作参数
}
# 0xFC 切换工作模式时,调用S2 set_send _control 终止发射流程
QALE --> QALE_Exiting : 0xFC 切换工作模式:关闭发射流程
# 收到发射流程关闭完成后,根据目标工作模式,进入相应模式的状态流程里。
QALE_Exiting --> FIXED : 关闭成功:切换到目标工作模式
state FIXED
备注
* 暂未考虑失败、超时等异常情况。
* Scanning / Linking / Running / Unlinking 等工作模式下收到 0xFC 切换业务类型或工作参数的命令后,考虑有两种处理方式:
a. 回退至 WorkTypeConfiging / WorkParamsConfiging 等状态。
b. 不改变状态,直接调用S2的业务类型或参数更新接口。
* QALE 预调谐目前设计在初始化时由业务实现。
stateDiagram-v2
state received_work_mode_msg <<choice>>
# 收到 S1 的 0xFC工作模式设置,保存所有信息到内存
[*]--> received_work_mode_msg : 0xFC工作模式设置
received_work_mode_msg --> FIXED:模式=0(定频)
received_work_mode_msg --> GROUP :模式=2
state GROUP {
[*] --> Initting : ⇒组网业务初始化:S2_init_module
# 收到 S2 QALE 参数初始化完成消息。发送 S2_set_work_mode 工作模式设置 3 组网
Initting --> WorkModeConfiging: 初始化完成:设置工作模式为组网
# 收到工作模式设置完成消息, 调用S2 set_work_type 设置业务类型(模拟话/声码话/数据链)
WorkModeConfiging--> WorkTypeConfiging: 工作模式设置完成:设置业务类型
# 收到业务类型设置完成消息,调用S2各个工作参数设置接口(波道号,速率,明/密,密钥分区,带宽,QALE呼叫地址)
WorkTypeConfiging --> WorkParamsConfiging : 业务类型设置完成:设置各参数
state received_work_param_msg <<choice>>
WorkParamsConfiging --> WorkTypeConfiging :0xFC切换业务类型
WorkParamsConfiging --> received_work_param_msg : 0xfc参数设置
received_work_param_msg --> WorkParamsConfiging : 尚有参数未设置完成
state work_order_type <<choice>>
received_work_param_msg --> work_order_type : 参数设置完成,根据工作指令类型
# 所有参数设置完成,根据工作指令类型
# 以下所有 transition 均向外部接口发送 0xDC 工作状态上报
work_order_type --> Scanning: 1(扫描)
# 工作指令为单呼或组呼:调用 S2_set_qale_link 开始建链
work_order_type --> Linking : 2(单呼)/3(组呼):开始建链
# 建链成功消息
Linking--> Running : 建链成功
Linking --> Scanning : 建链失败
#Linking--> WorkTypeConfiging :0xFC切换业务类型
#Running --> WorkTypeConfiging :0xFC切换业务类型
Running --> Unlinking : 0xFC(工作指令=1扫描),开始拆链
# 拆链成功消息,向外部接口回复 0xDC 工作状态上报
Unlinking --> Scanning : 拆链成功
Scanning --> Linking : 0xFC(工作指令=2/3)
Scanning --> Running : 被呼建链消息
# 0xF3 本机地址加载:调用 set_work_self_address
Running --> Running :0xF3
Running --> Scanning : 被动拆链消息
# 收到S2当前本机地址消息:更新内存,发送0xD3本地地址上报
Running --> Running :本机地址消息
Running --> WorkTypeConfiging :0xFC切换业务类型
Running --> WorkParamsConfiging :0xFC切换工作参数
}
# 0xFC 切换工作模式时,调用S2 set_send _control 终止发射流程
GROUP --> GROUP_Exiting : 0xFC 切换工作模式:关闭发射流程
# 收到发射流程关闭完成后,根据目标工作模式,进入相应模式的状态流程里。
GROUP_Exiting --> FIXED : 关闭成功:切换到目标工作模式
与 QALE 流程类似