Renamed master 'mode' to 'phase'.
This commit is contained in:
parent
d91aa97487
commit
0ef150c812
1
TODO
1
TODO
|
|
@ -16,7 +16,6 @@ Version 1.4.0:
|
|||
* Update documentation.
|
||||
* Check for sizes of uploaded Sdos when reading mapping from CoE.
|
||||
* Attach Pdo names from SII or Coe dictioary to Pdos read via CoE.
|
||||
* Rename master MODE to STATE.
|
||||
* Remove the end state of the master state machine.
|
||||
* Add a -n (numeric) switch to ethercat command.
|
||||
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
|
|||
data.slave_count = master->slave_count;
|
||||
data.config_count = ec_master_config_count(master);
|
||||
data.domain_count = ec_master_domain_count(master);
|
||||
data.mode = (uint8_t) master->mode;
|
||||
data.phase = (uint8_t) master->phase;
|
||||
|
||||
memcpy(data.devices[0].address, master->main_mac, ETH_ALEN);
|
||||
data.devices[0].attached = master->main_device.dev ? 1 : 0;
|
||||
|
|
|
|||
|
|
@ -421,7 +421,7 @@ void ecdev_withdraw(ec_device_t *device /**< EtherCAT device */)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Opens the network device and makes the master enter IDLE mode.
|
||||
/** Opens the network device and makes the master enter IDLE phase.
|
||||
*
|
||||
* \return 0 on success, else < 0
|
||||
* \ingroup DeviceInterface
|
||||
|
|
@ -433,8 +433,8 @@ int ecdev_open(ec_device_t *device /**< EtherCAT device */)
|
|||
return -1;
|
||||
}
|
||||
|
||||
if (ec_master_enter_idle_mode(device->master)) {
|
||||
EC_ERR("Failed to enter idle mode!\n");
|
||||
if (ec_master_enter_idle_phase(device->master)) {
|
||||
EC_ERR("Failed to enter IDLE phase!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -443,14 +443,14 @@ int ecdev_open(ec_device_t *device /**< EtherCAT device */)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Makes the master leave IDLE mode and closes the network device.
|
||||
/** Makes the master leave IDLE phase and closes the network device.
|
||||
*
|
||||
* \return 0 on success, else < 0
|
||||
* \ingroup DeviceInterface
|
||||
*/
|
||||
void ecdev_close(ec_device_t *device /**< EtherCAT device */)
|
||||
{
|
||||
ec_master_leave_idle_mode(device->master);
|
||||
ec_master_leave_idle_phase(device->master);
|
||||
|
||||
if (ec_device_close(device))
|
||||
EC_WARN("Failed to close device!\n");
|
||||
|
|
|
|||
|
|
@ -260,9 +260,9 @@ void ec_fsm_master_state_broadcast(
|
|||
slave = master->slaves + i;
|
||||
ec_slave_init(slave, master, i, i + 1);
|
||||
|
||||
// do not force reconfiguration in operation mode to avoid
|
||||
// do not force reconfiguration in operation phase to avoid
|
||||
// unnecesssary process data interruptions
|
||||
if (master->mode != EC_MASTER_MODE_OPERATION)
|
||||
if (master->phase != EC_OPERATION)
|
||||
slave->force_config = 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ typedef struct {
|
|||
uint32_t slave_count;
|
||||
uint32_t config_count;
|
||||
uint32_t domain_count;
|
||||
uint8_t mode;
|
||||
uint8_t phase;
|
||||
struct {
|
||||
uint8_t address[6];
|
||||
uint8_t attached;
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ int ec_master_init(ec_master_t *master, /**< EtherCAT master */
|
|||
master->backup_mac = backup_mac;
|
||||
init_MUTEX(&master->device_sem);
|
||||
|
||||
master->mode = EC_MASTER_MODE_ORPHANED;
|
||||
master->phase = EC_ORPHANED;
|
||||
master->injection_seq_fsm = 0;
|
||||
master->injection_seq_rt = 0;
|
||||
|
||||
|
|
@ -338,7 +338,9 @@ int ec_master_thread_start(
|
|||
|
||||
/** Stops the master thread.
|
||||
*/
|
||||
void ec_master_thread_stop(ec_master_t *master /**< EtherCAT master */)
|
||||
void ec_master_thread_stop(
|
||||
ec_master_t *master /**< EtherCAT master */
|
||||
)
|
||||
{
|
||||
if (!master->thread_id) {
|
||||
EC_WARN("ec_master_thread_stop: Already finished!\n");
|
||||
|
|
@ -362,9 +364,11 @@ void ec_master_thread_stop(ec_master_t *master /**< EtherCAT master */)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Transition function from ORPHANED to IDLE mode.
|
||||
/** Transition function from ORPHANED to IDLE phase.
|
||||
*/
|
||||
int ec_master_enter_idle_mode(ec_master_t *master /**< EtherCAT master */)
|
||||
int ec_master_enter_idle_phase(
|
||||
ec_master_t *master /**< EtherCAT master */
|
||||
)
|
||||
{
|
||||
master->request_cb = ec_master_request_cb;
|
||||
master->release_cb = ec_master_release_cb;
|
||||
|
|
@ -373,9 +377,9 @@ int ec_master_enter_idle_mode(ec_master_t *master /**< EtherCAT master */)
|
|||
if (master->debug_level)
|
||||
EC_DBG("ORPHANED -> IDLE.\n");
|
||||
|
||||
master->mode = EC_MASTER_MODE_IDLE;
|
||||
master->phase = EC_IDLE;
|
||||
if (ec_master_thread_start(master, ec_master_idle_thread)) {
|
||||
master->mode = EC_MASTER_MODE_ORPHANED;
|
||||
master->phase = EC_ORPHANED;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
|
@ -384,14 +388,14 @@ int ec_master_enter_idle_mode(ec_master_t *master /**< EtherCAT master */)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Transition function from IDLE to ORPHANED mode.
|
||||
/** Transition function from IDLE to ORPHANED phase.
|
||||
*/
|
||||
void ec_master_leave_idle_mode(ec_master_t *master /**< EtherCAT master */)
|
||||
void ec_master_leave_idle_phase(ec_master_t *master /**< EtherCAT master */)
|
||||
{
|
||||
if (master->debug_level)
|
||||
EC_DBG("IDLE -> ORPHANED.\n");
|
||||
|
||||
master->mode = EC_MASTER_MODE_ORPHANED;
|
||||
master->phase = EC_ORPHANED;
|
||||
|
||||
#ifdef EC_EOE
|
||||
ec_master_eoe_stop(master);
|
||||
|
|
@ -402,9 +406,9 @@ void ec_master_leave_idle_mode(ec_master_t *master /**< EtherCAT master */)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Transition function from IDLE to OPERATION mode.
|
||||
/** Transition function from IDLE to OPERATION phase.
|
||||
*/
|
||||
int ec_master_enter_operation_mode(ec_master_t *master /**< EtherCAT master */)
|
||||
int ec_master_enter_operation_phase(ec_master_t *master /**< EtherCAT master */)
|
||||
{
|
||||
ec_slave_t *slave;
|
||||
#ifdef EC_EOE
|
||||
|
|
@ -464,9 +468,9 @@ int ec_master_enter_operation_mode(ec_master_t *master /**< EtherCAT master */)
|
|||
#endif
|
||||
|
||||
if (master->debug_level)
|
||||
EC_DBG("Switching to operation mode.\n");
|
||||
EC_DBG("Switching to operation phase.\n");
|
||||
|
||||
master->mode = EC_MASTER_MODE_OPERATION;
|
||||
master->phase = EC_OPERATION;
|
||||
master->ext_request_cb = NULL;
|
||||
master->ext_release_cb = NULL;
|
||||
master->ext_cb_data = NULL;
|
||||
|
|
@ -480,9 +484,9 @@ out_allow:
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Transition function from OPERATION to IDLE mode.
|
||||
/** Transition function from OPERATION to IDLE phase.
|
||||
*/
|
||||
void ec_master_leave_operation_mode(ec_master_t *master
|
||||
void ec_master_leave_operation_phase(ec_master_t *master
|
||||
/**< EtherCAT master */)
|
||||
{
|
||||
ec_slave_t *slave;
|
||||
|
|
@ -493,7 +497,7 @@ void ec_master_leave_operation_mode(ec_master_t *master
|
|||
if (master->debug_level)
|
||||
EC_DBG("OPERATION -> IDLE.\n");
|
||||
|
||||
master->mode = EC_MASTER_MODE_IDLE;
|
||||
master->phase = EC_IDLE;
|
||||
|
||||
#ifdef EC_EOE
|
||||
ec_master_eoe_stop(master);
|
||||
|
|
@ -771,7 +775,7 @@ void ec_master_receive_datagrams(ec_master_t *master, /**< EtherCAT master */
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Output statistics in cyclic mode.
|
||||
/** Output master statistics.
|
||||
*
|
||||
* This function outputs statistical data on demand, but not more often than
|
||||
* necessary. The output happens at most once a second.
|
||||
|
|
@ -801,7 +805,7 @@ void ec_master_output_stats(ec_master_t *master /**< EtherCAT master */)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Master kernel thread function for IDLE mode.
|
||||
/** Master kernel thread function for IDLE phase.
|
||||
*/
|
||||
static int ec_master_idle_thread(ec_master_t *master)
|
||||
{
|
||||
|
|
@ -857,7 +861,7 @@ schedule:
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Master kernel thread function for IDLE mode.
|
||||
/** Master kernel thread function for IDLE phase.
|
||||
*/
|
||||
static int ec_master_operation_thread(ec_master_t *master)
|
||||
{
|
||||
|
|
|
|||
132
master/master.h
132
master/master.h
|
|
@ -53,13 +53,16 @@
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** EtherCAT master mode.
|
||||
/** EtherCAT master phase.
|
||||
*/
|
||||
typedef enum {
|
||||
EC_MASTER_MODE_ORPHANED,
|
||||
EC_MASTER_MODE_IDLE,
|
||||
EC_MASTER_MODE_OPERATION
|
||||
} ec_master_mode_t;
|
||||
EC_ORPHANED, /**< Orphaned phase. The master has no Ethernet device
|
||||
attached. */
|
||||
EC_IDLE, /**< Idle phase. An Ethernet device is attached, but the master
|
||||
is not in use, yet. */
|
||||
EC_OPERATION /**< Operation phase. The master was requested by a realtime
|
||||
application. */
|
||||
} ec_master_phase_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
|
|
@ -80,25 +83,25 @@ typedef struct {
|
|||
* Manages slaves, domains and IO.
|
||||
*/
|
||||
struct ec_master {
|
||||
unsigned int index; /**< master index */
|
||||
unsigned int reserved; /**< non-zero, if the master is reserved for RT */
|
||||
unsigned int index; /**< Index. */
|
||||
unsigned int reserved; /**< \a True, if the master is in use. */
|
||||
|
||||
ec_cdev_t cdev; /**< Master character device. */
|
||||
struct class_device *class_device; /**< Master class device. */
|
||||
|
||||
ec_device_t main_device; /**< EtherCAT device */
|
||||
const uint8_t *main_mac; /**< MAC address of main device */
|
||||
ec_device_t backup_device; /**< EtherCAT backup device */
|
||||
const uint8_t *backup_mac; /**< MAC address of backup device */
|
||||
struct semaphore device_sem; /**< device semaphore */
|
||||
ec_device_t main_device; /**< EtherCAT main device. */
|
||||
const uint8_t *main_mac; /**< MAC address of main device. */
|
||||
ec_device_t backup_device; /**< EtherCAT backup device. */
|
||||
const uint8_t *backup_mac; /**< MAC address of backup device. */
|
||||
struct semaphore device_sem; /**< Device semaphore. */
|
||||
|
||||
ec_fsm_master_t fsm; /**< master state machine */
|
||||
ec_datagram_t fsm_datagram; /**< datagram used for state machines */
|
||||
ec_master_mode_t mode; /**< master mode */
|
||||
unsigned int injection_seq_fsm; /**< datagram injection sequence number
|
||||
for the FSM side */
|
||||
unsigned int injection_seq_rt; /**< datagram injection sequence number
|
||||
for the realtime side */
|
||||
ec_fsm_master_t fsm; /**< Master state machine. */
|
||||
ec_datagram_t fsm_datagram; /**< Datagram used for state machines. */
|
||||
ec_master_phase_t phase; /**< Master phase. */
|
||||
unsigned int injection_seq_fsm; /**< Datagram injection sequence number
|
||||
for the FSM side. */
|
||||
unsigned int injection_seq_rt; /**< Datagram injection sequence number
|
||||
for the realtime side. */
|
||||
|
||||
ec_slave_t *slaves; /**< Array of slaves on the bus. */
|
||||
unsigned int slave_count; /**< Number of slaves on the bus. */
|
||||
|
|
@ -106,61 +109,62 @@ struct ec_master {
|
|||
struct list_head configs; /**< List of slave configurations. */
|
||||
|
||||
unsigned int scan_busy; /**< Current scan state. */
|
||||
unsigned int allow_scan; /**< non-zero, if slave scanning is allowed */
|
||||
struct semaphore scan_sem; /**< semaphore protecting the scan_state
|
||||
variable and the allow_scan flag */
|
||||
wait_queue_head_t scan_queue; /**< queue for processes that wait for
|
||||
slave scanning */
|
||||
unsigned int allow_scan; /**< \a True, if slave scanning is allowed. */
|
||||
struct semaphore scan_sem; /**< Semaphore protecting the \a scan_busy
|
||||
variable and the \a allow_scan flag. */
|
||||
wait_queue_head_t scan_queue; /**< Queue for processes that wait for
|
||||
slave scanning. */
|
||||
|
||||
unsigned int config_busy; /**< State of slave configuration. */
|
||||
unsigned int allow_config; /**< non-zero, if slave scanning is allowed */
|
||||
struct semaphore config_sem; /**< semaphore protecting the config_state
|
||||
variable and the allow_config flag */
|
||||
wait_queue_head_t config_queue; /**< queue for processes that wait for
|
||||
slave configuration */
|
||||
unsigned int allow_config; /**< \a True, if slave configuration is
|
||||
allowed. */
|
||||
struct semaphore config_sem; /**< Semaphore protecting the \a config_busy
|
||||
variable and the allow_config flag. */
|
||||
wait_queue_head_t config_queue; /**< Queue for processes that wait for
|
||||
slave configuration. */
|
||||
|
||||
struct list_head datagram_queue; /**< datagram queue */
|
||||
uint8_t datagram_index; /**< current datagram index */
|
||||
struct list_head datagram_queue; /**< Datagram queue. */
|
||||
uint8_t datagram_index; /**< Current datagram index. */
|
||||
|
||||
struct list_head domains; /**< list of domains */
|
||||
struct list_head domains; /**< List of domains. */
|
||||
|
||||
int debug_level; /**< Master debug level. */
|
||||
ec_stats_t stats; /**< cyclic statistics */
|
||||
unsigned int frames_timed_out; /**< there were frame timeouts in the last
|
||||
call to ecrt_master_receive() */
|
||||
ec_stats_t stats; /**< Cyclic statistics. */
|
||||
unsigned int frames_timed_out; /**< There were frame timeouts in the last
|
||||
call to ecrt_master_receive(). */
|
||||
|
||||
int thread_id; /**< master thread PID */
|
||||
struct completion thread_exit; /**< thread completion object */
|
||||
uint32_t idle_cycle_times[HZ]; /**< Idle cycle times ring */
|
||||
int thread_id; /**< Master thread PID. */
|
||||
struct completion thread_exit; /**< Thread completion object. */
|
||||
uint32_t idle_cycle_times[HZ]; /**< Idle cycle times ring. */
|
||||
unsigned int idle_cycle_time_pos; /**< time ring buffer position */
|
||||
|
||||
#ifdef EC_EOE
|
||||
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 */
|
||||
struct timer_list eoe_timer; /**< EoE timer object. */
|
||||
unsigned int eoe_running; /**< \a True, 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. */
|
||||
#endif
|
||||
|
||||
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 */
|
||||
spinlock_t internal_lock; /**< Spinlock used in \a IDLE phase. */
|
||||
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 *); /**< External lock release callback. */
|
||||
void *ext_cb_data; /**< Data parameter of external locking callbacks. */
|
||||
|
||||
struct list_head sii_requests; /**< SII write requests */
|
||||
struct semaphore sii_sem; /**< semaphore protecting the list of
|
||||
SII write requests */
|
||||
wait_queue_head_t sii_queue; /**< wait queue for SII
|
||||
write requests from user space */
|
||||
struct list_head sii_requests; /**< SII write requests. */
|
||||
struct semaphore sii_sem; /**< Semaphore protecting the list of
|
||||
SII write requests. */
|
||||
wait_queue_head_t sii_queue; /**< Wait queue for SII
|
||||
write requests from user space. */
|
||||
|
||||
struct list_head slave_sdo_requests; /**< Sdo access requests. */
|
||||
struct semaphore sdo_sem; /**< semaphore protecting the list of
|
||||
Sdo access requests */
|
||||
wait_queue_head_t sdo_queue; /**< wait queue for Sdo access requests
|
||||
from user space */
|
||||
struct semaphore sdo_sem; /**< Semaphore protecting the list of
|
||||
Sdo access requests. */
|
||||
wait_queue_head_t sdo_queue; /**< Wait queue for Sdo access requests
|
||||
from user space. */
|
||||
};
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -170,11 +174,11 @@ int ec_master_init(ec_master_t *, unsigned int, const uint8_t *,
|
|||
const uint8_t *, dev_t, struct class *);
|
||||
void ec_master_clear(ec_master_t *);
|
||||
|
||||
// mode transitions
|
||||
int ec_master_enter_idle_mode(ec_master_t *);
|
||||
void ec_master_leave_idle_mode(ec_master_t *);
|
||||
int ec_master_enter_operation_mode(ec_master_t *);
|
||||
void ec_master_leave_operation_mode(ec_master_t *);
|
||||
// phase transitions
|
||||
int ec_master_enter_idle_phase(ec_master_t *);
|
||||
void ec_master_leave_idle_phase(ec_master_t *);
|
||||
int ec_master_enter_operation_phase(ec_master_t *);
|
||||
void ec_master_leave_operation_phase(ec_master_t *);
|
||||
|
||||
#ifdef EC_EOE
|
||||
// EoE
|
||||
|
|
|
|||
|
|
@ -484,7 +484,7 @@ ec_master_t *ecrt_request_master(unsigned int master_index)
|
|||
|
||||
down(&master->device_sem);
|
||||
|
||||
if (master->mode != EC_MASTER_MODE_IDLE) {
|
||||
if (master->phase != EC_IDLE) {
|
||||
up(&master->device_sem);
|
||||
EC_ERR("Master %u still waiting for devices!\n", master_index);
|
||||
goto out_release;
|
||||
|
|
@ -498,8 +498,8 @@ ec_master_t *ecrt_request_master(unsigned int master_index)
|
|||
|
||||
up(&master->device_sem);
|
||||
|
||||
if (ec_master_enter_operation_mode(master)) {
|
||||
EC_ERR("Failed to enter OPERATION mode!\n");
|
||||
if (ec_master_enter_operation_phase(master)) {
|
||||
EC_ERR("Failed to enter OPERATION phase!\n");
|
||||
goto out_module_put;
|
||||
}
|
||||
|
||||
|
|
@ -525,7 +525,7 @@ void ecrt_release_master(ec_master_t *master)
|
|||
return;
|
||||
}
|
||||
|
||||
ec_master_leave_operation_mode(master);
|
||||
ec_master_leave_operation_phase(master);
|
||||
|
||||
module_put(master->main_device.module);
|
||||
master->reserved = 0;
|
||||
|
|
|
|||
|
|
@ -434,14 +434,14 @@ void Master::showMaster()
|
|||
|
||||
cout
|
||||
<< "Master" << index << endl
|
||||
<< " State: ";
|
||||
<< " Phase: ";
|
||||
|
||||
switch (data.mode) {
|
||||
switch (data.phase) {
|
||||
case 0: cout << "Waiting for device..."; break;
|
||||
case 1: cout << "Idle"; break;
|
||||
case 2: cout << "Operation"; break;
|
||||
default:
|
||||
err << "Invalid master state " << data.mode;
|
||||
err << "Invalid master phase " << data.phase;
|
||||
throw MasterException(err.str());
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue