master/master.c
branchstable-1.5
changeset 2421 bc2d4bf9cbe5
parent 2419 fdb85a806585
child 2433 3bdd7a747fae
equal deleted inserted replaced
2420:69056c46aa4d 2421:bc2d4bf9cbe5
   154     master->injection_seq_fsm = 0;
   154     master->injection_seq_fsm = 0;
   155     master->injection_seq_rt = 0;
   155     master->injection_seq_rt = 0;
   156 
   156 
   157     master->slaves = NULL;
   157     master->slaves = NULL;
   158     master->slave_count = 0;
   158     master->slave_count = 0;
   159     
   159 
   160     INIT_LIST_HEAD(&master->configs);
   160     INIT_LIST_HEAD(&master->configs);
   161     INIT_LIST_HEAD(&master->domains);
   161     INIT_LIST_HEAD(&master->domains);
   162 
   162 
   163     master->app_time = 0ULL;
   163     master->app_time = 0ULL;
   164     master->app_start_time = 0ULL;
   164     master->app_start_time = 0ULL;
   170     init_waitqueue_head(&master->scan_queue);
   170     init_waitqueue_head(&master->scan_queue);
   171 
   171 
   172     master->config_busy = 0;
   172     master->config_busy = 0;
   173     sema_init(&master->config_sem, 1);
   173     sema_init(&master->config_sem, 1);
   174     init_waitqueue_head(&master->config_queue);
   174     init_waitqueue_head(&master->config_queue);
   175     
   175 
   176     INIT_LIST_HEAD(&master->datagram_queue);
   176     INIT_LIST_HEAD(&master->datagram_queue);
   177     master->datagram_index = 0;
   177     master->datagram_index = 0;
   178 
   178 
   179     INIT_LIST_HEAD(&master->ext_datagram_queue);
   179     INIT_LIST_HEAD(&master->ext_datagram_queue);
   180     sema_init(&master->ext_queue_sem, 1);
   180     sema_init(&master->ext_queue_sem, 1);
   181 
   181 
   182     INIT_LIST_HEAD(&master->external_datagram_queue);
   182     INIT_LIST_HEAD(&master->external_datagram_queue);
   183     
   183 
   184     // send interval in IDLE phase
   184     // send interval in IDLE phase
   185     ec_master_set_send_interval(master, 1000000 / HZ);
   185     ec_master_set_send_interval(master, 1000000 / HZ);
   186 
   186 
   187     master->debug_level = debug_level;
   187     master->debug_level = debug_level;
   188     master->stats.timeouts = 0;
   188     master->stats.timeouts = 0;
   272 
   272 
   273     // init character device
   273     // init character device
   274     ret = ec_cdev_init(&master->cdev, master, device_number);
   274     ret = ec_cdev_init(&master->cdev, master, device_number);
   275     if (ret)
   275     if (ret)
   276         goto out_clear_sync_mon;
   276         goto out_clear_sync_mon;
   277     
   277 
   278 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
   278 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 27)
   279     master->class_device = device_create(class, NULL,
   279     master->class_device = device_create(class, NULL,
   280             MKDEV(MAJOR(device_number), master->index), NULL,
   280             MKDEV(MAJOR(device_number), master->index), NULL,
   281             "EtherCAT%u", master->index);
   281             "EtherCAT%u", master->index);
   282 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
   282 #elif LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 26)
   332 #else
   332 #else
   333     class_device_unregister(master->class_device);
   333     class_device_unregister(master->class_device);
   334 #endif
   334 #endif
   335 
   335 
   336     ec_cdev_clear(&master->cdev);
   336     ec_cdev_clear(&master->cdev);
   337     
   337 
   338 #ifdef EC_EOE
   338 #ifdef EC_EOE
   339     ec_master_clear_eoe_handlers(master);
   339     ec_master_clear_eoe_handlers(master);
   340 #endif
   340 #endif
   341     ec_master_clear_domains(master);
   341     ec_master_clear_domains(master);
   342     ec_master_clear_slave_configs(master);
   342     ec_master_clear_slave_configs(master);
   510         EC_MASTER_ERR(master, "Failed to start master thread (error %i)!\n",
   510         EC_MASTER_ERR(master, "Failed to start master thread (error %i)!\n",
   511                 err);
   511                 err);
   512         master->thread = NULL;
   512         master->thread = NULL;
   513         return err;
   513         return err;
   514     }
   514     }
   515     
   515 
   516     return 0;
   516     return 0;
   517 }
   517 }
   518 
   518 
   519 /*****************************************************************************/
   519 /*****************************************************************************/
   520 
   520 
   523 void ec_master_thread_stop(
   523 void ec_master_thread_stop(
   524         ec_master_t *master /**< EtherCAT master */
   524         ec_master_t *master /**< EtherCAT master */
   525         )
   525         )
   526 {
   526 {
   527     unsigned long sleep_jiffies;
   527     unsigned long sleep_jiffies;
   528     
   528 
   529     if (!master->thread) {
   529     if (!master->thread) {
   530         EC_MASTER_WARN(master, "%s(): Already finished!\n", __func__);
   530         EC_MASTER_WARN(master, "%s(): Already finished!\n", __func__);
   531         return;
   531         return;
   532     }
   532     }
   533 
   533 
   537     master->thread = NULL;
   537     master->thread = NULL;
   538     EC_MASTER_INFO(master, "Master thread exited.\n");
   538     EC_MASTER_INFO(master, "Master thread exited.\n");
   539 
   539 
   540     if (master->fsm_datagram.state != EC_DATAGRAM_SENT)
   540     if (master->fsm_datagram.state != EC_DATAGRAM_SENT)
   541         return;
   541         return;
   542     
   542 
   543     // wait for FSM datagram
   543     // wait for FSM datagram
   544     sleep_jiffies = max(HZ / 100, 1); // 10 ms, at least 1 jiffy
   544     sleep_jiffies = max(HZ / 100, 1); // 10 ms, at least 1 jiffy
   545     schedule_timeout(sleep_jiffies);
   545     schedule_timeout(sleep_jiffies);
   546 }
   546 }
   547 
   547 
   584 void ec_master_leave_idle_phase(ec_master_t *master /**< EtherCAT master */)
   584 void ec_master_leave_idle_phase(ec_master_t *master /**< EtherCAT master */)
   585 {
   585 {
   586     EC_MASTER_DBG(master, 1, "IDLE -> ORPHANED.\n");
   586     EC_MASTER_DBG(master, 1, "IDLE -> ORPHANED.\n");
   587 
   587 
   588     master->phase = EC_ORPHANED;
   588     master->phase = EC_ORPHANED;
   589     
   589 
   590 #ifdef EC_EOE
   590 #ifdef EC_EOE
   591     ec_master_eoe_stop(master);
   591     ec_master_eoe_stop(master);
   592 #endif
   592 #endif
   593     ec_master_thread_stop(master);
   593     ec_master_thread_stop(master);
   594 
   594 
   645         if (ret) {
   645         if (ret) {
   646             EC_MASTER_INFO(master, "Waiting for slave scan"
   646             EC_MASTER_INFO(master, "Waiting for slave scan"
   647                     " interrupted by signal.\n");
   647                     " interrupted by signal.\n");
   648             goto out_allow;
   648             goto out_allow;
   649         }
   649         }
   650         
   650 
   651         EC_MASTER_DBG(master, 1, "Waiting for pending"
   651         EC_MASTER_DBG(master, 1, "Waiting for pending"
   652                 " slave scan returned.\n");
   652                 " slave scan returned.\n");
   653     }
   653     }
   654 
   654 
   655     // set states for all slaves
   655     // set states for all slaves
   670     master->phase = EC_OPERATION;
   670     master->phase = EC_OPERATION;
   671     master->app_send_cb = NULL;
   671     master->app_send_cb = NULL;
   672     master->app_receive_cb = NULL;
   672     master->app_receive_cb = NULL;
   673     master->app_cb_data = NULL;
   673     master->app_cb_data = NULL;
   674     return ret;
   674     return ret;
   675     
   675 
   676 out_allow:
   676 out_allow:
   677     master->allow_scan = 1;
   677     master->allow_scan = 1;
   678 out_return:
   678 out_return:
   679     return ret;
   679     return ret;
   680 }
   680 }
  1033 /*****************************************************************************/
  1033 /*****************************************************************************/
  1034 
  1034 
  1035 /** Processes a received frame.
  1035 /** Processes a received frame.
  1036  *
  1036  *
  1037  * This function is called by the network driver for every received frame.
  1037  * This function is called by the network driver for every received frame.
  1038  * 
  1038  *
  1039  * \return 0 in case of success, else < 0
  1039  * \return 0 in case of success, else < 0
  1040  */
  1040  */
  1041 void ec_master_receive_datagrams(ec_master_t *master, /**< EtherCAT master */
  1041 void ec_master_receive_datagrams(ec_master_t *master, /**< EtherCAT master */
  1042                                  const uint8_t *frame_data, /**< frame data */
  1042                                  const uint8_t *frame_data, /**< frame data */
  1043                                  size_t size /**< size of the received data */
  1043                                  size_t size /**< size of the received data */
  1355 #ifdef EC_USE_HRTIMER
  1355 #ifdef EC_USE_HRTIMER
  1356     size_t sent_bytes;
  1356     size_t sent_bytes;
  1357 #endif
  1357 #endif
  1358 
  1358 
  1359     // send interval in IDLE phase
  1359     // send interval in IDLE phase
  1360     ec_master_set_send_interval(master, 1000000 / HZ); 
  1360     ec_master_set_send_interval(master, 1000000 / HZ);
  1361 
  1361 
  1362     EC_MASTER_DBG(master, 1, "Idle thread running with send interval = %u us,"
  1362     EC_MASTER_DBG(master, 1, "Idle thread running with send interval = %u us,"
  1363             " max data size=%zu\n", master->send_interval,
  1363             " max data size=%zu\n", master->send_interval,
  1364             master->max_queue_size);
  1364             master->max_queue_size);
  1365 
  1365 
  1408 #else
  1408 #else
  1409             schedule();
  1409             schedule();
  1410 #endif
  1410 #endif
  1411         }
  1411         }
  1412     }
  1412     }
  1413     
  1413 
  1414     EC_MASTER_DBG(master, 1, "Master IDLE thread exiting...\n");
  1414     EC_MASTER_DBG(master, 1, "Master IDLE thread exiting...\n");
  1415 
  1415 
  1416     return 0;
  1416     return 0;
  1417 }
  1417 }
  1418 
  1418 
  1466         else {
  1466         else {
  1467             schedule();
  1467             schedule();
  1468         }
  1468         }
  1469 #endif
  1469 #endif
  1470     }
  1470     }
  1471     
  1471 
  1472     EC_MASTER_DBG(master, 1, "Master OP thread exiting...\n");
  1472     EC_MASTER_DBG(master, 1, "Master OP thread exiting...\n");
  1473     return 0;
  1473     return 0;
  1474 }
  1474 }
  1475 
  1475 
  1476 /*****************************************************************************/
  1476 /*****************************************************************************/
  1582             schedule_timeout(1);
  1582             schedule_timeout(1);
  1583         } else {
  1583         } else {
  1584             schedule();
  1584             schedule();
  1585         }
  1585         }
  1586     }
  1586     }
  1587     
  1587 
  1588     EC_MASTER_DBG(master, 1, "EoE thread exiting...\n");
  1588     EC_MASTER_DBG(master, 1, "EoE thread exiting...\n");
  1589     return 0;
  1589     return 0;
  1590 }
  1590 }
  1591 #endif
  1591 #endif
  1592 
  1592 
  1599         )
  1599         )
  1600 {
  1600 {
  1601     ec_slave_config_t *sc;
  1601     ec_slave_config_t *sc;
  1602 
  1602 
  1603     list_for_each_entry(sc, &master->configs, list) {
  1603     list_for_each_entry(sc, &master->configs, list) {
  1604         ec_slave_config_detach(sc); 
  1604         ec_slave_config_detach(sc);
  1605     }
  1605     }
  1606 }
  1606 }
  1607 
  1607 
  1608 /*****************************************************************************/
  1608 /*****************************************************************************/
  1609 
  1609 
  1890             break;
  1890             break;
  1891         }
  1891         }
  1892     }
  1892     }
  1893 
  1893 
  1894     master->dc_ref_clock = ref;
  1894     master->dc_ref_clock = ref;
  1895     
  1895 
  1896     // This call always succeeds, because the datagram has been pre-allocated.
  1896     // This call always succeeds, because the datagram has been pre-allocated.
  1897     ec_datagram_frmw(&master->sync_datagram,
  1897     ec_datagram_frmw(&master->sync_datagram,
  1898             ref ? ref->station_address : 0xffff, 0x0910, 4);
  1898             ref ? ref->station_address : 0xffff, 0x0910, 4);
  1899 }
  1899 }
  1900 
  1900 
  2108             EC_MASTER_ERR(master, "Failed to finish domain 0x%p!\n", domain);
  2108             EC_MASTER_ERR(master, "Failed to finish domain 0x%p!\n", domain);
  2109             return ret;
  2109             return ret;
  2110         }
  2110         }
  2111         domain_offset += domain->data_size;
  2111         domain_offset += domain->data_size;
  2112     }
  2112     }
  2113     
  2113 
  2114     up(&master->master_sem);
  2114     up(&master->master_sem);
  2115 
  2115 
  2116     // restart EoE process and master thread with new locking
  2116     // restart EoE process and master thread with new locking
  2117 
  2117 
  2118     ec_master_thread_stop(master);
  2118     ec_master_thread_stop(master);
  2127     master->injection_seq_rt = 0;
  2127     master->injection_seq_rt = 0;
  2128 
  2128 
  2129     master->send_cb = master->app_send_cb;
  2129     master->send_cb = master->app_send_cb;
  2130     master->receive_cb = master->app_receive_cb;
  2130     master->receive_cb = master->app_receive_cb;
  2131     master->cb_data = master->app_cb_data;
  2131     master->cb_data = master->app_cb_data;
  2132     
  2132 
  2133 #ifdef EC_EOE
  2133 #ifdef EC_EOE
  2134     if (eoe_was_running) {
  2134     if (eoe_was_running) {
  2135         ec_master_eoe_start(master);
  2135         ec_master_eoe_start(master);
  2136     }
  2136     }
  2137 #endif
  2137 #endif
  2173     ec_master_thread_stop(master);
  2173     ec_master_thread_stop(master);
  2174 #ifdef EC_EOE
  2174 #ifdef EC_EOE
  2175     eoe_was_running = master->eoe_thread != NULL;
  2175     eoe_was_running = master->eoe_thread != NULL;
  2176     ec_master_eoe_stop(master);
  2176     ec_master_eoe_stop(master);
  2177 #endif
  2177 #endif
  2178     
  2178 
  2179     master->send_cb = ec_master_internal_send_cb;
  2179     master->send_cb = ec_master_internal_send_cb;
  2180     master->receive_cb = ec_master_internal_receive_cb;
  2180     master->receive_cb = ec_master_internal_receive_cb;
  2181     master->cb_data = master;
  2181     master->cb_data = master;
  2182     
  2182 
  2183     ec_master_clear_config(master);
  2183     ec_master_clear_config(master);
  2184 
  2184 
  2185     for (slave = master->slaves;
  2185     for (slave = master->slaves;
  2186             slave < master->slaves + master->slave_count;
  2186             slave < master->slaves + master->slave_count;
  2187             slave++) {
  2187             slave++) {