Interface changes for version 1.2, see NEWS file.

This commit is contained in:
Florian Pose
2006-11-24 11:02:35 +00:00
parent ded638c296
commit c0f6188104
12 changed files with 83 additions and 155 deletions

View File

@@ -1 +1,5 @@
$Id$
Authors:
Florian Pose <fp@igh-essen.com>

21
NEWS
View File

@@ -4,6 +4,27 @@ $Id$
-------------------------------------------------------------------------------
Changes in version 1.2.0:
* Re-introduced ecrt_domain_queue() to allow datagram queuing apart
from datagram processing. The queuing of a domain's datagrams is not
done in ecrt_domain_process() any more!
* Removed ecrt_master_deactivate(). Its functionality was moved into
ecrt_master_release().
* Removed ecrt_master_prepare(). Its functionality was moved into
ecrt_master_activate().
* Removed ecdev_start() and ecdev_stop(). Their functionality was moved into
ecdev_register() and ecdev_unregister, respectively.
* The data_ptr parameter of ecrt_domain_register_pdo(),
ecrt_domain_register_pdo_list() and ecrt_domain_register_pdo_range() may
not be NULL any more.
* Removed ecrt_slave_pdo_size(). This function was deprecated long before.
* Added frame counter to master info file.
-------------------------------------------------------------------------------
Changes in version 1.1.1:
* State change FSM: Clearing of sync managers before PREOP.
* Added modules_install make target.
* Device modules for kernel 2.6.17.

View File

@@ -1,5 +1,7 @@
#!/bin/bash
# $Id$
set -x
mkdir -p autoconf
aclocal -I autoconf

View File

