master/fsm_change.c
changeset 1989 6aa393418fb3
parent 1921 d9cf40facbc4
child 1967 c41b4f4af645
equal deleted inserted replaced
1988:ea38efeeb7b3 1989:6aa393418fb3
   180     if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
   180     if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
   181         return;
   181         return;
   182 
   182 
   183     if (datagram->state != EC_DATAGRAM_RECEIVED) {
   183     if (datagram->state != EC_DATAGRAM_RECEIVED) {
   184         fsm->state = ec_fsm_change_state_error;
   184         fsm->state = ec_fsm_change_state_error;
   185         EC_ERR("Failed to receive state datagram from slave %u: ",
   185         EC_SLAVE_ERR(slave, "Failed to receive state datagram: ");
   186                fsm->slave->ring_position);
       
   187         ec_datagram_print_state(datagram);
   186         ec_datagram_print_state(datagram);
   188         return;
   187         return;
   189     }
   188     }
   190 
   189 
   191     if (fsm->take_time) {
   190     if (fsm->take_time) {
   196     if (datagram->working_counter == 0) {
   195     if (datagram->working_counter == 0) {
   197         if (datagram->jiffies_received - fsm->jiffies_start >= 3 * HZ) {
   196         if (datagram->jiffies_received - fsm->jiffies_start >= 3 * HZ) {
   198             char state_str[EC_STATE_STRING_SIZE];
   197             char state_str[EC_STATE_STRING_SIZE];
   199             ec_state_string(fsm->requested_state, state_str, 0);
   198             ec_state_string(fsm->requested_state, state_str, 0);
   200             fsm->state = ec_fsm_change_state_error;
   199             fsm->state = ec_fsm_change_state_error;
   201             EC_ERR("Failed to set state %s on slave %u: ",
   200             EC_SLAVE_ERR(slave, "Failed to set state %s: ", state_str);
   202                     state_str, fsm->slave->ring_position);
       
   203             ec_datagram_print_wc_error(datagram);
   201             ec_datagram_print_wc_error(datagram);
   204             return;
   202             return;
   205         }
   203         }
   206 
   204 
   207         // repeat writing new state to slave
   205         // repeat writing new state to slave
   213 
   211 
   214     if (unlikely(datagram->working_counter > 1)) {
   212     if (unlikely(datagram->working_counter > 1)) {
   215         char state_str[EC_STATE_STRING_SIZE];
   213         char state_str[EC_STATE_STRING_SIZE];
   216         ec_state_string(fsm->requested_state, state_str, 0);
   214         ec_state_string(fsm->requested_state, state_str, 0);
   217         fsm->state = ec_fsm_change_state_error;
   215         fsm->state = ec_fsm_change_state_error;
   218         EC_ERR("Failed to set state %s on slave %u: ",
   216         EC_SLAVE_ERR(slave, "Failed to set state %s: ", state_str);
   219                 state_str, fsm->slave->ring_position);
       
   220         ec_datagram_print_wc_error(datagram);
   217         ec_datagram_print_wc_error(datagram);
   221         return;
   218         return;
   222     }
   219     }
   223 
   220 
   224     fsm->take_time = 1;
   221     fsm->take_time = 1;
   246     if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
   243     if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
   247         return;
   244         return;
   248 
   245 
   249     if (datagram->state != EC_DATAGRAM_RECEIVED) {
   246     if (datagram->state != EC_DATAGRAM_RECEIVED) {
   250         fsm->state = ec_fsm_change_state_error;
   247         fsm->state = ec_fsm_change_state_error;
   251         EC_ERR("Failed to receive state checking datagram from slave %u: ",
   248         EC_SLAVE_ERR(slave, "Failed to receive state checking datagram: ");
   252                slave->ring_position);
       
   253         ec_datagram_print_state(datagram);
   249         ec_datagram_print_state(datagram);
   254         return;
   250         return;
   255     }
   251     }
   256 
   252 
   257     if (datagram->working_counter != 1) {
   253     if (datagram->working_counter != 1) {
   258         char req_state[EC_STATE_STRING_SIZE];
   254         char req_state[EC_STATE_STRING_SIZE];
   259         ec_state_string(fsm->requested_state, req_state, 0);
   255         ec_state_string(fsm->requested_state, req_state, 0);
   260         fsm->state = ec_fsm_change_state_error;
   256         fsm->state = ec_fsm_change_state_error;
   261         EC_ERR("Failed to check state %s on slave %u: ",
   257         EC_SLAVE_ERR(slave, "Failed to check state %s: ", req_state);
   262                req_state, slave->ring_position);
       
   263         ec_datagram_print_wc_error(datagram);
   258         ec_datagram_print_wc_error(datagram);
   264         return;
   259         return;
   265     }
   260     }
   266 
   261 
   267     if (fsm->take_time) {
   262     if (fsm->take_time) {
   286             // Slave spontaneously changed its state just before the new state
   281             // Slave spontaneously changed its state just before the new state
   287             // was written. Accept current state as old state and wait for
   282             // was written. Accept current state as old state and wait for
   288             // state change
   283             // state change
   289             fsm->spontaneous_change = 1;
   284             fsm->spontaneous_change = 1;
   290             fsm->old_state = slave->current_state;
   285             fsm->old_state = slave->current_state;
   291             EC_WARN("Slave %u changed to %s in the meantime.\n",
   286             EC_SLAVE_WARN(slave, "Changed to %s in the meantime.\n",
   292                     slave->ring_position, cur_state);
   287                     cur_state);
   293             goto check_again;
   288             goto check_again;
   294         }
   289         }
   295 
   290 
   296         // state change error
   291         // state change error
   297 
   292 
   298         slave->error_flag = 1;
   293         slave->error_flag = 1;
   299         ec_state_string(fsm->requested_state, req_state, 0);
   294         ec_state_string(fsm->requested_state, req_state, 0);
   300 
   295 
   301         EC_ERR("Failed to set %s state, slave %u refused state change (%s).\n",
   296         EC_SLAVE_ERR(slave, "Failed to set %s state, slave refused state"
   302                req_state, slave->ring_position, cur_state);
   297                 " change (%s).\n", req_state, cur_state);
   303         // fetch AL status error code
   298         // fetch AL status error code
   304         ec_datagram_fprd(datagram, slave->station_address, 0x0134, 2);
   299         ec_datagram_fprd(datagram, slave->station_address, 0x0134, 2);
   305         ec_datagram_zero(datagram);
   300         ec_datagram_zero(datagram);
   306         fsm->retries = EC_FSM_RETRIES;
   301         fsm->retries = EC_FSM_RETRIES;
   307         fsm->state = ec_fsm_change_state_code;
   302         fsm->state = ec_fsm_change_state_code;
   314             EC_AL_STATE_CHANGE_TIMEOUT * HZ) {
   309             EC_AL_STATE_CHANGE_TIMEOUT * HZ) {
   315         // timeout while checking
   310         // timeout while checking
   316         char state_str[EC_STATE_STRING_SIZE];
   311         char state_str[EC_STATE_STRING_SIZE];
   317         ec_state_string(fsm->requested_state, state_str, 0);
   312         ec_state_string(fsm->requested_state, state_str, 0);
   318         fsm->state = ec_fsm_change_state_error;
   313         fsm->state = ec_fsm_change_state_error;
   319         EC_ERR("Timeout while setting state %s on slave %u.\n",
   314         EC_SLAVE_ERR(slave, "Timeout while setting state %s.\n", state_str);
   320                 state_str, slave->ring_position);
       
   321         return;
   315         return;
   322     }
   316     }
   323 
   317 
   324  check_again:
   318  check_again:
   325     // no timeout yet. check again
   319     // no timeout yet. check again
   404     if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
   398     if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
   405         return;
   399         return;
   406 
   400 
   407     if (datagram->state != EC_DATAGRAM_RECEIVED) {
   401     if (datagram->state != EC_DATAGRAM_RECEIVED) {
   408         fsm->state = ec_fsm_change_state_error;
   402         fsm->state = ec_fsm_change_state_error;
   409         EC_ERR("Failed to receive AL status code datagram from slave %u: ",
   403         EC_SLAVE_ERR(fsm->slave, "Failed to receive"
   410                fsm->slave->ring_position);
   404                 " AL status code datagram: ");
   411         ec_datagram_print_state(datagram);
   405         ec_datagram_print_state(datagram);
   412         return;
   406         return;
   413     }
   407     }
   414 
   408 
   415     if (datagram->working_counter != 1) {
   409     if (datagram->working_counter != 1) {
   416         EC_WARN("Reception of AL status code datagram failed: ");
   410         EC_SLAVE_WARN(fsm->slave, "Reception of AL status code"
       
   411                 " datagram failed: ");
   417         ec_datagram_print_wc_error(datagram);
   412         ec_datagram_print_wc_error(datagram);
   418     } else {
   413     } else {
   419         code = EC_READ_U16(datagram->data);
   414         code = EC_READ_U16(datagram->data);
   420         for (al_msg = al_status_messages; al_msg->code != 0xffff; al_msg++) {
   415         for (al_msg = al_status_messages; al_msg->code != 0xffff; al_msg++) {
   421             if (al_msg->code != code) continue;
   416             if (al_msg->code != code) continue;
   422             EC_ERR("AL status message 0x%04X: \"%s\".\n",
   417             EC_SLAVE_ERR(fsm->slave, "AL status message 0x%04X: \"%s\".\n",
   423                     al_msg->code, al_msg->message);
   418                     al_msg->code, al_msg->message);
   424             break;
   419             break;
   425         }
   420         }
   426         if (!al_msg->code)
   421         if (!al_msg->code)
   427             EC_ERR("Unknown AL status code 0x%04X.\n", code);
   422             EC_SLAVE_ERR(fsm->slave, "Unknown AL status code 0x%04X.\n",
       
   423                     code);
   428     }
   424     }
   429 
   425 
   430     // acknowledge "old" slave state
   426     // acknowledge "old" slave state
   431     ec_fsm_change_state_start_ack(fsm); // execute immediately
   427     ec_fsm_change_state_start_ack(fsm); // execute immediately
   432 }
   428 }
   463     if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
   459     if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
   464         return;
   460         return;
   465 
   461 
   466     if (datagram->state != EC_DATAGRAM_RECEIVED) {
   462     if (datagram->state != EC_DATAGRAM_RECEIVED) {
   467         fsm->state = ec_fsm_change_state_error;
   463         fsm->state = ec_fsm_change_state_error;
   468         EC_ERR("Failed to receive state ack datagram for slave %u: ",
   464         EC_SLAVE_ERR(slave, "Failed to receive state ack datagram: ");
   469                slave->ring_position);
       
   470         ec_datagram_print_state(datagram);
   465         ec_datagram_print_state(datagram);
   471         return;
   466         return;
   472     }
   467     }
   473 
   468 
   474     if (datagram->working_counter != 1) {
   469     if (datagram->working_counter != 1) {
   475         fsm->state = ec_fsm_change_state_error;
   470         fsm->state = ec_fsm_change_state_error;
   476         EC_ERR("Reception of state ack datagram failed on slave %u: ",
   471         EC_SLAVE_ERR(slave, "Reception of state ack datagram failed: ");
   477                 slave->ring_position);
       
   478         ec_datagram_print_wc_error(datagram);
   472         ec_datagram_print_wc_error(datagram);
   479         return;
   473         return;
   480     }
   474     }
   481 
   475 
   482     fsm->take_time = 1;
   476     fsm->take_time = 1;
   503     if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
   497     if (datagram->state == EC_DATAGRAM_TIMED_OUT && fsm->retries--)
   504         return;
   498         return;
   505 
   499 
   506     if (datagram->state != EC_DATAGRAM_RECEIVED) {
   500     if (datagram->state != EC_DATAGRAM_RECEIVED) {
   507         fsm->state = ec_fsm_change_state_error;
   501         fsm->state = ec_fsm_change_state_error;
   508         EC_ERR("Failed to receive state ack check datagram from slave %u: ",
   502         EC_SLAVE_ERR(slave, "Failed to receive state ack check datagram: ");
   509                slave->ring_position);
       
   510         ec_datagram_print_state(datagram);
   503         ec_datagram_print_state(datagram);
   511         return;
   504         return;
   512     }
   505     }
   513 
   506 
   514     if (datagram->working_counter != 1) {
   507     if (datagram->working_counter != 1) {
   515         fsm->state = ec_fsm_change_state_error;
   508         fsm->state = ec_fsm_change_state_error;
   516         EC_ERR("Reception of state ack check datagram failed on slave %u: ",
   509         EC_SLAVE_ERR(slave, "Reception of state ack check datagram failed: ");
   517                 slave->ring_position);
       
   518         ec_datagram_print_wc_error(datagram);
   510         ec_datagram_print_wc_error(datagram);
   519         return;
   511         return;
   520     }
   512     }
   521 
   513 
   522     if (fsm->take_time) {
   514     if (fsm->take_time) {
   533             fsm->state = ec_fsm_change_state_error;
   525             fsm->state = ec_fsm_change_state_error;
   534         }
   526         }
   535         else { // EC_FSM_CHANGE_MODE_ACK_ONLY
   527         else { // EC_FSM_CHANGE_MODE_ACK_ONLY
   536             fsm->state = ec_fsm_change_state_end;
   528             fsm->state = ec_fsm_change_state_end;
   537         }
   529         }
   538         EC_INFO("Acknowledged state %s on slave %u.\n",
   530         EC_SLAVE_INFO(slave, "Acknowledged state %s.\n", state_str);
   539                 state_str, slave->ring_position);
       
   540         return;
   531         return;
   541     }
   532     }
   542 
   533 
   543     if (datagram->jiffies_received - fsm->jiffies_start >=
   534     if (datagram->jiffies_received - fsm->jiffies_start >=
   544             EC_AL_STATE_CHANGE_TIMEOUT * HZ) {
   535             EC_AL_STATE_CHANGE_TIMEOUT * HZ) {
   545         // timeout while checking
   536         // timeout while checking
   546         char state_str[EC_STATE_STRING_SIZE];
   537         char state_str[EC_STATE_STRING_SIZE];
   547         ec_state_string(slave->current_state, state_str, 0);
   538         ec_state_string(slave->current_state, state_str, 0);
   548         fsm->state = ec_fsm_change_state_error;
   539         fsm->state = ec_fsm_change_state_error;
   549         EC_ERR("Timeout while acknowledging state %s on slave %u.\n",
   540         EC_SLAVE_ERR(slave, "Timeout while acknowledging state %s.\n",
   550                state_str, slave->ring_position);
   541                 state_str);
   551         return;
   542         return;
   552     }
   543     }
   553 
   544 
   554     // reread new AL status
   545     // reread new AL status
   555     ec_datagram_fprd(datagram, slave->station_address, 0x0130, 2);
   546     ec_datagram_fprd(datagram, slave->station_address, 0x0130, 2);