master/master.c
changeset 495 88c597598bbc
parent 493 b17c95eac6b2
child 496 b2aee2241952
equal deleted inserted replaced
494:178b1b43a88c 495:88c597598bbc
   127 
   127 
   128     INIT_LIST_HEAD(&master->domains);
   128     INIT_LIST_HEAD(&master->domains);
   129     master->debug_level = 0;
   129     master->debug_level = 0;
   130 
   130 
   131     master->stats.timeouts = 0;
   131     master->stats.timeouts = 0;
   132     master->stats.starved = 0;
       
   133     master->stats.corrupted = 0;
   132     master->stats.corrupted = 0;
   134     master->stats.skipped = 0;
   133     master->stats.skipped = 0;
   135     master->stats.unmatched = 0;
   134     master->stats.unmatched = 0;
   136     master->stats.output_jiffies = 0;
   135     master->stats.output_jiffies = 0;
   137 
   136 
   708 
   707 
   709         if (master->stats.timeouts) {
   708         if (master->stats.timeouts) {
   710             EC_WARN("%i datagram%s TIMED OUT!\n", master->stats.timeouts,
   709             EC_WARN("%i datagram%s TIMED OUT!\n", master->stats.timeouts,
   711                     master->stats.timeouts == 1 ? "" : "s");
   710                     master->stats.timeouts == 1 ? "" : "s");
   712             master->stats.timeouts = 0;
   711             master->stats.timeouts = 0;
   713         }
       
   714         if (master->stats.starved) {
       
   715             EC_WARN("%i datagram%s STARVED!\n", master->stats.starved,
       
   716                     master->stats.starved == 1 ? "" : "s");
       
   717             master->stats.starved = 0;
       
   718         }
   712         }
   719         if (master->stats.corrupted) {
   713         if (master->stats.corrupted) {
   720             EC_WARN("%i frame%s CORRUPTED!\n", master->stats.corrupted,
   714             EC_WARN("%i frame%s CORRUPTED!\n", master->stats.corrupted,
   721                     master->stats.corrupted == 1 ? "" : "s");
   715                     master->stats.corrupted == 1 ? "" : "s");
   722             master->stats.corrupted = 0;
   716             master->stats.corrupted = 0;
  1270   error:
  1264   error:
  1271     ec_datagram_clear(&datagram);
  1265     ec_datagram_clear(&datagram);
  1272     return -1;
  1266     return -1;
  1273 }
  1267 }
  1274 
  1268 
       
  1269 /*****************************************************************************/
       
  1270 
       
  1271 /**
       
  1272    Prepares synchronous IO.
       
  1273    Queues all domain datagrams and sends them. Then waits a certain time, so
       
  1274    that ecrt_master_receive() can be called securely.
       
  1275 */
       
  1276 
       
  1277 void ec_master_prepare(ec_master_t *master /**< EtherCAT master */)
       
  1278 {
       
  1279     ec_domain_t *domain;
       
  1280     cycles_t cycles_start, cycles_end, cycles_timeout;
       
  1281 
       
  1282     // queue datagrams of all domains
       
  1283     list_for_each_entry(domain, &master->domains, list)
       
  1284         ecrt_domain_queue(domain);
       
  1285 
       
  1286     ecrt_master_send(master);
       
  1287 
       
  1288     cycles_start = get_cycles();
       
  1289     cycles_timeout = (cycles_t) EC_IO_TIMEOUT /* us */ * (cpu_khz / 1000);
       
  1290 
       
  1291     // active waiting
       
  1292     while (1) {
       
  1293         udelay(100);
       
  1294         cycles_end = get_cycles();
       
  1295         if (cycles_end - cycles_start >= cycles_timeout) break;
       
  1296     }
       
  1297 }
       
  1298 
  1275 /******************************************************************************
  1299 /******************************************************************************
  1276  *  Realtime interface
  1300  *  Realtime interface
  1277  *****************************************************************************/
  1301  *****************************************************************************/
  1278 
  1302 
  1279 /**
  1303 /**
  1352             EC_ERR("Failed to configure slave %i!\n", slave->ring_position);
  1376             EC_ERR("Failed to configure slave %i!\n", slave->ring_position);
  1353             return -1;
  1377             return -1;
  1354         }
  1378         }
  1355     }
  1379     }
  1356 
  1380 
       
  1381     ec_master_prepare(master); // prepare asynchronous IO
       
  1382 
  1357     return 0;
  1383     return 0;
  1358 }
       
  1359 
       
  1360 /*****************************************************************************/
       
  1361 
       
  1362 /**
       
  1363    Resets all slaves to INIT state.
       
  1364    This method is deprecated and will disappear in the next version
       
  1365    of the realtime interface. The functionality is moved to
       
  1366    ecrt_master_release().
       
  1367    \ingroup RealtimeInterface
       
  1368 */
       
  1369 
       
  1370 void ecrt_master_deactivate(ec_master_t *master /**< EtherCAT master */)
       
  1371 {
       
  1372 }
  1384 }
  1373 
  1385 
  1374 /*****************************************************************************/
  1386 /*****************************************************************************/
  1375 
  1387 
  1376 /**
  1388 /**
  1443 
  1455 
  1444     cycles_timeout = (cycles_t) EC_IO_TIMEOUT /* us */ * (cpu_khz / 1000);
  1456     cycles_timeout = (cycles_t) EC_IO_TIMEOUT /* us */ * (cpu_khz / 1000);
  1445 
  1457 
  1446     // dequeue all datagrams that timed out
  1458     // dequeue all datagrams that timed out
  1447     list_for_each_entry_safe(datagram, next, &master->datagram_queue, queue) {
  1459     list_for_each_entry_safe(datagram, next, &master->datagram_queue, queue) {
  1448         switch (datagram->state) {
  1460         if (datagram->state != EC_DATAGRAM_SENT) continue;
  1449             case EC_DATAGRAM_QUEUED:
  1461 
  1450                 if (master->device->cycles_isr
  1462         if (master->device->cycles_isr - datagram->cycles_sent
  1451                     - datagram->cycles_queued > cycles_timeout) {
  1463             > cycles_timeout) {
  1452                     list_del_init(&datagram->queue);
  1464             list_del_init(&datagram->queue);
  1453                     datagram->state = EC_DATAGRAM_TIMED_OUT;
  1465             datagram->state = EC_DATAGRAM_TIMED_OUT;
  1454                     master->stats.starved++;
  1466             master->stats.timeouts++;
  1455                     ec_master_output_stats(master);
  1467             ec_master_output_stats(master);
  1456                 }
  1468         }
  1457                 break;
       
  1458             case EC_DATAGRAM_SENT:
       
  1459                 if (master->device->cycles_isr
       
  1460                     - datagram->cycles_sent > cycles_timeout) {
       
  1461                     list_del_init(&datagram->queue);
       
  1462                     datagram->state = EC_DATAGRAM_TIMED_OUT;
       
  1463                     master->stats.timeouts++;
       
  1464                     ec_master_output_stats(master);
       
  1465                 }
       
  1466                 break;
       
  1467             default:
       
  1468                 break;
       
  1469         }
       
  1470     }
       
  1471 }
       
  1472 
       
  1473 /*****************************************************************************/
       
  1474 
       
  1475 /**
       
  1476    Prepares synchronous IO.
       
  1477    Queues all domain datagrams and sends them. Then waits a certain time, so
       
  1478    that ecrt_master_receive() can be called securely.
       
  1479    \ingroup RealtimeInterface
       
  1480 */
       
  1481 
       
  1482 void ecrt_master_prepare(ec_master_t *master /**< EtherCAT master */)
       
  1483 {
       
  1484     ec_domain_t *domain;
       
  1485     cycles_t cycles_start, cycles_end, cycles_timeout;
       
  1486 
       
  1487     // queue datagrams of all domains
       
  1488     list_for_each_entry(domain, &master->domains, list)
       
  1489         ec_domain_queue_datagrams(domain);
       
  1490 
       
  1491     ecrt_master_send(master);
       
  1492 
       
  1493     cycles_start = get_cycles();
       
  1494     cycles_timeout = (cycles_t) EC_IO_TIMEOUT /* us */ * (cpu_khz / 1000);
       
  1495 
       
  1496     // active waiting
       
  1497     while (1) {
       
  1498         udelay(100);
       
  1499         cycles_end = get_cycles();
       
  1500         if (cycles_end - cycles_start >= cycles_timeout) break;
       
  1501     }
  1469     }
  1502 }
  1470 }
  1503 
  1471 
  1504 /*****************************************************************************/
  1472 /*****************************************************************************/
  1505 
  1473 
  1649 
  1617 
  1650 /** \cond */
  1618 /** \cond */
  1651 
  1619 
  1652 EXPORT_SYMBOL(ecrt_master_create_domain);
  1620 EXPORT_SYMBOL(ecrt_master_create_domain);
  1653 EXPORT_SYMBOL(ecrt_master_activate);
  1621 EXPORT_SYMBOL(ecrt_master_activate);
  1654 EXPORT_SYMBOL(ecrt_master_deactivate);
       
  1655 EXPORT_SYMBOL(ecrt_master_prepare);
       
  1656 EXPORT_SYMBOL(ecrt_master_send);
  1622 EXPORT_SYMBOL(ecrt_master_send);
  1657 EXPORT_SYMBOL(ecrt_master_receive);
  1623 EXPORT_SYMBOL(ecrt_master_receive);
  1658 EXPORT_SYMBOL(ecrt_master_run);
  1624 EXPORT_SYMBOL(ecrt_master_run);
  1659 EXPORT_SYMBOL(ecrt_master_callbacks);
  1625 EXPORT_SYMBOL(ecrt_master_callbacks);
  1660 EXPORT_SYMBOL(ecrt_master_get_slave);
  1626 EXPORT_SYMBOL(ecrt_master_get_slave);