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