Linux
Linux software install
Google repo的使用
Vector AP StartApplication编译脚本解析
Yocto的cmake版本升级
不能自动安装的解决方式
S32G-BSP35.0-SDK使用方法
S32G从SDK生成文件系统的制作过程
Linux Samba设置
Linux添加双网卡
S32G USB-Redirector安装指南
VS code自动生成Doxygen格式注释
Linux下使用多线程下载
使用pandoc 生成带中文的pdf
minicom无法输入的问题解决办法
使用 systemd unit 添加一条路由规则
CMake 教程
步骤 1:基本起点
步骤 2:添加lib库
步骤 3:为库添加使用要求
步骤 4:添加生成器表达式
步骤 5:安装和测试
步骤 6:添加支持测试仪表板
步骤 7: 添加系统内省
步骤 8:自定义命令和生成的文
步骤 9:打包安装程序
步骤 10:选择静态库或共享库
步骤 11:添加导出配置
步骤 12:打包 Debug 和 Release
添加虚拟网卡
Vector AP 去掉防篡改校验
Vector AP startapplication编译与使用
Vector AP问题汇总
Vector AP大型项目开发流程
Vector AP EM
Vector AP 最简单的开发示例
Linux kernel 版本降级
Vector AP StartApplicaiton
startappplication-machine-design
startapplicaiton-machine-integration
amsr-vector-fs-em-executionmanager-design
amsr-vector-fs-em-executionmanager
Vector AP 复杂模型的开发
第一章 Machine和MachineDesign
第二章 Execute Manager
第三章 Log
第四章 State Manager
第五章 State Manager 源码的理解
第六章 Someip daemon
第七章 IPC Service Discovery Daemon
crond的使用方法
解决蓝牙鼠标在 Ubuntu 中单位时间内断开的问题
VPS服务器自建教程
v2rayA的客户端使用配置
GDB调试指南入门篇:揭开程序运行世界的神秘面纱
GDB调试指南高级篇:成为调试专家,掌控程序的命运
Linux安装PyQt5并配置Qt Designer
ADB 命令大全
GoogleTest(一)
GoogleTest(二)简单的TEST宏
GoogleTest(三)简单类函数测试
C++ Template
1. 函数模板
2. 类模板
3. 非类型模板参数
软件版本号规范
EPOLL
C++手札
C++ 使用{}初始化有哪些好处?
现代 C++ decltype 深入解析
函数对象(functor)
Linux性能剖析:CPU、内存、网络与I/O压力测试
AP StateManager
C++ Lambda表达式
C++ 中的Lambda表达式
Lambda 表达式语法
Lambda 表达式的示例
手动发送UDP数据包
pyqt5生成的UI界面不能输入中文
自己搭建repo镜像
摄影
Sony仿富士PP值设置
诗词歌赋
本文档使用 MrDoc 发布
-
+
首页
AP StateManager
## 总体结构  ## 整体层级说明 1. 信号处理,屏蔽一些中断信号,各模块都一样。因为AP的应用不像其他应用,中断退出没人管。AP的应用要退出必须走一些Autosar规定的必要流程,比如说进程状态切换,PHM通知等 2. 初始化应用。每个AP应用都要做的一些初始化,暂时没去细究到底Init了些什么 3. core state manager。主要有三块业务: - Platform state manager:主要是管理Machine FG 和功能组管理normal state manager的启动和关闭。 - normal state manager:功能组状态的管理 - UDP控制命令接收:接收UDP控制命令(明令长度为3个字节,第一个字节是`服务ID`,第二个是`命令字长度`,第三个是`命令字`)。切换功能组状态 4. 退出时的通知和清理 ## Core State Manager Core State Manager主要是管理和驱动PlatformStateManager和NormalStateManager 略.... ## PlatformStateManager 主要理解的有三个方面: 1. 状态(State) 2. 动作(SyncAction,AsyncAction) 3. 事件(Event) 4. 功能组(MachineFG) 5. 状态机(StateMachine) StateMachine通过Trigger一个Event产生,驱动一个或多个Action来切换切换功能组,到达某个新的State。 作为一个PlatformStateManager,首先要做的就是创建这些State,Action,Event。因此,我们会在kochi_platform_state_machine.h先创建这些材料。 ```cpp namespace kochi { namespace platformcorestatemanager { /** * @brief Implements platform state machine */ class KochiPlatformStateMachine final{ public: ... private: /** * @brief FG "MachineFG" 的功能组控制实例。 */ amsr::sm::function_group_control::FunctionGroupControl& fgc_machine_fg_; /** * @brief 状态机实例 */ amsr::sm::state_machine::StateMachine state_machine_{ amsr::sm::state_machine::CreateStateMachine("KochiPlatformStateMachine")}; /** * @brief 平台状态:启动 */ amsr::sm::state_machine::State state_startup_{state_machine_->CreateState("Startup")}; /** * @brief 平台状态:运行 */ amsr::sm::state_machine::State state_running_{state_machine_->CreateState("Running")}; /** * @brief 平台状态:关闭 */ amsr::sm::state_machine::State state_shutdown_{state_machine_->CreateState("Shutdown")}; /** * @brief 初始 FG 转换完成 */ amsr::sm::state_machine::Event event_initial_fg_transition_done_{state_machine_->CreateEvent("InitialFGTransitionDone")}; /** * @brief 事件:触发关闭 */ amsr::sm::state_machine::Event event_shutdown_{state_machine_->CreateEvent("Trigger Shutdown")}; /** * @brief 操作:将 "MachineFG" 的功能组状态设置为 "Running" */ amsr::sm::state_machine::AsyncAction action_set_machine_fg_running_{}; /** * @brief 操作:将 "MachineFG" 的功能组状态设置为 "Shutdown" */ amsr::sm::state_machine::AsyncAction action_set_machine_fg_shutdown_{}; ... ``` 上面的示例: - 创建功能组`fgc_machine_fg_`; - 创建并初始化状态机`state_machine_`("KochiPlatformStateMachine") - 创建并初始化状态`state_startup_`,`state_running_`,`state_shutdown_` - 创建并初始化事件`event_initial_fg_transition_done_`,`event_shutdown_` ### KochiPlatformStateMachine的初始化 这里说的初始化指的就是`KochiPlatformStateMachine`的构造函数。为了容易理解,做了部分简化,去掉了`KochiActionContext& action_context`,`KochiNormalStateMachine& kochi_normal_machine`两个参数。这两个参数实际是KochiNormalStateManager使用的,对于MachineFG的切换并不起什么作用。 #### 传参 构造函数: ```cpp KochiPlatformStateMachine::KochiPlatformStateMachine( amsr::sm::function_group_control::FunctionGroupControl& fgc_machine_fg) ``` 这里的`fgc_machine_fg`实际的初始化动作是在`CoreStateManger`中初始化的,如下: ```cpp /** * @brief 功能组MachineFG */ amsr::exec::FunctionGroup const kMachineFg{CreateFunctionGroup("MachineFG")}; /** * @brief FG "MachineFG" 的功能组控制实例 */ amsr::sm::function_group_control::FunctionGroupControl fgc_machine_fg_{kMachineFg}; ``` `CoreStateManger.fgc_machine_fg_` 作为实参传递给`PlatformStateManager`,最终会在初始化列表中去初始化`PlatformStateManager.fgc_machine_fg_`。 #### 初始化列表 `:fgc_machine_fg_{fgc_machine_fg}` 这个没什么好讲的,就是`CoreStateManger.fgc_machine_fg_` 作为实参传递给`PlatformStateManager`,最终会在初始化列表中去初始化`PlatformStateManager.fgc_machine_fg_`。 #### 构造函数(重点) 先看示例 ```cpp KochiPlatformStateMachine::KochiPlatformStateMachine( amsr::sm::function_group_control::FunctionGroupControl& fgc_machine_fg) : fgc_machine_fg_{fgc_machine_fg}{ // 注册初始机器状态转换回调函数,以存储转换结果。 amsr::sm::function_group_control::RegisterInitialMachineStateTransitionCallback( [this](ara::core::Result<void> result, ara::core::Optional<AsyncAction> action) { initial_machine_state_transition_result_ = result; if (initial_machine_state_transition_result_) { log_.LogInfo() << "@@kochi Initial state transition result: OK"; } else { log_.LogError() << "@@kochi Initial state transition reslut: " << initial_machine_state_transition_result_.Error(); } if (action) { action->Resume(initial_machine_state_transition_result_); } }); // 该回调函数仅在 SetState 操作完成时执行。它不会在 CreateStateAction 操作时执行。 // 在特定情况下,回调函数会在通过 SetState 操作将 MachineFG 设置为关机后执行。 fgc_machine_fg_.RegisterSetStateCallback( [this](ara::core::Result<void> result, amsr::exec::FunctionGroupState const& fgs, ara::core::Optional<AsyncAction> action) { if (result) { log_.LogInfo() << "@@kochi SetState for " << fgs.GetFunctionGroupName() << " to state " << fgs.GetStateName() << "was successful."; } else { log_.LogError() << "@@kochi SetState for " << fgs.GetFunctionGroupName() << " to state " << fgs.GetStateName() << "failed with error " << result.Error(); } if (action) { action->Resume(result); } }); // Startup: // Entry / // GetInitialMachineStateTransitionResult // SYNC // InitialFGTransitionDone AsyncAction const action_get_initial_transition_result{ state_machine_->CreateAsyncAction("@@kochi GetInitialMachineStateTransitionResult", [this](AsyncAction action){ //等待初始机器状态转换到启动,并评估结果 ara::core::Result<void> const result{ amsr::sm::function_group_control::GetInitialMachineStateTransitionResult(action) }; if (!result){ log_.LogError() << "@@kochi Initial state transition result: " << result.Error(); initial_machine_state_transition_result_.EmplaceError(result.Error()); action.Resume(result); } })}; SyncAction action_initial_fg_transition_done{ state_machine_->CreateSyncAction("@@kochi Trigger Event: InitialFGTransitionDone", event_initial_fg_transition_done_)}; state_startup_.AddEntryAction(action_get_initial_transition_result); state_startup_.AddEntryAction(state_machine_->GetSYNC()); state_startup_.AddEntryAction(action_initial_fg_transition_done); // Shutdown: // Entry / // EM Shutdown AsyncAction action_em_shutdown{ amsr::sm::function_group_control::CreateShutdownAction(*state_machine_, "@@kochi EM Shutdown")}; state_shutdown_.AddEntryAction( state_machine_->CreateSyncAction("@@kochi Log EM Shutdown", [this]() -> ara::core::Result<void>{ log_.LogInfo() << "@@kochi kochi normal manager Request graceful shutdown of the stack."; return {}; })); state_shutdown_.AddEntryAction(action_em_shutdown); // [*] --> Startup: // 这个transition是从initial状态切换到Startup状态的 Transition initial_transition{state_machine_->CreateInitialTransition("@@kochi Initial Transition", state_startup_)}; // Startup --> Running: // InitialFGTransitionDone // [InitialTransition == OK] / // SetState(MachineFG, Running) // SYNC Transition transition_startup_running{ state_machine_->CreateTransition("@@kochi Transition_Startup_Running", state_startup_, event_initial_fg_transition_done_, state_running_)}; transition_startup_running.SetGuard( state_machine_->CreateGuard("@@kochi InitialTransition == OK", [this](Guard guard) -> bool { bool const guard_result{ initial_machine_state_transition_result_ }; log_.LogInfo() << "@@kochi GUARD EVAL" << guard.ToString() << (guard_result ? "TRUE" : "FALSE"); return guard_result; })); action_set_machine_fg_running_ = fgc_machine_fg_.CreateStateAction(*state_machine_, kMachineFgRunning, "@@kochi set machine state running"); transition_startup_running.AddAction(action_set_machine_fg_running_); transition_startup_running.AddAction(state_machine_->GetSYNC()); // Startup --> Shutdown: // InitialFGTransitionDone // [InitialTransition != OK] Transition transition_startup_shutdown { state_machine_->CreateTransition( "@@kochi Transiton_Startup_Shutdown", state_startup_, event_initial_fg_transition_done_, state_shutdown_)}; transition_startup_shutdown.SetGuard( state_machine_->CreateGuard("@@kochi InitialTransition != OK", [this](Guard guard) -> bool { bool const guard_result{!initial_machine_state_transition_result_ }; log_.LogInfo() << "@@kochi GUARD EVAL" << guard.ToString() << (guard_result ? "TRUE" : "FALSE"); return guard_result; })); // Running --> Shutdown: // Shutdown // SetState(MachineFG, Shutdown) // SYNC Transition transition_running_shutdown{state_machine_->CreateTransition("Transition_Running Shutdown", state_running_, event_shutdown_, state_shutdown_)}; action_set_machine_fg_shutdown_ = state_machine_->CreateAsyncAction("@@kochi Set MachineFG Shutdown", [this](AsyncAction action){ ara::core::Result<void> const result{fgc_machine_fg_.SetState(kMachineFgShutDown, action)}; if (!result){ log_.LogError() << "@@kochi SetState result: " << result.Error(); action.Resume(result); } }); transition_running_shutdown.AddAction(action_set_machine_fg_shutdown_); transition_running_shutdown.AddAction(state_machine_->GetSYNC()); //错误处理函数 initial_transition.SetErrorHandler( [this] (TransitionContextInterface & transition_context) { ErrorHandler(transition_context); }); transition_startup_shutdown.SetErrorHandler( [this] (TransitionContextInterface & transition_context) { ErrorHandler(transition_context); }); transition_startup_running.SetErrorHandler( [this] (TransitionContextInterface & transition_context) { ErrorHandler(transition_context); }); transition_running_shutdown.SetErrorHandler( [this] (TransitionContextInterface & transition_context) { ErrorHandler(transition_context); }); // Register Guard evaluation callbacks state_machine_->RegisterGuardEvaluationStartCallback([this](GuardEvaluationInterface & guard_evaluation){ log_.LogInfo() << "@@kochi GuardEvaluationStartNotification"; guard_evaluation.Resume(); }); state_machine_->RegisterGuardEvaluationEndCallback([this](){ log_.LogInfo() << "@@kochi GuardEvaluationEndNotification"; }); amsr::sm::function_group_control::RegisterUndefinedStateCallback( [this](amsr::sm::function_group_control::FunctionGroupControl fgc){ log_.LogError() << "@@kochi Undefined state callback called for: " << fgc.GetFunctionGroup().GetFunctionGroupName() << " for state" << fgc.GetState().GetStateName() << "."; }); } ``` > MachineState在的有一个阶段容易漏掉,那就是Intialization,Autosar AP中并没有太多篇幅去介绍它,包括我们在用Davinchi做模型的时候,也没有看到Initial的状态,一般都是`StartUp`, `Verify`, `Running`, `Restart`, `Shutdown`这几个状态出现的比较多。MachineState并不能直接一下子切换到`Startup`, 首先需要做Init操作。(先知道有这么回事) 进入正题 构造函数一开始还就注册两个Callbak ```cpp amsr::sm::function_group_control::RegisterInitialMachineStateTransitionCallback( [this](ara::core::Result<void> result, ara::core::Optional<AsyncAction> action) { initial_machine_state_transition_result_ = result; if (initial_machine_state_transition_result_) { log_.LogInfo() << "@@kochi Initial state transition result: OK"; } else { log_.LogError() << "@@kochi Initial state transition reslut: " << initial_machine_state_transition_result_.Error(); } if (action) { action->Resume(initial_machine_state_transition_result_); } }); // 该回调函数仅在 SetState 操作完成时执行。它不会在 CreateStateAction 操作时执行。 // 在特定情况下,回调函数会在通过 SetState 操作将 MachineFG 设置为关机后执行。 fgc_machine_fg_.RegisterSetStateCallback( [this](ara::core::Result<void> result, amsr::exec::FunctionGroupState const& fgs, ara::core::Optional<AsyncAction> action) { if (result) { log_.LogInfo() << "@@kochi SetState for " << fgs.GetFunctionGroupName() << " to state " << fgs.GetStateName() << "was successful."; } else { log_.LogError() << "@@kochi SetState for " << fgs.GetFunctionGroupName() << " to state " << fgs.GetStateName() << "failed with error " << result.Error(); } if (action) { action->Resume(result); } }); ``` `RegisterInitialMachineStateTransitionCallback`当Init之后,会调用其Lambda函数,将`initial_machine_state_transition_result_`这个重要的标志位置位,`acttion->Resume(initial_machine_state_transition_result_)`会继续执行后续Action动作。 `RegisterSetStateCallback`回调函数仅在 `SetState` 操作完成时执行。 再看最后的三个回调函数 ```cpp // Register Guard evaluation callbacks state_machine_->RegisterGuardEvaluationStartCallback([this](GuardEvaluationInterface & guard_evaluation){ log_.LogInfo() << "@@kochi GuardEvaluationStartNotification"; guard_evaluation.Resume(); }); state_machine_->RegisterGuardEvaluationEndCallback([this](){ log_.LogInfo() << "@@kochi GuardEvaluationEndNotification"; }); amsr::sm::function_group_control::RegisterUndefinedStateCallback( [this](amsr::sm::function_group_control::FunctionGroupControl fgc){ log_.LogError() << "@@kochi Undefined state callback called for: " << fgc.GetFunctionGroup().GetFunctionGroupName() << " for state" << fgc.GetState().GetStateName() << "."; }); } ``` 每个state都有自己的Guard,Guard的作用就是判断我是否满足状态切换的条件,如果满足就可以切换状态。当一个事件来临后,进入`GuardEvaluationStartCallback`,`guard_evaluation`会调用`CreateGuard`时设置的Lambda函数去判断是否满足切换条件。每个`CreateGuard`时注册的Lambda函数都会跑一遍,以确定最终哪个状态条件为真,哪个条件为假。测试完之后调用`GuardEvaluationEndCallback`(如果中间有未定义的状态,会调用`UndefinedStateCallback`)。至此,应该切换到哪个状态,状态机已经清楚了。 以上是回调函数的说明,我们暂且放一边。现在去看看其他初始化,如Transition,State,Action等 设置状态的进入函数 ```cpp AsyncAction const action_get_initial_transition_result{ state_machine_->CreateAsyncAction("@@kochi GetInitialMachineStateTransitionResult", [this](AsyncAction action){ //等待初始机器状态转换到启动,并评估结果 ara::core::Result<void> const result{ amsr::sm::function_group_control::GetInitialMachineStateTransitionResult(action) }; if (!result){ log_.LogError() << "@@kochi Initial state transition result: " << result.Error(); initial_machine_state_transition_result_.EmplaceError(result.Error()); action.Resume(result); } })}; SyncAction action_initial_fg_transition_done{ state_machine_->CreateSyncAction("@@kochi Trigger Event: InitialFGTransitionDone", event_initial_fg_transition_done_)}; state_startup_.AddEntryAction(action_get_initial_transition_result); state_startup_.AddEntryAction(state_machine_->GetSYNC()); state_startup_.AddEntryAction(action_initial_fg_transition_done); ``` 这部分是对初始状态的一些检测,认为init完成之后,就执行一个`action_initial_fg_transition_done`的动作,`AddEntryAction`和`AddExitAction`的作用是,当我进入一个状态或退出一个状态,如`state_startup_`就会执行通过`AddEntryAction`和`AddExitAction`添加的动作 另:哪怕一条语句也没有,`MachineFG`依然会进入`Startup`状态 关机动作: 当有Normal Manager的关机Action或者自身的`action_em_shutdown`Action时,进入关机状态 ```cpp AsyncAction action_em_shutdown{ amsr::sm::function_group_control::CreateShutdownAction(*state_machine_, "@@kochi EM Shutdown")}; state_shutdown_.AddEntryAction( state_machine_->CreateSyncAction("@@kochi Log EM Shutdown", [this]() -> ara::core::Result<void>{ log_.LogInfo() << "@@kochi kochi normal manager Request graceful shutdown of the stack."; return {}; })); state_shutdown_.AddEntryAction(action_em_shutdown); ``` init_transition 在启动状态转换前,这个`CreateInitialTransition`是必须被先执行的,否则就无法切换 ```cpp // [*] --> Startup: Transition initial_transition{state_machine_->CreateInitialTransition("@@kochi Initial Transition", state_startup_)}; ``` `MachineFG`的状态切换`Startup --> Running` ```cpp // Startup --> Running: // InitialFGTransitionDone // [InitialTransition == OK] / // SetState(MachineFG, Running) // SYNC Transition transition_startup_running{ state_machine_->CreateTransition("@@kochi Transition_Startup_Running", state_startup_, event_initial_fg_transition_done_, state_running_)}; transition_startup_running.SetGuard( state_machine_->CreateGuard("@@kochi InitialTransition == OK", [this](Guard guard) -> bool { bool const guard_result{ initial_machine_state_transition_result_ }; log_.LogInfo() << "@@kochi GUARD EVAL" << guard.ToString() << (guard_result ? "TRUE" : "FALSE"); return guard_result; })); action_set_machine_fg_running_ = fgc_machine_fg_.CreateStateAction(*state_machine_, kMachineFgRunning, "@@kochi set machine state running"); transition_startup_running.AddAction(action_set_machine_fg_running_); transition_startup_running.AddAction(state_machine_->GetSYNC()); ``` 状态切换需要`transition`, `guard`, `action` ```cpp /*! * \brief Creates a transition instance in this state machine. * \param[in] logging_identifier String identifier used for logging. * \param[in] source_state Source state of this transition. Only pass instances that have been created using * StateMachineInterface::Create*(). * \param[in] event Event that shall trigger this transition. Only pass instances that have been created using * StateMachineInterface::Create*(). * \param[in] target_state Target state of this transition. Only pass instances that have been created using * StateMachineInterface::Create*(). * * \return The created transition. * \context InitPhase * \pre State machine must be in status initializing, i.e. Start must not have been called before. * \threadsafe FALSE * \reentrant FALSE * \synchronous TRUE * \vpublic */ virtual Transition CreateTransition(ara::core::String&& logging_identifier, State const& source_state, Event const& event, State const& target_state) ``` Transition的第二个参数指定了原状态(从哪个状态开始),第三个参数是触发事件(发生了什么事件我就切换),第四个参数是目标状态(要切换到哪个状态) `action_set_machine_fg_running_`,要从`state_startup_`,切换到`state_running_`,触发这次切换的事件是`event_initial_fg_transition_done_` 动作有了,接下来`Transition`就可以设置`Guard`。Guard的作用就是判断我切换条件是否满足。如`bool const guard_result{ initial_machine_state_transition_result_ };`, 当guard_result为true的时候,就表示可以状态切换(`initial_machine_state_transition_result_`是在`CreateInitialTransition`初始化后的回调函数`InitialMachineStateTransitionCallback`中设置的)。当`event_initial_fg_transition_done_`事件发生,`GuardEvaluationStartCallback`的回调函数会去验证各个`Guard`是否条件为真,来确定正确的状态切换
admin
2024年8月30日 17:10
转发文档
收藏文档
上一篇
下一篇
手机扫码
复制链接
手机扫一扫转发分享
复制链接
Markdown文件
分享
链接
类型
密码
更新密码