概述
在处理时序问题上优选的就是Stateflow,利用状态之间的跳转完成时序任务的编码,非常的简洁直观高效。但是代价是有的,建模太过自由,在生成代码上可能就会产生几倍代码量。避免这个问题,就有必要仔细考虑一下模型是如何生成代码的。
简单的说就是,每个状态对应一个状态标志位,所有的状态标志位(包括整个模型所有chart)会在定义在一个结构体中。状态之间的跳转通过Switch-Case完成,每个case下代码内容主要包含以下几个部分:该状态中的du语句;判断是否要跳出该状态的语句以及该状态的exist语句和目标状态的entry语句。可以对比下如下的一个状态图
代码如下(删除掉自动生成的注释,替换为对应解释的注释):
void Chart_step(void)
{
int32_T tmp;
/*Step1: chart 初始化操作*/
if (Chart_DW.is_active_c3_Chart == 0U) {
/*Step1.1:初始化完成后标志位至位*/
Chart_DW.is_active_c3_Chart = 1U;
/*Step1.2:选择初始化的状态*/
Chart_DW.is_c3_Chart = Chart_IN_Initial;
/*Step1.3:初始化动作*/
Chart_Y.a = 1;
} else {
/*Step2:状态转移对应的switch-case循环*/
switch (Chart_DW.is_c3_Chart) {
/*Step2.1:Initial状态Case语句*/
case Chart_IN_Initial:
/*Step2.1.1:判断是否满足该状态的退出条件*/
if (Chart_Y.a == 20) {
/*Step2.1.2:满足退出条件后的本状态exist语句*/
Chart_Y.b = 1;
/*Step2.1.3:满足退出条件后更新状态*/
Chart_DW.is_c3_Chart = Chart_IN_S1;
/*Step2.1.4:满足退出条件后目标状态的Entry语句 */
Chart_Y.a = 0;
} else {
/*Step2.1.5:不满足退出状态时执行的during语句*/
tmp = Chart_Y.a + 1;
if (tmp > 32767) {
tmp = 32767;
}
Chart_Y.a = (int16_T)tmp;
}
break;
/*Step2.2:S1状态Case语句*/
case Chart_IN_S1:
if (Chart_Y.b == 20) {
Chart_Y.a = 1;
Chart_DW.is_c3_Chart = Chart_IN_S2;
Chart_Y.b = 0;
} else {
tmp = Chart_Y.b + 1;
if (tmp > 32767) {
tmp = 32767;
}
Chart_Y.b = (int16_T)tmp;
}
break;
/*Step2.3:S2状态Case语句*/
default:
if (Chart_Y.b == 25) {
Chart_DW.is_c3_Chart = Chart_IN_Initial;
Chart_Y.a = 1;
} else {
tmp = Chart_Y.b + 1;
if (tmp > 32767) {
tmp = 32767;
}
Chart_Y.b = (int16_T)tmp;
}
break;
}
}
}
需要注意的是,每一条转移路径都会包含该转移路径上的退出条件判断代码,该状态的exist语句,目标状态的entry语句,状态的更新等几个部分。如果entry语句比较复杂,转移路径比较多,那么重复的代码量可能就会非常大了。
最后
以上就是聪慧短靴为你收集整理的Stateflow 状态机是怎么代码实现的的全部内容,希望文章能够帮你解决Stateflow 状态机是怎么代码实现的所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复