Dynamic creation of EoE handlers.
This commit is contained in:
parent
e17ebc9764
commit
9466d51185
19
NEWS
19
NEWS
|
|
@ -8,33 +8,34 @@ Changes in version 1.3.0:
|
|||
|
||||
* Added testing version of Intel PRO/100 ethernet driver (e100).
|
||||
* Added testing version of NVIDIA nForce ethernet driver (forcedeth).
|
||||
* Removed "ec_eoeif_count" master module parameter.
|
||||
* Removed "ec_eoeif_count" master module parameter. EoE handlers are created
|
||||
dynamically instead.
|
||||
* Added "main" and "backup" parameters to master module to hand over the
|
||||
MAC addresses of the devices to wait for. This made the ec_device_index
|
||||
parameter of the ethercat drivers obsolete.
|
||||
parameter of the ethernet drivers obsolete.
|
||||
* Changed format of sysconfig file and accordingly adjusted functionality
|
||||
of the init script to handle MAC address lists.
|
||||
of the init script to handle the above MAC address lists.
|
||||
* Realtime interface changes:
|
||||
- ecrt_master_run() became obsolete, because the master state machine is now
|
||||
run in process context.
|
||||
- Parameter changes in PDO registration functions ecrt_domain_register_pdo()
|
||||
and ecrt_register_pdo_range(): Replaced slave_address, vendor ID and
|
||||
product code arguments with a slave pointer, which has to be optained with
|
||||
product code arguments with a slave pointer, which has to be obtained with
|
||||
a prior call to ecrt_master_get_slave().
|
||||
- ecrt_master_get_slave() got additional parameters to check for vendor ID
|
||||
and product code.
|
||||
- Removed addressing scheme "X:Y" for ecrt_master_get_slave().
|
||||
- Added ecrt_master_get_status() to get information about the bus.
|
||||
- Added functions to set up an alternative PDO mapping, i. e.
|
||||
- Added ecrt_master_get_status() to get status information about the bus.
|
||||
- Added functions to set up an alternative PDO mapping for a slave, i. e.
|
||||
ec_slave_pdo_mapping_clear(), ec_slave_pdo_mapping_add() and
|
||||
ec_slave_pdo_mapping().
|
||||
* Device interface changes:
|
||||
- Replaced ecdev_register() and ecdev_unregister() with ecdev_offer() and
|
||||
ecdev_withdraw(), respectively. The device modules now offer all their
|
||||
devices to the master, which decides, which ones to register.
|
||||
devices to the master. The master then decides, which ones to register.
|
||||
* All EEPROM write operations from user space are now blocking until
|
||||
writing has finished and return appropriate error codes.
|
||||
* Implemented setting of secondary slave address (alias) via sysfs.
|
||||
writing has finished. Appropriate error codes are returned.
|
||||
* Implemented setting of the "Secondary slave address" (alias) via sysfs.
|
||||
* Implemented SDO reading in operation mode via sysfs.
|
||||
* Removed annoying eeprom_write_enable file. EEPROM writing always enabled.
|
||||
* Slave configuration is now done exclusively from the master thread. Removed
|
||||
|
|
|
|||
4
TODO
4
TODO
|
|
@ -6,9 +6,6 @@ $Id$
|
|||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
* Release 1.3:
|
||||
- Dynamic creation of EoE handlers.
|
||||
|
||||
* Future features:
|
||||
- Interface/buffers for asynchronous domain IO.
|
||||
- Distributed clocks.
|
||||
|
|
@ -31,6 +28,7 @@ $Id$
|
|||
- Interrupt master state machines state scan for other jobs.
|
||||
- Master state machine, slave configuration: Do not check every slave on
|
||||
a cycle.
|
||||
- Fix problem when lock ist not required for EoE sending.
|
||||
|
||||
* Less important issues:
|
||||
- Implement all EtherCAT datagram types.
|
||||
|
|
|
|||
|
|
@ -83,16 +83,21 @@ struct net_device_stats *ec_eoedev_stats(struct net_device *);
|
|||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
EoE constructor.
|
||||
Initializes the EoE handler, creates a net_device and registeres it.
|
||||
*/
|
||||
* EoE constructor.
|
||||
* Initializes the EoE handler, creates a net_device and registers it.
|
||||
*/
|
||||
|
||||
int ec_eoe_init(ec_eoe_t *eoe /**< EoE handler */)
|
||||
int ec_eoe_init(
|
||||
ec_eoe_t *eoe, /**< EoE handler */
|
||||
ec_slave_t *slave /**< EtherCAT slave */
|
||||
)
|
||||
{
|
||||
ec_eoe_t **priv;
|
||||
int result, i;
|
||||
char name[20];
|
||||
|
||||
eoe->slave = slave;
|
||||
|
||||
eoe->slave = NULL;
|
||||
ec_datagram_init(&eoe->datagram);
|
||||
eoe->state = ec_eoe_state_rx_start;
|
||||
eoe->opened = 0;
|
||||
|
|
@ -112,8 +117,9 @@ int ec_eoe_init(ec_eoe_t *eoe /**< EoE handler */)
|
|||
eoe->tx_rate = 0;
|
||||
eoe->rate_jiffies = 0;
|
||||
|
||||
if (!(eoe->dev =
|
||||
alloc_netdev(sizeof(ec_eoe_t *), "eoe%d", ether_setup))) {
|
||||
sprintf(name, "eoe%u-%u", slave->master->index, slave->ring_position);
|
||||
|
||||
if (!(eoe->dev = alloc_netdev(sizeof(ec_eoe_t *), name, ether_setup))) {
|
||||
EC_ERR("Unable to allocate net_device for EoE handler!\n");
|
||||
goto out_return;
|
||||
}
|
||||
|
|
@ -147,7 +153,6 @@ int ec_eoe_init(ec_eoe_t *eoe /**< EoE handler */)
|
|||
|
||||
// make the last address octet unique
|
||||
eoe->dev->dev_addr[ETH_ALEN - 1] = (uint8_t) eoe->dev->ifindex;
|
||||
|
||||
return 0;
|
||||
|
||||
out_free:
|
||||
|
|
@ -305,9 +310,9 @@ void ec_eoe_run(ec_eoe_t *eoe /**< EoE handler */)
|
|||
\return 1 if the device is "up", 0 if it is "down"
|
||||
*/
|
||||
|
||||
int ec_eoe_active(const ec_eoe_t *eoe /**< EoE handler */)
|
||||
int ec_eoe_is_open(const ec_eoe_t *eoe /**< EoE handler */)
|
||||
{
|
||||
return eoe->slave && eoe->opened;
|
||||
return eoe->opened;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
|
|
|
|||
|
|
@ -99,9 +99,9 @@ struct ec_eoe
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
int ec_eoe_init(ec_eoe_t *);
|
||||
int ec_eoe_init(ec_eoe_t *, ec_slave_t *);
|
||||
void ec_eoe_clear(ec_eoe_t *);
|
||||
void ec_eoe_run(ec_eoe_t *);
|
||||
int ec_eoe_active(const ec_eoe_t *);
|
||||
int ec_eoe_is_open(const ec_eoe_t *);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -41,6 +41,7 @@
|
|||
#include "globals.h"
|
||||
#include "master.h"
|
||||
#include "mailbox.h"
|
||||
#include "ethernet.h"
|
||||
#include "fsm_master.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -238,6 +239,7 @@ void ec_fsm_master_state_broadcast(ec_fsm_master_t *fsm /**< master state machin
|
|||
fsm->scan_jiffies = jiffies;
|
||||
|
||||
ec_master_eoe_stop(master);
|
||||
ec_master_clear_eoe_handlers(master);
|
||||
ec_master_destroy_slaves(master);
|
||||
|
||||
master->slave_count = datagram->working_counter;
|
||||
|
|
@ -483,9 +485,6 @@ void ec_fsm_master_action_process_states(ec_fsm_master_t *fsm
|
|||
return;
|
||||
}
|
||||
|
||||
// Check, if EoE processing has to be started
|
||||
ec_master_eoe_start(master);
|
||||
|
||||
// Check for a pending SDO request
|
||||
if (ec_fsm_master_action_process_sdo(fsm))
|
||||
return;
|
||||
|
|
@ -809,6 +808,23 @@ void ec_fsm_master_state_scan_slaves(
|
|||
if (ec_fsm_slave_exec(&fsm->fsm_slave)) // execute slave state machine
|
||||
return;
|
||||
|
||||
if (slave->sii_mailbox_protocols & EC_MBOX_EOE) {
|
||||
// create EoE handler for this slave
|
||||
ec_eoe_t *eoe;
|
||||
if (!(eoe = kmalloc(sizeof(ec_eoe_t), GFP_KERNEL))) {
|
||||
EC_ERR("Failed to allocate EoE handler memory for slave %u!\n",
|
||||
slave->ring_position);
|
||||
}
|
||||
else if (ec_eoe_init(eoe, slave)) {
|
||||
EC_ERR("Failed to init EoE handler for slave %u!\n",
|
||||
slave->ring_position);
|
||||
kfree(eoe);
|
||||
}
|
||||
else {
|
||||
list_add_tail(&eoe->list, &master->eoe_handlers);
|
||||
}
|
||||
}
|
||||
|
||||
// another slave to fetch?
|
||||
if (slave->list.next != &master->slaves) {
|
||||
fsm->slave = list_entry(slave->list.next, ec_slave_t, list);
|
||||
|
|
@ -819,6 +835,10 @@ void ec_fsm_master_state_scan_slaves(
|
|||
|
||||
EC_INFO("Bus scanning completed in %u ms.\n",
|
||||
(u32) (jiffies - fsm->scan_jiffies) * 1000 / HZ);
|
||||
|
||||
// check if EoE processing has to be started
|
||||
ec_master_eoe_start(master);
|
||||
|
||||
master->scan_state = EC_REQUEST_COMPLETE;
|
||||
wake_up_interruptible(&master->scan_queue);
|
||||
|
||||
|
|
|
|||
156
master/master.c
156
master/master.c
|
|
@ -154,7 +154,6 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */
|
|||
master->eoe_timer.function = ec_master_eoe_run;
|
||||
master->eoe_timer.data = (unsigned long) master;
|
||||
master->eoe_running = 0;
|
||||
master->eoe_checked = 0;
|
||||
INIT_LIST_HEAD(&master->eoe_handlers);
|
||||
|
||||
master->internal_lock = SPIN_LOCK_UNLOCKED;
|
||||
|
|
@ -229,40 +228,36 @@ void ec_master_clear(
|
|||
ec_master_t *master /**< EtherCAT master */
|
||||
)
|
||||
{
|
||||
ec_eoe_t *eoe, *next_eoe;
|
||||
ec_datagram_t *datagram, *next_datagram;
|
||||
|
||||
ec_master_clear_eoe_handlers(master);
|
||||
ec_master_destroy_slaves(master);
|
||||
ec_master_destroy_domains(master);
|
||||
|
||||
// list of EEPROM requests is empty,
|
||||
// otherwise master could not be cleared.
|
||||
|
||||
// dequeue all datagrams
|
||||
list_for_each_entry_safe(datagram, next_datagram,
|
||||
&master->datagram_queue, queue) {
|
||||
datagram->state = EC_DATAGRAM_ERROR;
|
||||
list_del_init(&datagram->queue);
|
||||
}
|
||||
|
||||
ec_fsm_master_clear(&master->fsm);
|
||||
ec_datagram_clear(&master->fsm_datagram);
|
||||
|
||||
// clear EoE objects
|
||||
list_for_each_entry_safe(eoe, next_eoe, &master->eoe_handlers, list) {
|
||||
list_del(&eoe->list);
|
||||
ec_eoe_clear(eoe);
|
||||
kfree(eoe);
|
||||
}
|
||||
|
||||
ec_device_clear(&master->backup_device);
|
||||
ec_device_clear(&master->main_device);
|
||||
|
||||
// destroy self
|
||||
kobject_del(&master->kobj);
|
||||
kobject_put(&master->kobj);
|
||||
}
|
||||
|
||||
EC_INFO("Master %u freed.\n", master->index);
|
||||
/*****************************************************************************/
|
||||
|
||||
/**
|
||||
* Clear and free all EoE handlers.
|
||||
*/
|
||||
|
||||
void ec_master_clear_eoe_handlers(
|
||||
ec_master_t *master /**< EtherCAT master */
|
||||
)
|
||||
{
|
||||
ec_eoe_t *eoe, *next;
|
||||
|
||||
list_for_each_entry_safe(eoe, next, &master->eoe_handlers, list) {
|
||||
list_del(&eoe->list);
|
||||
ec_eoe_clear(eoe);
|
||||
kfree(eoe);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -413,6 +408,7 @@ void ec_master_leave_idle_mode(ec_master_t *master /**< EtherCAT master */)
|
|||
int ec_master_enter_operation_mode(ec_master_t *master /**< EtherCAT master */)
|
||||
{
|
||||
ec_slave_t *slave;
|
||||
ec_eoe_t *eoe;
|
||||
|
||||
down(&master->config_sem);
|
||||
master->allow_config = 0; // temporarily disable slave configuration
|
||||
|
|
@ -446,12 +442,20 @@ int ec_master_enter_operation_mode(ec_master_t *master /**< EtherCAT master */)
|
|||
list_for_each_entry(slave, &master->slaves, list) {
|
||||
ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP);
|
||||
}
|
||||
// ... but set EoE slaves to OP
|
||||
list_for_each_entry(eoe, &master->eoe_handlers, list) {
|
||||
if (ec_eoe_is_open(eoe))
|
||||
ec_slave_request_state(eoe->slave, EC_SLAVE_STATE_OP);
|
||||
}
|
||||
|
||||
if (master->debug_level)
|
||||
EC_DBG("Switching to operation mode.\n");
|
||||
|
||||
master->mode = EC_MASTER_MODE_OPERATION;
|
||||
master->pdo_slaves_offline = 0; // assume all PDO slaves online
|
||||
master->ext_request_cb = NULL;
|
||||
master->ext_release_cb = NULL;
|
||||
master->ext_cb_data = NULL;
|
||||
return 0;
|
||||
|
||||
out_allow:
|
||||
|
|
@ -470,6 +474,7 @@ void ec_master_leave_operation_mode(ec_master_t *master
|
|||
/**< EtherCAT master */)
|
||||
{
|
||||
ec_slave_t *slave;
|
||||
ec_eoe_t *eoe;
|
||||
|
||||
master->mode = EC_MASTER_MODE_IDLE;
|
||||
|
||||
|
|
@ -485,15 +490,20 @@ void ec_master_leave_operation_mode(ec_master_t *master
|
|||
ec_slave_reset(slave);
|
||||
ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP);
|
||||
}
|
||||
// ... but leave EoE slaves in OP
|
||||
list_for_each_entry(eoe, &master->eoe_handlers, list) {
|
||||
if (ec_eoe_is_open(eoe))
|
||||
ec_slave_request_state(eoe->slave, EC_SLAVE_STATE_OP);
|
||||
}
|
||||
|
||||
ec_master_destroy_domains(master);
|
||||
|
||||
if (ec_master_thread_start(master, ec_master_idle_thread))
|
||||
EC_WARN("Failed to restart master thread!\n");
|
||||
ec_master_eoe_start(master);
|
||||
|
||||
master->allow_scan = 1;
|
||||
master->allow_config = 1;
|
||||
|
||||
if (ec_master_thread_start(master, ec_master_idle_thread)) {
|
||||
EC_WARN("Failed to restart master thread!\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -1059,48 +1069,16 @@ ssize_t ec_store_master_attribute(struct kobject *kobj, /**< slave's kobject */
|
|||
|
||||
void ec_master_eoe_start(ec_master_t *master /**< EtherCAT master */)
|
||||
{
|
||||
ec_eoe_t *eoe;
|
||||
ec_slave_t *slave;
|
||||
unsigned int coupled, found;
|
||||
|
||||
if (master->eoe_running || master->eoe_checked) return;
|
||||
|
||||
master->eoe_checked = 1;
|
||||
|
||||
// decouple all EoE handlers
|
||||
list_for_each_entry(eoe, &master->eoe_handlers, list)
|
||||
eoe->slave = NULL;
|
||||
|
||||
// couple a free EoE handler to every EoE-capable slave
|
||||
coupled = 0;
|
||||
list_for_each_entry(slave, &master->slaves, list) {
|
||||
if (!(slave->sii_mailbox_protocols & EC_MBOX_EOE)) continue;
|
||||
|
||||
found = 0;
|
||||
list_for_each_entry(eoe, &master->eoe_handlers, list) {
|
||||
if (eoe->slave) continue;
|
||||
eoe->slave = slave;
|
||||
found = 1;
|
||||
coupled++;
|
||||
EC_INFO("Coupling device %s to slave %i.\n",
|
||||
eoe->dev->name, slave->ring_position);
|
||||
if (eoe->opened)
|
||||
ec_slave_request_state(slave, EC_SLAVE_STATE_OP);
|
||||
else
|
||||
ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP);
|
||||
break;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
if (master->debug_level)
|
||||
EC_WARN("No EoE handler for slave %i!\n",
|
||||
slave->ring_position);
|
||||
ec_slave_request_state(slave, EC_SLAVE_STATE_PREOP);
|
||||
}
|
||||
if (master->eoe_running) {
|
||||
EC_WARN("EoE already running!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!coupled) {
|
||||
EC_INFO("No EoE handlers coupled.\n");
|
||||
if (list_empty(&master->eoe_handlers))
|
||||
return;
|
||||
|
||||
if (!master->request_cb || !master->release_cb) {
|
||||
EC_WARN("No EoE processing because of missing locking callbacks!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1110,7 +1088,6 @@ void ec_master_eoe_start(ec_master_t *master /**< EtherCAT master */)
|
|||
// start EoE processing
|
||||
master->eoe_timer.expires = jiffies + 10;
|
||||
add_timer(&master->eoe_timer);
|
||||
return;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -1121,24 +1098,11 @@ void ec_master_eoe_start(ec_master_t *master /**< EtherCAT master */)
|
|||
|
||||
void ec_master_eoe_stop(ec_master_t *master /**< EtherCAT master */)
|
||||
{
|
||||
ec_eoe_t *eoe;
|
||||
|
||||
master->eoe_checked = 0;
|
||||
|
||||
if (!master->eoe_running) return;
|
||||
|
||||
EC_INFO("Stopping EoE processing.\n");
|
||||
|
||||
del_timer_sync(&master->eoe_timer);
|
||||
|
||||
// decouple all EoE handlers
|
||||
list_for_each_entry(eoe, &master->eoe_handlers, list) {
|
||||
if (eoe->slave) {
|
||||
ec_slave_request_state(eoe->slave, EC_SLAVE_STATE_PREOP);
|
||||
eoe->slave = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
master->eoe_running = 0;
|
||||
}
|
||||
|
||||
|
|
@ -1152,14 +1116,18 @@ void ec_master_eoe_run(unsigned long data /**< master pointer */)
|
|||
{
|
||||
ec_master_t *master = (ec_master_t *) data;
|
||||
ec_eoe_t *eoe;
|
||||
unsigned int active = 0;
|
||||
unsigned int none_open = 1;
|
||||
cycles_t cycles_start, cycles_end;
|
||||
unsigned long restart_jiffies;
|
||||
|
||||
list_for_each_entry(eoe, &master->eoe_handlers, list) {
|
||||
if (ec_eoe_active(eoe)) active++;
|
||||
if (ec_eoe_is_open(eoe)) {
|
||||
none_open = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!active) goto queue_timer;
|
||||
if (none_open)
|
||||
goto queue_timer;
|
||||
|
||||
// receive datagrams
|
||||
if (master->request_cb(master->cb_data)) goto queue_timer;
|
||||
|
|
@ -1288,12 +1256,11 @@ void ec_master_prepare(ec_master_t *master /**< EtherCAT master */)
|
|||
/**
|
||||
* Translates an ASCII coded bus-address to a slave pointer.
|
||||
* These are the valid addressing schemes:
|
||||
* - \a "X" = the X. slave on the bus (ring position),
|
||||
* - \a "X:Y" = the Y. slave after the X. branch (bus coupler),
|
||||
* - \a "X" = the Xth slave on the bus (ring position),
|
||||
* - \a "#X" = the slave with alias X,
|
||||
* - \a "#X:Y" = the Y. slave after the branch (bus coupler) with alias X.
|
||||
* - \a "#X:Y" = the Yth slave after the slave with alias X.
|
||||
* X and Y are zero-based indices and may be provided in hexadecimal or octal
|
||||
* notation (with respective prefix).
|
||||
* notation (with appropriate prefix).
|
||||
* \return pointer to the slave on success, else NULL
|
||||
*/
|
||||
|
||||
|
|
@ -1462,12 +1429,15 @@ int ecrt_master_activate(ec_master_t *master /**< EtherCAT master */)
|
|||
|
||||
master->injection_seq_fsm = 0;
|
||||
master->injection_seq_rt = 0;
|
||||
master->request_cb = master->ext_request_cb;
|
||||
master->release_cb = master->ext_release_cb;
|
||||
master->cb_data = master->ext_cb_data;
|
||||
|
||||
if (ec_master_thread_start(master, ec_master_operation_thread)) {
|
||||
EC_ERR("Failed to start master thread!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ec_master_eoe_start(master);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -1577,9 +1547,9 @@ void ecrt_master_callbacks(ec_master_t *master, /**< EtherCAT master */
|
|||
void *cb_data /**< data parameter */
|
||||
)
|
||||
{
|
||||
master->request_cb = request_cb;
|
||||
master->release_cb = release_cb;
|
||||
master->cb_data = cb_data;
|
||||
master->ext_request_cb = request_cb;
|
||||
master->ext_release_cb = release_cb;
|
||||
master->ext_cb_data = cb_data;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
|
|
@ -144,17 +144,18 @@ struct ec_master
|
|||
unsigned int idle_cycle_time_pos; /**< time ring buffer position */
|
||||
|
||||
struct timer_list eoe_timer; /**< EoE timer object */
|
||||
unsigned int eoe_running; /**< non-zero, if EoE processing is active. */
|
||||
struct list_head eoe_handlers; /**< Ethernet-over-EtherCAT handlers */
|
||||
uint32_t eoe_cycle_times[HZ]; /**< EoE cycle times ring */
|
||||
unsigned int eoe_cycle_time_pos; /**< time ring buffer position */
|
||||
unsigned int eoe_running; /**< non-zero, if EoE processing is active. */
|
||||
unsigned int eoe_checked; /**< non-zero, if EoE processing is not
|
||||
necessary. */
|
||||
struct list_head eoe_handlers; /**< Ethernet-over-EtherCAT handlers */
|
||||
|
||||
spinlock_t internal_lock; /**< spinlock used in idle mode */
|
||||
int (*request_cb)(void *); /**< lock request callback */
|
||||
void (*release_cb)(void *); /**< lock release callback */
|
||||
void *cb_data; /**< data parameter of locking callbacks */
|
||||
int (*ext_request_cb)(void *); /**< external lock request callback */
|
||||
void (*ext_release_cb)(void *); /**< externam lock release callback */
|
||||
void *ext_cb_data; /**< data parameter of external locking callbacks */
|
||||
|
||||
struct list_head eeprom_requests; /**< EEPROM write requests */
|
||||
struct semaphore eeprom_sem; /**< semaphore protecting the list of
|
||||
|
|
@ -192,6 +193,7 @@ void ec_master_queue_datagram(ec_master_t *, ec_datagram_t *);
|
|||
|
||||
// misc.
|
||||
void ec_master_output_stats(ec_master_t *);
|
||||
void ec_master_clear_eoe_handlers(ec_master_t *);
|
||||
void ec_master_destroy_slaves(ec_master_t *);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
Loading…
Reference in New Issue