@@ -2907,20 +2907,12 @@ static int __init rtl8139_init_module (void)
printk(KERN_ERR "Failed to register EtherCAT device!\n");
goto out_pci;
}
printk(KERN_INFO "Starting EtherCAT device...\n");
if (ecdev_start(ec_device_master_index)) {
printk(KERN_ERR "Failed to start EtherCAT device!\n");
goto out_unregister;
}
} else {
printk(KERN_WARNING "No EtherCAT device registered!\n");
}
return 0;
out_unregister:
ecdev_unregister(ec_device_master_index, rtl_ec_dev);
out_pci:
pci_unregister_driver(&rtl8139_pci_driver);
out_return:
@@ -2937,8 +2929,6 @@ static void __exit rtl8139_cleanup_module (void)
printk(KERN_INFO "Cleaning up RTL8139-EtherCAT module...\n");
if (rtl_ec_net_dev) {
printk(KERN_INFO "Stopping device...\n");
ecdev_stop(ec_device_master_index);
printk(KERN_INFO "Unregistering device...\n");
ecdev_unregister(ec_device_master_index, rtl_ec_dev);
rtl_ec_dev = NULL;

View File

@@ -2905,20 +2905,12 @@ static int __init rtl8139_init_module (void)
printk(KERN_ERR "Failed to register EtherCAT device!\n");
goto out_pci;
}
printk(KERN_INFO "Starting EtherCAT device...\n");
if (ecdev_start(ec_device_master_index)) {
printk(KERN_ERR "Failed to start EtherCAT device!\n");
goto out_unregister;
}
} else {
printk(KERN_WARNING "No EtherCAT device registered!\n");
}
return 0;
out_unregister:
ecdev_unregister(ec_device_master_index, rtl_ec_dev);
out_pci:
pci_unregister_driver(&rtl8139_pci_driver);
out_return:
@@ -2935,8 +2927,6 @@ static void __exit rtl8139_cleanup_module (void)
printk(KERN_INFO "Cleaning up RTL8139-EtherCAT module...\n");
if (rtl_ec_net_dev) {
printk(KERN_INFO "Stopping device...\n");
ecdev_stop(ec_device_master_index);
printk(KERN_INFO "Unregistering device...\n");
ecdev_unregister(ec_device_master_index, rtl_ec_dev);
rtl_ec_dev = NULL;

View File

@@ -71,9 +71,6 @@ ec_device_t *ecdev_register(unsigned int master_index,
struct module *module);
void ecdev_unregister(unsigned int master_index, ec_device_t *device);
int ecdev_start(unsigned int master_index);
void ecdev_stop(unsigned int master_index);
/*****************************************************************************/
// Device methods

View File

@@ -110,8 +110,6 @@ ec_domain_t *ecrt_master_create_domain(ec_master_t *master);
int ecrt_master_activate(ec_master_t *master);
void ecrt_master_prepare(ec_master_t *master);
void ecrt_master_send(ec_master_t *master);
void ecrt_master_receive(ec_master_t *master);

View File

@@ -503,7 +503,6 @@ ssize_t ec_show_domain_attribute(struct kobject *kobj, /**< kobject */
/**
Registers a PDO in a domain.
- If \a data_ptr is NULL, the slave is only validated.
\return pointer to the slave on success, else NULL
\ingroup RealtimeInterface
*/
@@ -537,8 +536,6 @@ ec_slave_t *ecrt_domain_register_pdo(ec_domain_t *domain,
if (!(slave = ecrt_master_get_slave(master, address))) return NULL;
if (ec_slave_validate(slave, vendor_id, product_code)) return NULL;
if (!data_ptr) return slave;
list_for_each_entry(pdo, &slave->sii_pdos, list) {
list_for_each_entry(entry, &pdo->entries, list) {
if (entry->index != pdo_index
@@ -561,7 +558,7 @@ ec_slave_t *ecrt_domain_register_pdo(ec_domain_t *domain,
/**
Registeres a bunch of data fields.
Caution! The list has to be terminated with a NULL structure ({})!
\attention The list has to be terminated with a NULL structure ({})!
\return 0 in case of success, else < 0
\ingroup RealtimeInterface
*/
@@ -590,7 +587,6 @@ int ecrt_domain_register_pdo_list(ec_domain_t *domain,
/**
Registers a PDO range in a domain.
- If \a data_ptr is NULL, the slave is only validated.
\return pointer to the slave on success, else NULL
\ingroup RealtimeInterface
*/
@@ -624,8 +620,6 @@ ec_slave_t *ecrt_domain_register_pdo_range(ec_domain_t *domain,
if (!(slave = ecrt_master_get_slave(master, address))) return NULL;
if (ec_slave_validate(slave, vendor_id, product_code)) return NULL;
if (!data_ptr) return slave;
if (ec_domain_reg_pdo_range(domain, slave,
direction, offset, length, data_ptr)) {
return NULL;

View File

@@ -79,7 +79,6 @@ int ec_domain_init(ec_domain_t *, ec_master_t *, unsigned int);
void ec_domain_destroy(ec_domain_t *);
int ec_domain_alloc(ec_domain_t *, uint32_t);
void ec_domain_queue_datagrams(ec_domain_t *);
/*****************************************************************************/

View File

@@ -129,7 +129,6 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */
master->debug_level = 0;
master->stats.timeouts = 0;
master->stats.starved = 0;
master->stats.corrupted = 0;
master->stats.skipped = 0;
master->stats.unmatched = 0;
@@ -711,11 +710,6 @@ void ec_master_output_stats(ec_master_t *master /**< EtherCAT master */)
master->stats.timeouts == 1 ? "" : "s");
master->stats.timeouts = 0;
}
if (master->stats.starved) {
EC_WARN("%i datagram%s STARVED!\n", master->stats.starved,
master->stats.starved == 1 ? "" : "s");
master->stats.starved = 0;
}
if (master->stats.corrupted) {
EC_WARN("%i frame%s CORRUPTED!\n", master->stats.corrupted,
master->stats.corrupted == 1 ? "" : "s");
@@ -1272,6 +1266,36 @@ int ec_master_measure_bus_time(ec_master_t *master)
return -1;
}
/*****************************************************************************/
/**
Prepares synchronous IO.
Queues all domain datagrams and sends them. Then waits a certain time, so
that ecrt_master_receive() can be called securely.
*/
void ec_master_prepare(ec_master_t *master /**< EtherCAT master */)
{
ec_domain_t *domain;
cycles_t cycles_start, cycles_end, cycles_timeout;
// queue datagrams of all domains
list_for_each_entry(domain, &master->domains, list)
ecrt_domain_queue(domain);
ecrt_master_send(master);
cycles_start = get_cycles();
cycles_timeout = (cycles_t) EC_IO_TIMEOUT /* us */ * (cpu_khz / 1000);
// active waiting
while (1) {
udelay(100);
cycles_end = get_cycles();
if (cycles_end - cycles_start >= cycles_timeout) break;
}
}
/******************************************************************************
* Realtime interface
*****************************************************************************/
@@ -1354,25 +1378,13 @@ int ecrt_master_activate(ec_master_t *master /**< EtherCAT master */)
}
}
ec_master_prepare(master); // prepare asynchronous IO
return 0;
}
/*****************************************************************************/
/**
Resets all slaves to INIT state.
This method is deprecated and will disappear in the next version
of the realtime interface. The functionality is moved to
ecrt_master_release().
\ingroup RealtimeInterface
*/
void ecrt_master_deactivate(ec_master_t *master /**< EtherCAT master */)
{
}
/*****************************************************************************/
/**
Sends queued datagrams and waits for their reception.
*/
@@ -1445,64 +1457,20 @@ void ecrt_master_receive(ec_master_t *master /**< EtherCAT master */)
// dequeue all datagrams that timed out
list_for_each_entry_safe(datagram, next, &master->datagram_queue, queue) {
switch (datagram->state) {
case EC_DATAGRAM_QUEUED:
if (master->device->cycles_isr
- datagram->cycles_queued > cycles_timeout) {
list_del_init(&datagram->queue);
datagram->state = EC_DATAGRAM_TIMED_OUT;
master->stats.starved++;
ec_master_output_stats(master);
}
break;
case EC_DATAGRAM_SENT:
if (master->device->cycles_isr
- datagram->cycles_sent > cycles_timeout) {
list_del_init(&datagram->queue);
datagram->state = EC_DATAGRAM_TIMED_OUT;
master->stats.timeouts++;
ec_master_output_stats(master);
}
break;
default:
break;
if (datagram->state != EC_DATAGRAM_SENT) continue;
if (master->device->cycles_isr - datagram->cycles_sent
> cycles_timeout) {
list_del_init(&datagram->queue);
datagram->state = EC_DATAGRAM_TIMED_OUT;
master->stats.timeouts++;
ec_master_output_stats(master);
}
}
}
/*****************************************************************************/
/**
Prepares synchronous IO.
Queues all domain datagrams and sends them. Then waits a certain time, so
that ecrt_master_receive() can be called securely.
\ingroup RealtimeInterface
*/
void ecrt_master_prepare(ec_master_t *master /**< EtherCAT master */)
{
ec_domain_t *domain;
cycles_t cycles_start, cycles_end, cycles_timeout;
// queue datagrams of all domains
list_for_each_entry(domain, &master->domains, list)
ec_domain_queue_datagrams(domain);
ecrt_master_send(master);
cycles_start = get_cycles();
cycles_timeout = (cycles_t) EC_IO_TIMEOUT /* us */ * (cpu_khz / 1000);
// active waiting
while (1) {
udelay(100);
cycles_end = get_cycles();
if (cycles_end - cycles_start >= cycles_timeout) break;
}
}
/*****************************************************************************/
/**
Does all cyclic master work.
\ingroup RealtimeInterface
@@ -1651,8 +1619,6 @@ void ecrt_master_callbacks(ec_master_t *master, /**< EtherCAT master */
EXPORT_SYMBOL(ecrt_master_create_domain);
EXPORT_SYMBOL(ecrt_master_activate);
EXPORT_SYMBOL(ecrt_master_deactivate);
EXPORT_SYMBOL(ecrt_master_prepare);
EXPORT_SYMBOL(ecrt_master_send);
EXPORT_SYMBOL(ecrt_master_receive);
EXPORT_SYMBOL(ecrt_master_run);

View File

@@ -75,7 +75,6 @@ ec_master_mode_t;
typedef struct
{
unsigned int timeouts; /**< datagram timeouts */
unsigned int starved; /**< starved datagrams (not even sent) */
unsigned int corrupted; /**< corrupted frames */
unsigned int skipped; /**< skipped datagrams (the ones that were
requeued when not yet received) */

View File

@@ -311,9 +311,19 @@ ec_device_t *ecdev_register(unsigned int master_index, /**< master index */
goto out_free;
}
if (ec_device_open(master->device)) {
EC_ERR("Failed to open device!\n");
goto out_clear;
}
up(&master->device_sem);
ec_master_enter_idle_mode(master);
return master->device;
out_clear:
ec_device_clear(master->device);
out_free:
kfree(master->device);
master->device = NULL;
@@ -342,6 +352,11 @@ void ecdev_unregister(unsigned int master_index, /**< master index */
if (!(master = ec_find_master(master_index))) return;
ec_master_leave_idle_mode(master);
if (ec_device_close(master->device))
EC_WARN("Failed to close device!\n");
down(&master->device_sem);
if (!master->device || master->device != device) {
@@ -357,51 +372,6 @@ void ecdev_unregister(unsigned int master_index, /**< master index */
up(&master->device_sem);
}
/*****************************************************************************/
/**
Starts the master associated with the device.
This function has to be called by the network device driver to tell the
master that the device is ready to send and receive data. The master
will enter the idle mode then.
\ingroup DeviceInterface
*/
int ecdev_start(unsigned int master_index /**< master index */)
{
ec_master_t *master;
if (!(master = ec_find_master(master_index))) return -1;
if (ec_device_open(master->device)) {
EC_ERR("Failed to open device!\n");
return -1;
}
ec_master_enter_idle_mode(master);
return 0;
}
/*****************************************************************************/
/**
Stops the master associated with the device.
Tells the master to stop using the device for frame IO. Has to be called
before unregistering the device.
\ingroup DeviceInterface
*/
void ecdev_stop(unsigned int master_index /**< master index */)
{
ec_master_t *master;
if (!(master = ec_find_master(master_index))) return;
ec_master_leave_idle_mode(master);
if (ec_device_close(master->device))
EC_WARN("Failed to close device!\n");
}
/******************************************************************************
* Realtime interface
*****************************************************************************/
@@ -495,8 +465,6 @@ module_exit(ec_cleanup_module);
EXPORT_SYMBOL(ecdev_register);
EXPORT_SYMBOL(ecdev_unregister);
EXPORT_SYMBOL(ecdev_start);
EXPORT_SYMBOL(ecdev_stop);
EXPORT_SYMBOL(ecrt_request_master);
EXPORT_SYMBOL(ecrt_release_master);