master/master.c
changeset 1980 a89e2bedf004
parent 1978 d9b6e641eaeb
parent 1914 da7adbde2625
child 1981 c14b6bb14fdf
equal deleted inserted replaced
1979:2c22f3bea8ba 1980:a89e2bedf004
    22  *  ---
    22  *  ---
    23  *
    23  *
    24  *  The license mentioned above concerns the source code only. Using the
    24  *  The license mentioned above concerns the source code only. Using the
    25  *  EtherCAT technology and brand is only permitted in compliance with the
    25  *  EtherCAT technology and brand is only permitted in compliance with the
    26  *  industrial property and similar rights of Beckhoff Automation GmbH.
    26  *  industrial property and similar rights of Beckhoff Automation GmbH.
       
    27  *
       
    28  *  vim: expandtab
    27  *
    29  *
    28  *****************************************************************************/
    30  *****************************************************************************/
    29 
    31 
    30 /**
    32 /**
    31    \file
    33    \file
    61 #ifdef EC_HAVE_CYCLES
    63 #ifdef EC_HAVE_CYCLES
    62 
    64 
    63 /** Frame timeout in cycles.
    65 /** Frame timeout in cycles.
    64  */
    66  */
    65 static cycles_t timeout_cycles;
    67 static cycles_t timeout_cycles;
    66 static cycles_t sdo_injection_timeout_cycles;
    68 
       
    69 /** Timeout for external datagram injection [cycles].
       
    70  */
       
    71 static cycles_t ext_injection_timeout_cycles;
       
    72 
    67 #else
    73 #else
    68 
    74 
    69 /** Frame timeout in jiffies.
    75 /** Frame timeout in jiffies.
    70  */
    76  */
    71 static unsigned long timeout_jiffies;
    77 static unsigned long timeout_jiffies;
    72 static unsigned long sdo_injection_timeout_jiffies;
    78 
       
    79 /** Timeout for external datagram injection [jiffies].
       
    80  */
       
    81 static unsigned long ext_injection_timeout_jiffies;
    73 
    82 
    74 #endif
    83 #endif
    75 
    84 
    76 /*****************************************************************************/
    85 /*****************************************************************************/
    77 
    86 
    90 */
    99 */
    91 void ec_master_init_static(void)
   100 void ec_master_init_static(void)
    92 {
   101 {
    93 #ifdef EC_HAVE_CYCLES
   102 #ifdef EC_HAVE_CYCLES
    94     timeout_cycles = (cycles_t) EC_IO_TIMEOUT /* us */ * (cpu_khz / 1000);
   103     timeout_cycles = (cycles_t) EC_IO_TIMEOUT /* us */ * (cpu_khz / 1000);
    95     sdo_injection_timeout_cycles = (cycles_t) EC_SDO_INJECTION_TIMEOUT /* us */ * (cpu_khz / 1000);
   104     ext_injection_timeout_cycles = (cycles_t) EC_SDO_INJECTION_TIMEOUT /* us */ * (cpu_khz / 1000);
    96 #else
   105 #else
    97     // one jiffy may always elapse between time measurement
   106     // one jiffy may always elapse between time measurement
    98     timeout_jiffies = max(EC_IO_TIMEOUT * HZ / 1000000, 1);
   107     timeout_jiffies = max(EC_IO_TIMEOUT * HZ / 1000000, 1);
    99     sdo_injection_timeout_jiffies = max(EC_SDO_INJECTION_TIMEOUT * HZ / 1000000, 1);
   108     ext_injection_timeout_jiffies = max(EC_SDO_INJECTION_TIMEOUT * HZ / 1000000, 1);
   100 #endif
   109 #endif
   101 }
   110 }
   102 
   111 
   103 /*****************************************************************************/
   112 /*****************************************************************************/
   104 
   113 
   415             // get first request
   424             // get first request
   416             request = list_entry(slave->slave_sdo_requests.next,
   425             request = list_entry(slave->slave_sdo_requests.next,
   417                     ec_master_sdo_request_t, list);
   426                     ec_master_sdo_request_t, list);
   418             list_del_init(&request->list); // dequeue
   427             list_del_init(&request->list); // dequeue
   419             EC_INFO("Discarding SDO request,"
   428             EC_INFO("Discarding SDO request,"
   420 					" slave %u does not exist anymore.\n",
   429                     " slave %u does not exist anymore.\n",
   421                     slave->ring_position);
   430                     slave->ring_position);
   422             request->req.state = EC_INT_REQUEST_FAILURE;
   431             request->req.state = EC_INT_REQUEST_FAILURE;
   423             wake_up(&slave->sdo_queue);
   432             wake_up(&slave->sdo_queue);
   424         }
   433         }
   425         // FoE requests
   434         // FoE requests
   430             // get first request
   439             // get first request
   431             request = list_entry(slave->foe_requests.next,
   440             request = list_entry(slave->foe_requests.next,
   432                     ec_master_foe_request_t, list);
   441                     ec_master_foe_request_t, list);
   433             list_del_init(&request->list); // dequeue
   442             list_del_init(&request->list); // dequeue
   434             EC_INFO("Discarding FoE request,"
   443             EC_INFO("Discarding FoE request,"
   435 					" slave %u does not exist anymore.\n",
   444                     " slave %u does not exist anymore.\n",
   436                     slave->ring_position);
   445                     slave->ring_position);
   437             request->req.state = EC_INT_REQUEST_FAILURE;
   446             request->req.state = EC_INT_REQUEST_FAILURE;
   438             wake_up(&slave->foe_queue);
   447             wake_up(&slave->foe_queue);
   439         }
   448         }
   440         // SoE requests
   449         // SoE requests
   445             // get first request
   454             // get first request
   446             request = list_entry(slave->soe_requests.next,
   455             request = list_entry(slave->soe_requests.next,
   447                     ec_master_soe_request_t, list);
   456                     ec_master_soe_request_t, list);
   448             list_del_init(&request->list); // dequeue
   457             list_del_init(&request->list); // dequeue
   449             EC_INFO("Discarding SoE request,"
   458             EC_INFO("Discarding SoE request,"
   450 					" slave %u does not exist anymore.\n",
   459                     " slave %u does not exist anymore.\n",
   451                     slave->ring_position);
   460                     slave->ring_position);
   452             request->req.state = EC_INT_REQUEST_FAILURE;
   461             request->req.state = EC_INT_REQUEST_FAILURE;
   453             wake_up(&slave->soe_queue);
   462             wake_up(&slave->soe_queue);
   454         }
   463         }
   455         ec_slave_clear(slave);
   464         ec_slave_clear(slave);
   749             } else {
   758             } else {
   750 #ifdef EC_HAVE_CYCLES
   759 #ifdef EC_HAVE_CYCLES
   751                 cycles_t cycles_now = get_cycles();
   760                 cycles_t cycles_now = get_cycles();
   752 
   761 
   753                 if (cycles_now - datagram->cycles_sent
   762                 if (cycles_now - datagram->cycles_sent
   754                         > sdo_injection_timeout_cycles)
   763                         > ext_injection_timeout_cycles)
   755 #else
   764 #else
   756                 if (jiffies - datagram->jiffies_sent
   765                 if (jiffies - datagram->jiffies_sent
   757                         > sdo_injection_timeout_jiffies)
   766                         > ext_injection_timeout_jiffies)
   758 #endif
   767 #endif
   759                 {
   768                 {
   760                     unsigned int time_us;
   769                     unsigned int time_us;
   761 
   770 
   762                     list_del_init(&datagram->queue);
   771                     list_del_init(&datagram->queue);
  1515 #define EC_FIND_SLAVE \
  1524 #define EC_FIND_SLAVE \
  1516     do { \
  1525     do { \
  1517         if (alias) { \
  1526         if (alias) { \
  1518             for (; slave < master->slaves + master->slave_count; \
  1527             for (; slave < master->slaves + master->slave_count; \
  1519                     slave++) { \
  1528                     slave++) { \
  1520                 if (slave->sii.alias == alias) \
  1529                 if (slave->effective_alias == alias) \
  1521                 break; \
  1530                 break; \
  1522             } \
  1531             } \
  1523             if (slave == master->slaves + master->slave_count) \
  1532             if (slave == master->slaves + master->slave_count) \
  1524             return NULL; \
  1533             return NULL; \
  1525         } \
  1534         } \
  1930 int ecrt_master_activate(ec_master_t *master)
  1939 int ecrt_master_activate(ec_master_t *master)
  1931 {
  1940 {
  1932     uint32_t domain_offset;
  1941     uint32_t domain_offset;
  1933     ec_domain_t *domain;
  1942     ec_domain_t *domain;
  1934     int ret;
  1943     int ret;
       
  1944 #ifdef EC_EOE
       
  1945     int eoe_was_running;
       
  1946 #endif
  1935 
  1947 
  1936     if (master->debug_level)
  1948     if (master->debug_level)
  1937         EC_DBG("ecrt_master_activate(master = 0x%p)\n", master);
  1949         EC_DBG("ecrt_master_activate(master = 0x%p)\n", master);
  1938 
  1950 
  1939     if (master->active) {
  1951     if (master->active) {
  1961     }
  1973     }
  1962 
  1974 
  1963     up(&master->master_sem);
  1975     up(&master->master_sem);
  1964 
  1976 
  1965     // restart EoE process and master thread with new locking
  1977     // restart EoE process and master thread with new locking
       
  1978 
       
  1979     ec_master_thread_stop(master);
  1966 #ifdef EC_EOE
  1980 #ifdef EC_EOE
       
  1981     eoe_was_running = master->eoe_thread != NULL;
  1967     ec_master_eoe_stop(master);
  1982     ec_master_eoe_stop(master);
  1968 #endif
  1983 #endif
  1969     ec_master_thread_stop(master);
       
  1970 
  1984 
  1971     if (master->debug_level)
  1985     if (master->debug_level)
  1972         EC_DBG("FSM datagram is %p.\n", &master->fsm_datagram);
  1986         EC_DBG("FSM datagram is %p.\n", &master->fsm_datagram);
  1973 
  1987 
  1974     master->injection_seq_fsm = 0;
  1988     master->injection_seq_fsm = 0;
  1976 
  1990 
  1977     master->send_cb = master->app_send_cb;
  1991     master->send_cb = master->app_send_cb;
  1978     master->receive_cb = master->app_receive_cb;
  1992     master->receive_cb = master->app_receive_cb;
  1979     master->cb_data = master->app_cb_data;
  1993     master->cb_data = master->app_cb_data;
  1980     
  1994     
       
  1995 #ifdef EC_EOE
       
  1996     if (eoe_was_running) {
       
  1997         ec_master_eoe_start(master);
       
  1998     }
       
  1999 #endif
  1981     ret = ec_master_thread_start(master, ec_master_operation_thread,
  2000     ret = ec_master_thread_start(master, ec_master_operation_thread,
  1982                 "EtherCAT-OP");
  2001                 "EtherCAT-OP");
  1983     if (ret < 0) {
  2002     if (ret < 0) {
  1984         EC_ERR("Failed to start master thread!\n");
  2003         EC_ERR("Failed to start master thread!\n");
  1985         return ret;
  2004         return ret;
  1986     }
  2005     }
  1987 #ifdef EC_EOE
       
  1988     ec_master_eoe_start(master);
       
  1989 #endif
       
  1990 
  2006 
  1991     master->allow_config = 1; // request the current configuration
  2007     master->allow_config = 1; // request the current configuration
  1992     master->allow_scan = 1; // allow re-scanning on topology change
  2008     master->allow_scan = 1; // allow re-scanning on topology change
  1993     master->active = 1;
  2009     master->active = 1;
  1994     return 0;
  2010     return 0;
  1999 void ecrt_master_deactivate(ec_master_t *master)
  2015 void ecrt_master_deactivate(ec_master_t *master)
  2000 {
  2016 {
  2001     ec_slave_t *slave;
  2017     ec_slave_t *slave;
  2002 #ifdef EC_EOE
  2018 #ifdef EC_EOE
  2003     ec_eoe_t *eoe;
  2019     ec_eoe_t *eoe;
       
  2020     int eoe_was_running;
  2004 #endif
  2021 #endif
  2005 
  2022 
  2006     if (master->debug_level)
  2023     if (master->debug_level)
  2007         EC_DBG("ecrt_master_deactivate(master = 0x%x)\n", (u32) master);
  2024         EC_DBG("ecrt_master_deactivate(master = 0x%x)\n", (u32) master);
  2008 
  2025 
  2009     if (!master->active) {
  2026     if (!master->active) {
  2010         EC_WARN("%s: Master not active.\n", __func__);
  2027         EC_WARN("%s: Master not active.\n", __func__);
  2011         return;
  2028         return;
  2012     }
  2029     }
  2013 
  2030 
       
  2031     ec_master_thread_stop(master);
  2014 #ifdef EC_EOE
  2032 #ifdef EC_EOE
       
  2033     eoe_was_running = master->eoe_thread != NULL;
  2015     ec_master_eoe_stop(master);
  2034     ec_master_eoe_stop(master);
  2016 #endif
  2035 #endif
  2017     ec_master_thread_stop(master);
       
  2018     
  2036     
  2019     master->send_cb = ec_master_internal_send_cb;
  2037     master->send_cb = ec_master_internal_send_cb;
  2020     master->receive_cb = ec_master_internal_receive_cb;
  2038     master->receive_cb = ec_master_internal_receive_cb;
  2021     master->cb_data = master;
  2039     master->cb_data = master;
  2022     
  2040     
  2048 
  2066 
  2049     master->app_time = 0ULL;
  2067     master->app_time = 0ULL;
  2050     master->app_start_time = 0ULL;
  2068     master->app_start_time = 0ULL;
  2051     master->has_start_time = 0;
  2069     master->has_start_time = 0;
  2052 
  2070 
       
  2071 #ifdef EC_EOE
       
  2072     if (eoe_was_running) {
       
  2073         ec_master_eoe_start(master);
       
  2074     }
       
  2075 #endif
  2053     if (ec_master_thread_start(master, ec_master_idle_thread,
  2076     if (ec_master_thread_start(master, ec_master_idle_thread,
  2054                 "EtherCAT-IDLE"))
  2077                 "EtherCAT-IDLE"))
  2055         EC_WARN("Failed to restart master thread!\n");
  2078         EC_WARN("Failed to restart master thread!\n");
  2056 #ifdef EC_EOE
       
  2057     ec_master_eoe_start(master);
       
  2058 #endif
       
  2059 
  2079 
  2060     master->allow_scan = 1;
  2080     master->allow_scan = 1;
  2061     master->allow_config = 1;
  2081     master->allow_config = 1;
  2062     master->active = 0;
  2082     master->active = 0;
  2063 }
  2083 }
  2251     slave_info->position = slave->ring_position;
  2271     slave_info->position = slave->ring_position;
  2252     slave_info->vendor_id = slave->sii.vendor_id;
  2272     slave_info->vendor_id = slave->sii.vendor_id;
  2253     slave_info->product_code = slave->sii.product_code;
  2273     slave_info->product_code = slave->sii.product_code;
  2254     slave_info->revision_number = slave->sii.revision_number;
  2274     slave_info->revision_number = slave->sii.revision_number;
  2255     slave_info->serial_number = slave->sii.serial_number;
  2275     slave_info->serial_number = slave->sii.serial_number;
  2256     slave_info->alias = slave->sii.alias;
  2276     slave_info->alias = slave->effective_alias;
  2257     slave_info->current_on_ebus = slave->sii.current_on_ebus;
  2277     slave_info->current_on_ebus = slave->sii.current_on_ebus;
  2258     slave_info->al_state = slave->current_state;
  2278     slave_info->al_state = slave->current_state;
  2259     slave_info->error_flag = slave->error_flag;
  2279     slave_info->error_flag = slave->error_flag;
  2260     slave_info->sync_count = slave->sii.sync_count;
  2280     slave_info->sync_count = slave->sii.sync_count;
  2261     slave_info->sdo_count = ec_slave_sdo_count(slave);
  2281     slave_info->sdo_count = ec_slave_sdo_count(slave);