How Stateflow state machine is implemented in code

The preferred method for dealing with timing problems is Stateflow, which uses jumps between states to complete the coding of timing tasks, which is very simple, intuitive and efficient. But there is a price. The modeling is too free, and the generated code may generate several times the amount of code. To avoid this problem, it is necessary to think carefully about how the model generates code.
Simply put, each state corresponds to a state flag, and all state flags (including all charts in the entire model) will be defined in a structure. The jump between states is completed through Switch-Case. The code content under each case mainly includes the following parts: the du statement in the state; the statement to determine whether to jump out of the state, the exist statement of the state and the target state. entry statement. You can compare the following state diagram. The State diagram
code is as follows (delete the automatically generated comment and replace it with the comment corresponding to the explanation):

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;
    }
  }
}

It should be noted that each transition path will include the exit condition judgment code on the transition path, the exist statement of the state, the entry statement of the target state, and the update of the state. If the entry statement is more complex and there are many transfer paths, the amount of repeated code may be very large.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325833455&siteId=291194637