一,前言
二,代码架构设计
接着就是按顺序发命令,这个顺序理解为状态机,通过状态机不断运行,从开始直至结束。那么在c++中常用的就是map依次扫描,而xml的信息就可以存储到map中。那么就变成了命令可以动态可配置,符合我要做一个通用的boot上位机的功能需求。
三,xml结构体设计
<Step1>
<CanID>F_IDCanID>
<ServiceType>SID10ServiceType>
<Request>10,03Request>
<Response>50,03Response>
<Delay_ms>0Delay_ms>
Step1>
<Step2>
<CanID>P_IDCanID>
<ServiceType>SID10ServiceType>
<Request>10,02Request>
<Response>50,02Response>
<Delay_ms>0Delay_ms>
Step2>
<Step3>
<CanID>F_IDCanID>
<ServiceType>SID27ServiceType>
<Request>27,09Request>
<Response>67,09,seedResponse>
<Delay_ms>0Delay_ms>
Step3>
四,c++状态机设计
至于c++状态机设计网上太多了,这是经典的。主要用context上下文调度来切换state到下一个state,这个看上去有点像单片机的FreeRTOS切换任务一样。
我先加入了3条服务,用来搭建和验证框架的。如下为读取xml的ServiceType来创建任务类的map数组。context start后,则调用_context->Update(msg);
按map顺序调用状态机了。void CanListener::contextEnable(){
_context = new FsmState::Context();
// 根据xml创建状态机
getXMLandCreateState();
// 开始状态机
_context->Start(_startType);}void CanListener::getXMLandCreateState(){
QMap
::iterator iter = xmlreader::instance().getCmdInfBegin(); _startType = iter.key().toStdString();//iter.value().ServiceType.toStdString();
while (iter != xmlreader::instance().getCmdInfEnd())
{
// 通过xml的ServiceType来创建任务类的map数组
_step = iter.key();
QString ServiceType = iter.value().ServiceType;
if(ServiceType == "SID10")
{
_context->CreateState(new SID10(), "SID10","",_step.toStdString());
}
else if(ServiceType == "SID27")
{
_context->CreateState(new SID27(), "SID27","",_step.toStdString());
}
else if(ServiceType == "SID31")
{
_context->CreateState(new SID31(), "SID31","",_step.toStdString());
}
else
{
//add later
}
iter++;
}}
五,验证截图
如下截图,解析xml成功,且报文发送的顺序正确,但是rx报文的时间不会更新,之后要修改的。 image.png 六,小结
闲着没事,就喜欢创造发明小工具,还有很多功能没加,且听下回分解~
作者:applecai
链接:https://www.jianshu.com/p/a3f6b7c0a68f
来源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。原文始发于微信公众号(汇编语言):45.QT boot工具导入xml动态创建状态机--Apple的学习笔记
免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论