include/ecrt.h
changeset 2589 2b9c78543663
parent 2248 82afd3a5bab1
child 2609 777d1a8b3a27
--- a/include/ecrt.h	Thu Sep 06 14:21:02 2012 +0200
+++ b/include/ecrt.h	Mon Nov 03 15:20:05 2014 +0100
@@ -2,7 +2,7 @@
  *
  *  $Id$
  *
- *  Copyright (C) 2006-2008  Florian Pose, Ingenieurgemeinschaft IgH
+ *  Copyright (C) 2006-2012  Florian Pose, Ingenieurgemeinschaft IgH
  *
  *  This file is part of the IgH EtherCAT master userspace library.
  *
@@ -39,6 +39,37 @@
  * request a master, to map process data, to communicate with slaves via CoE
  * and to configure and activate the bus.
  *
+ * Changes in version 1.5.2:
+ *
+ * - Added redundancy_active flag to ec_domain_state_t.
+ * - Added ecrt_master_link_state() method and ec_master_link_state_t to query
+ *   the state of a redundant link.
+ * - Added the EC_HAVE_REDUNDANCY define, to check, if the interface contains
+ *   redundancy features.
+ * - Added ecrt_sdo_request_index() to change SDO index and subindex after
+ *   handler creation.
+ * - Added interface for retrieving CoE emergency messages, i. e.
+ *   ecrt_slave_config_emerg_size(), ecrt_slave_config_emerg_pop(),
+ *   ecrt_slave_config_emerg_clear(), ecrt_slave_config_emerg_overruns() and
+ *   the defines EC_HAVE_EMERGENCY and EC_COE_EMERGENCY_MSG_SIZE.
+ * - Added interface for direct EtherCAT register access: Added data type
+ *   ec_reg_request_t and methods ecrt_slave_config_create_reg_request(),
+ *   ecrt_reg_request_data(), ecrt_reg_request_state(),
+ *   ecrt_reg_request_write(), ecrt_reg_request_read() and the feature flag
+ *   EC_HAVE_REG_ACCESS.
+ * - Added method to select the reference clock,
+ *   ecrt_master_select_reference_clock() and the feature flag
+ *   EC_HAVE_SELECT_REF_CLOCK to check, if the method is available.
+ * - Added method to get the reference clock time,
+ *   ecrt_master_reference_clock_time() and the feature flag
+ *   EC_HAVE_REF_CLOCK_TIME to have the possibility to synchronize the master
+ *   clock to the reference clock.
+ * - Changed the data types of the shift times in ecrt_slave_config_dc() to
+ *   int32_t to correctly display negative shift times.
+ * - Added ecrt_slave_config_reg_pdo_entry_pos() and the feature flag
+ *   EC_HAVE_REG_BY_POS for registering PDO entries with non-unique indices
+ *   via their positions in the mapping.
+ *
  * Changes in version 1.5:
  *
  * - Added the distributed clocks feature and the respective method
@@ -49,7 +80,9 @@
  *   ecrt_master_sync_monitor_queue() and ecrt_master_sync_monitor_process()
  *   methods can be used to monitor the synchrony.
  * - Improved the callback mechanism. ecrt_master_callbacks() now takes two
- *   callback functions for locking and unlocking the fsm datagram queue.
+ *   callback functions for sending and receiving datagrams.
+ *   ecrt_master_send_ext() is used to execute the sending of non-application
+ *   datagrams.
  * - Added watchdog configuration (method ecrt_slave_config_watchdog(),
  *   #ec_watchdog_mode_t, \a watchdog_mode parameter in ec_sync_info_t and
  *   ecrt_slave_config_sync_manager()).
@@ -78,8 +111,6 @@
  *   and ecrt_master_read_idn() and ecrt_master_write_idn() to read/write IDNs
  *   ad-hoc via the user-space library.
  * - Added ecrt_master_reset() to initiate retrying to configure slaves.
- * - Added support for overlapping PDOs which allows inputs to use the same
- *   space as outputs on the frame. This reduces the frame length.
  *
  * @{
  */
@@ -119,6 +150,43 @@
  */
 #define ECRT_VERSION_MAGIC ECRT_VERSION(ECRT_VER_MAJOR, ECRT_VER_MINOR)
 
+/******************************************************************************
+ * Feature flags
+ *****************************************************************************/
+
+/** Defined, if the redundancy features are available.
+ *
+ * I. e. if the \a redundancy_active flag in ec_domain_state_t and the
+ * ecrt_master_link_state() method are available.
+ */
+#define EC_HAVE_REDUNDANCY
+
+/** Defined, if the CoE emergency ring feature is available.
+ *
+ * I. e. if the ecrt_slave_config_emerg_*() methods are available.
+ */
+#define EC_HAVE_EMERGENCY
+
+/** Defined, if the register access interface is available.
+ *
+ * I. e. if the methods ecrt_slave_config_create_reg_request(),
+ * ecrt_reg_request_data(), ecrt_reg_request_state(), ecrt_reg_request_write()
+ * and ecrt_reg_request_read() are available.
+ */
+#define EC_HAVE_REG_ACCESS
+
+/** Defined if the method ecrt_master_select_reference_clock() is available.
+ */
+#define EC_HAVE_SELECT_REF_CLOCK
+
+/** Defined if the method ecrt_master_reference_clock_time() is available.
+ */
+#define EC_HAVE_REF_CLOCK_TIME
+
+/** Defined if the method ecrt_slave_config_reg_pdo_entry_pos() is available.
+ */
+#define EC_HAVE_REG_BY_POS
+
 /*****************************************************************************/
 
 /** End of list marker.
@@ -151,6 +219,12 @@
 #define EC_TIMEVAL2NANO(TV) \
     (((TV).tv_sec - 946684800ULL) * 1000000000ULL + (TV).tv_usec * 1000ULL)
 
+/** Size of a CoE emergency message in byte.
+ *
+ * \see ecrt_slave_config_emerg_pop().
+ */
+#define EC_COE_EMERGENCY_MSG_SIZE 8
+
 /******************************************************************************
  * Data types
  *****************************************************************************/
@@ -170,18 +244,20 @@
 struct ec_voe_handler;
 typedef struct ec_voe_handler ec_voe_handler_t; /**< \see ec_voe_handler. */
 
+struct ec_reg_request;
+typedef struct ec_reg_request ec_reg_request_t; /**< \see ec_sdo_request. */
+
 /*****************************************************************************/
 
 /** Master state.
  *
- * This is used for the output parameter of ecrt_master_state() and
- * ecrt_master_configured_slaves_state().
+ * This is used for the output parameter of ecrt_master_state().
  *
  * \see ecrt_master_state().
- * \see ecrt_master_configured_slaves_state().
  */
 typedef struct {
-    unsigned int slaves_responding; /**< Number of slaves in the bus. */
+    unsigned int slaves_responding; /**< Sum of responding slaves on all
+                                      Ethernet devices. */
     unsigned int al_states : 4; /**< Application-layer states of all slaves.
                                   The states are coded in the lower 4 bits.
                                   If a bit is set, it means that at least one
@@ -191,11 +267,36 @@
                                   - Bit 1: \a PREOP
                                   - Bit 2: \a SAFEOP
                                   - Bit 3: \a OP */
-    unsigned int link_up : 1; /**< \a true, if the network link is up. */
+    unsigned int link_up : 1; /**< \a true, if at least one Ethernet link is
+                                up. */
 } ec_master_state_t;
 
 /*****************************************************************************/
 
+/** Redundant link state.
+ *
+ * This is used for the output parameter of ecrt_master_link_state().
+ *
+ * \see ecrt_master_link_state().
+ */
+typedef struct {
+    unsigned int slaves_responding; /**< Sum of responding slaves on the given
+                                      link. */
+    unsigned int al_states : 4; /**< Application-layer states of the slaves on
+                                  the given link.  The states are coded in the
+                                  lower 4 bits.  If a bit is set, it means
+                                  that at least one slave in the bus is in the
+                                  corresponding state:
+                                  - Bit 0: \a INIT
+                                  - Bit 1: \a PREOP
+                                  - Bit 2: \a SAFEOP
+                                  - Bit 3: \a OP */
+    unsigned int link_up : 1; /**< \a true, if the given Ethernet link is up.
+                               */
+} ec_master_link_state_t;
+
+/*****************************************************************************/
+
 /** Slave configuration state.
  *
  * This is used as an output parameter of ecrt_slave_config_state().
@@ -238,8 +339,8 @@
 typedef enum {
     EC_PORT_NOT_IMPLEMENTED, /**< Port is not implemented. */
     EC_PORT_NOT_CONFIGURED, /**< Port is not configured. */
-    EC_PORT_EBUS, /**< Port is an e-bus. */
-    EC_PORT_MII /**< Port is a mii. */
+    EC_PORT_EBUS, /**< Port is an E-Bus. */
+    EC_PORT_MII /**< Port is a MII. */
 } ec_slave_port_desc_t;
 
 /*****************************************************************************/
@@ -306,6 +407,7 @@
 typedef struct {
     unsigned int working_counter; /**< Value of the last working counter. */
     ec_wc_state_t wc_state; /**< Working counter interpretation. */
+    unsigned int redundancy_active; /**< Redundant link is in use. */
 } ec_domain_state_t;
 
 /*****************************************************************************/
@@ -486,25 +588,16 @@
  *
  * After use, a master it has to be released to make it available for other
  * applications.
+ *
+ * This method frees all created data structures. It should not be called in
+ * realtime context.
+ *
+ * If the master was activated, ecrt_master_deactivate() is called internally.
  */
 void ecrt_release_master(
         ec_master_t *master /**< EtherCAT master */
         );
 
-#ifdef __KERNEL__
-
-/** Attach to a running master
- *
- * This function returns the master handle for the RTDM-Interface
- *
- * \return Pointer to the opened master, otherwise \a NULL.
- */
-ec_master_t *ecrt_attach_master(
-       unsigned int master_index /**< Index of the master to request. */
-       );
-
-#endif // #ifdef __KERNEL__
-
 /******************************************************************************
  * Master methods
  *****************************************************************************/
@@ -517,7 +610,6 @@
  * request functions on the master, it has to reserve one for exclusive use.
  *
  * \return 0 in case of success, else < 0
- *
  */
 int ecrt_master_reserve(
         ec_master_t *master /**< EtherCAT master */
@@ -529,50 +621,31 @@
 
 /** Sets the locking callbacks.
  *
- * For concurrent master access, the application has to provide a locking
- * mechanism. The method takes two function pointers and a data value as
- * its parameters.
- * The arbitrary \a cb_data value will be passed as argument on every callback.
- *
+ * For concurrent master access, i. e. if other instances than the application
+ * want to send and receive datagrams on the bus, the application has to
+ * provide a callback mechanism. This method takes two function pointers as
+ * its parameters. Asynchronous master access (like EoE processing) is only
+ * possible if the callbacks have been set.
+ *
+ * The task of the send callback (\a send_cb) is to decide, if the bus is
+ * currently accessible and whether or not to call the ecrt_master_send_ext()
+ * method.
+ *
+ * The task of the receive callback (\a receive_cb) is to decide, if a call to
+ * ecrt_master_receive() is allowed and to execute it respectively.
+ *
+ * \attention This method has to be called before ecrt_master_activate().
  */
 void ecrt_master_callbacks(
         ec_master_t *master, /**< EtherCAT master */
-        void (*lock_cb)(void *), /**< Lock function. */
-        void (*unlock_cb)(void *), /**< Unlock function. */
-        void *cb_data /**< Arbitrary user data. */
-        );
-
-/** Returns domain structure pointer
- *
- * \fixme The application knows the domain pointers!
- *
- * This functions return the domain structure pointer for usage inside the
- * RTDM-Interface.
- *
- * \return Pointer to the domain on success, else NULL.
- */
-ec_domain_t *ecrt_master_find_domain(
-        ec_master_t *master,
-        unsigned int index);
+        void (*send_cb)(void *), /**< Datagram sending callback. */
+        void (*receive_cb)(void *), /**< Receive callback. */
+        void *cb_data /**< Arbitrary pointer passed to the callback functions.
+                       */
+        );
 
 #endif /* __KERNEL__ */
 
-#ifndef __KERNEL__
-
-/** Return the domain index of a given domain strucure
- *
- * Return the domain index of a given domain strucure. Usage inside of the
- * RTDM Interface
- *
- * \return Index of the domain strucure
- *
- */
- unsigned int ecrt_domain_index(
-         ec_domain_t *domain
-         );
-
-#endif // #ifndef __KERNEL__
-
 /** Creates a new process data domain.
  *
  * For process data exchange, at least one process data domain is needed.
@@ -580,6 +653,9 @@
  * new domain object. This object can be used for registering PDOs and
  * exchanging them in cyclic operation.
  *
+ * This method allocates memory and should be called in non-realtime context
+ * before ecrt_master_activate().
+ *
  * \return Pointer to the new domain on success, else NULL.
  */
 ec_domain_t *ecrt_master_create_domain(
@@ -610,6 +686,9 @@
  * configuration, a warning is raised and only the first configuration is
  * applied.
  *
+ * This method allocates memory and should be called in non-realtime context
+ * before ecrt_master_activate().
+ *
  * \retval >0 Pointer to the slave configuration structure.
  * \retval NULL in the error case.
  */
@@ -621,6 +700,20 @@
         uint32_t product_code /**< Expected product code. */
         );
 
+/** Selects the reference clock for distributed clocks.
+ *
+ * If this method is not called for a certain master, or if the slave
+ * configuration pointer is NULL, then the first slave with DC functionality
+ * will provide the reference clock.
+ *
+ * \return 0 on success, otherwise negative error code.
+ */
+int ecrt_master_select_reference_clock(
+        ec_master_t *master, /**< EtherCAT master. */
+        ec_slave_config_t *sc /**< Slave config of the slave to use as the
+                               * reference slave (or NULL). */
+        );
+
 /** Obtains master information.
  *
  * No memory is allocated on the heap in
@@ -772,7 +865,7 @@
  * error occurred.
  *
  * \retval  0 Success.
- * \retval -1 An error occured.
+ * \retval <0 Error code.
  */
 int ecrt_master_write_idn(
         ec_master_t *master, /**< EtherCAT master. */
@@ -791,7 +884,7 @@
  * error occurred.
  *
  * \retval  0 Success.
- * \retval -1 An error occured.
+ * \retval <0 Error code.
  */
 int ecrt_master_read_idn(
         ec_master_t *master, /**< EtherCAT master. */
@@ -818,7 +911,8 @@
  * in charge of cyclically calling ecrt_master_send() and
  * ecrt_master_receive() to ensure bus communication. Before calling this
  * function, the master thread is responsible for that, so these functions may
- * not be called!
+ * not be called! The method itself allocates memory and should not be called
+ * in realtime context.
  *
  * \return 0 in case of success, else < 0
  */
@@ -833,13 +927,22 @@
  * ecrt_slave_config_create_sdo_request() and
  * ecrt_slave_config_create_voe_handler() are freed, so pointers to them
  * become invalid.
+ *
+ * This method should not be called in realtime context.
  */
 void ecrt_master_deactivate(
         ec_master_t *master /**< EtherCAT master. */
         );
 
-/** Set interval between calls to ecrt_master_send
- *
+/** Set interval between calls to ecrt_master_send().
+ *
+ * This information helps the master to decide, how much data can be appended
+ * to a frame by the master state machine. When the master is configured with
+ * --enable-hrtimers, this is used to calculate the scheduling of the master
+ * thread.
+ *
+ * \retval 0 on success.
+ * \retval <0 Error code.
  */
 int ecrt_master_set_send_interval(
         ec_master_t *master, /**< EtherCAT master. */
@@ -872,26 +975,39 @@
         ec_master_t *master /**< EtherCAT master. */
         );
 
+/** Sends non-application datagrams.
+ *
+ * This method has to be called in the send callback function passed via
+ * ecrt_master_callbacks() to allow the sending of non-application datagrams.
+ */
+void ecrt_master_send_ext(
+        ec_master_t *master /**< EtherCAT master. */
+        );
+
 /** Reads the current master state.
  *
  * Stores the master state information in the given \a state structure.
+ *
+ * This method returns a global state. For the link-specific states in a
+ * redundant bus topology, use the ecrt_master_link_state() method.
  */
 void ecrt_master_state(
         const ec_master_t *master, /**< EtherCAT master. */
         ec_master_state_t *state /**< Structure to store the information. */
         );
 
-/** Reads the current master state and the al_state of all configured slaves.
- *
- * Use this function instead of ecrt_master_state() if there are unused slaves
- * on the bus. Stores the master state information in the given \a state
- * structure.
- *
- * \see ecrt_master_state()
- */
-void ecrt_master_configured_slaves_state(
+/** Reads the current state of a redundant link.
+ *
+ * Stores the link state information in the given \a state structure.
+ *
+ * \return Zero on success, otherwise negative error code.
+ */
+int ecrt_master_link_state(
         const ec_master_t *master, /**< EtherCAT master. */
-        ec_master_state_t *state /**< Structure to store the information. */
+        unsigned int dev_idx, /**< Index of the device (0 = main device, 1 =
+                                first backup device, ...). */
+        ec_master_link_state_t *state /**< Structure to store the information.
+                                       */
         );
 
 /** Sets the application time.
@@ -900,6 +1016,12 @@
  * distributed clocks. The time is not incremented by the master itself, so
  * this method has to be called cyclically.
  *
+ * \attention The first call of this method is used to calculate the phase
+ * delay for the slaves' SYNC0/1 interrupts. Either the method has to be
+ * called during the realtime cycle *only*, or the first time submitted must
+ * be in-phase with the realtime cycle. Otherwise synchronisation problems can
+ * occur.
+ *
  * The time is used when setting the slaves' <tt>System Time Offset</tt> and
  * <tt>Cyclic Operation Start Time</tt> registers and when synchronizing the
  * DC reference clock to the application time via
@@ -930,23 +1052,44 @@
         ec_master_t *master /**< EtherCAT master. */
         );
 
-/** Queues the DC synchonity monitoring datagram for sending.
+/** Get the lower 32 bit of the reference clock system time.
+ *
+ * This method can be used to synchronize the master to the reference clock.
+ *
+ * The reference clock system time is queried via the
+ * ecrt_master_sync_slave_clocks() method, that reads the system time of the
+ * reference clock and writes it to the slave clocks (so be sure to call it
+ * cyclically to get valid data).
+ *
+ * \attention The returned time is the system time of the reference clock
+ * minus the transmission delay of the reference clock.
+ *
+ * \retval 0 success, system time was written into \a time.
+ * \retval -ENXIO No reference clock found.
+ * \retval -EIO Slave synchronization datagram was not received.
+ */
+int ecrt_master_reference_clock_time(
+        ec_master_t *master, /**< EtherCAT master. */
+        uint32_t *time /**< Pointer to store the queried system time. */
+        );
+
+/** Queues the DC synchrony monitoring datagram for sending.
  *
  * The datagram broadcast-reads all "System time difference" registers (\a
- * 0x092c) to get an upper estiomation of the DC synchony. The result can be
+ * 0x092c) to get an upper estimation of the DC synchrony. The result can be
  * checked with the ecrt_master_sync_monitor_process() method.
  */
 void ecrt_master_sync_monitor_queue(
         ec_master_t *master /**< EtherCAT master. */
         );
 
-/** Processes the DC synchonity monitoring datagram.
+/** Processes the DC synchrony monitoring datagram.
  *
  * If the sync monitoring datagram was sent before with
  * ecrt_master_sync_monitor_queue(), the result can be queried with this
  * method.
  *
- * \return Upper estination of the maximum time difference in ns.
+ * \return Upper estimation of the maximum time difference in ns.
  */
 uint32_t ecrt_master_sync_monitor_process(
         ec_master_t *master /**< EtherCAT master. */
@@ -972,6 +1115,9 @@
  * Sets the direction of a sync manager. This overrides the direction bits
  * from the default control register from SII.
  *
+ * This method has to be called in non-realtime context before
+ * ecrt_master_activate().
+ *
  * \return zero on success, else non-zero
  */
 int ecrt_slave_config_sync_manager(
@@ -983,32 +1129,27 @@
         );
 
 /** Configure a slave's watchdog times.
+ *
+ * This method has to be called in non-realtime context before
+ * ecrt_master_activate().
  */
 void ecrt_slave_config_watchdog(
         ec_slave_config_t *sc, /**< Slave configuration. */
         uint16_t watchdog_divider, /**< Number of 40 ns intervals. Used as a
                                      base unit for all slave watchdogs. If set
                                      to zero, the value is not written, so the
-                                     default ist used. */
+                                     default is used. */
         uint16_t watchdog_intervals /**< Number of base intervals for process
                                       data watchdog. If set to zero, the value
                                       is not written, so the default is used.
                                      */
         );
 
-/** Configure wether a slave allows overlapping PDOs.
- *
- * Overlapping PDOs allows inputs to use the same space as outputs on the frame.
- * This reduces the frame length.
- */
-void ecrt_slave_config_overlapping_pdos(
-        ec_slave_config_t *sc, /**< Slave configuration. */
-        uint8_t allow_overlapping_pdos /**< Allow overlapping PDOs */
-        );
-
-
 /** Add a PDO to a sync manager's PDO assignment.
  *
+ * This method has to be called in non-realtime context before
+ * ecrt_master_activate().
+ *
  * \see ecrt_slave_config_pdos()
  * \return zero on success, else non-zero
  */
@@ -1025,6 +1166,9 @@
  * ecrt_slave_config_pdo_assign_add(), to clear the default assignment of a
  * sync manager.
  *
+ * This method has to be called in non-realtime context before
+ * ecrt_master_activate().
+ *
  * \see ecrt_slave_config_pdos()
  */
 void ecrt_slave_config_pdo_assign_clear(
@@ -1035,6 +1179,9 @@
 
 /** Add a PDO entry to the given PDO's mapping.
  *
+ * This method has to be called in non-realtime context before
+ * ecrt_master_activate().
+ *
  * \see ecrt_slave_config_pdos()
  * \return zero on success, else non-zero
  */
@@ -1053,6 +1200,9 @@
  * This can be called before mapping PDO entries via
  * ecrt_slave_config_pdo_mapping_add(), to clear the default mapping.
  *
+ * This method has to be called in non-realtime context before
+ * ecrt_master_activate().
+ *
  * \see ecrt_slave_config_pdos()
  */
 void ecrt_slave_config_pdo_mapping_clear(
@@ -1126,6 +1276,9 @@
  *   \a n_syncs should set to a number greater than the number of list items;
  *   using EC_END is recommended.
  *
+ * This method has to be called in non-realtime context before
+ * ecrt_master_activate().
+ *
  * \return zero on success, else non-zero
  */
 int ecrt_slave_config_pdos(
@@ -1148,6 +1301,9 @@
  * This pointer may be \a NULL, in this case an error is raised if the PDO
  * entry does not byte-align.
  *
+ * This method has to be called in non-realtime context before
+ * ecrt_master_activate().
+ *
  * \retval >=0 Success: Offset of the PDO entry's process data.
  * \retval  <0 Error code.
  */
@@ -1160,6 +1316,29 @@
                                  is desired */
         );
 
+/** Registers a PDO entry using its position.
+ *
+ * Similar to ecrt_slave_config_reg_pdo_entry(), but not using PDO indices but
+ * offsets in the PDO mapping, because PDO entry indices may not be unique
+ * inside a slave's PDO mapping. An error is raised, if
+ * one of the given positions is out of range.
+ *
+ * This method has to be called in non-realtime context before
+ * ecrt_master_activate().
+ *
+ * \retval >=0 Success: Offset of the PDO entry's process data.
+ * \retval  <0 Error code.
+ */
+int ecrt_slave_config_reg_pdo_entry_pos(
+        ec_slave_config_t *sc, /**< Slave configuration. */
+        uint8_t sync_index, /**< Sync manager index. */
+        unsigned int pdo_pos, /**< Position of the PDO inside the SM. */
+        unsigned int entry_pos, /**< Position of the entry inside the PDO. */
+        ec_domain_t *domain, /**< Domain. */
+        unsigned int *bit_position /**< Optional address if bit addressing
+                                 is desired */
+        );
+
 /** Configure distributed clocks.
  *
  * Sets the AssignActivate word and the cycle and shift times for the sync
@@ -1168,14 +1347,19 @@
  * The AssignActivate word is vendor-specific and can be taken from the XML
  * device description file (Device -> Dc -> AssignActivate). Set this to zero,
  * if the slave shall be operated without distributed clocks (default).
+ *
+ * This method has to be called in non-realtime context before
+ * ecrt_master_activate().
+ *
+ * \attention The \a sync1_shift time is ignored.
  */
 void ecrt_slave_config_dc(
         ec_slave_config_t *sc, /**< Slave configuration. */
         uint16_t assign_activate, /**< AssignActivate word. */
         uint32_t sync0_cycle, /**< SYNC0 cycle time [ns]. */
-        uint32_t sync0_shift, /**< SYNC0 shift time [ns]. */
+        int32_t sync0_shift, /**< SYNC0 shift time [ns]. */
         uint32_t sync1_cycle, /**< SYNC1 cycle time [ns]. */
-        uint32_t sync1_shift /**< SYNC1 shift time [ns]. */
+        int32_t sync1_shift /**< SYNC1 shift time [ns]. */
         );
 
 /** Add an SDO configuration.
@@ -1192,11 +1376,14 @@
  * friends instead.
  *
  * This is the generic function for adding an SDO configuration. Please note
- * that the this function does not do any endianess correction. If
+ * that the this function does not do any endianness correction. If
  * datatype-specific functions are needed (that automatically correct the
- * endianess), have a look at ecrt_slave_config_sdo8(),
+ * endianness), have a look at ecrt_slave_config_sdo8(),
  * ecrt_slave_config_sdo16() and ecrt_slave_config_sdo32().
  *
+ * This method has to be called in non-realtime context before
+ * ecrt_master_activate().
+ *
  * \retval  0 Success.
  * \retval <0 Error code.
  */
@@ -1210,6 +1397,9 @@
 
 /** Add a configuration value for an 8-bit SDO.
  *
+ * This method has to be called in non-realtime context before
+ * ecrt_master_activate().
+ *
  * \see ecrt_slave_config_sdo().
  *
  * \retval  0 Success.
@@ -1224,6 +1414,9 @@
 
 /** Add a configuration value for a 16-bit SDO.
  *
+ * This method has to be called in non-realtime context before
+ * ecrt_master_activate().
+ *
  * \see ecrt_slave_config_sdo().
  *
  * \retval  0 Success.
@@ -1238,6 +1431,9 @@
 
 /** Add a configuration value for a 32-bit SDO.
  *
+ * This method has to be called in non-realtime context before
+ * ecrt_master_activate().
+ *
  * \see ecrt_slave_config_sdo().
  *
  * \retval  0 Success.
@@ -1255,6 +1451,9 @@
  * The SDO data are transferred via CompleteAccess. Data for the first
  * subindex (0) have to be included.
  *
+ * This method has to be called in non-realtime context before
+ * ecrt_master_activate().
+ *
  * \see ecrt_slave_config_sdo().
  *
  * \retval  0 Success.
@@ -1267,10 +1466,67 @@
         size_t size /**< Size of the \a data. */
         );
 
+/** Set the size of the CoE emergency ring buffer.
+ *
+ * The initial size is zero, so all messages will be dropped. This method can
+ * be called even after master activation, but it will clear the ring buffer!
+ *
+ * This method has to be called in non-realtime context before
+ * ecrt_master_activate().
+ *
+ * \return 0 on success, or negative error code.
+ */
+int ecrt_slave_config_emerg_size(
+        ec_slave_config_t *sc, /**< Slave configuration. */
+        size_t elements /**< Number of records of the CoE emergency ring. */
+        );
+
+/** Read and remove one record from the CoE emergency ring buffer.
+ *
+ * A record consists of 8 bytes:
+ *
+ * Byte 0-1: Error code (little endian)
+ * Byte   2: Error register
+ * Byte 3-7: Data
+ *
+ * \return 0 on success (record popped), or negative error code (i. e.
+ * -ENOENT, if ring is empty).
+ */
+int ecrt_slave_config_emerg_pop(
+        ec_slave_config_t *sc, /**< Slave configuration. */
+        uint8_t *target /**< Pointer to target memory (at least
+                          EC_COE_EMERGENCY_MSG_SIZE bytes). */
+        );
+
+/** Clears CoE emergency ring buffer and the overrun counter.
+ *
+ * \return 0 on success, or negative error code.
+ */
+int ecrt_slave_config_emerg_clear(
+        ec_slave_config_t *sc /**< Slave configuration. */
+        );
+
+/** Read the number of CoE emergency overruns.
+ *
+ * The overrun counter will be incremented when a CoE emergency message could
+ * not be stored in the ring buffer and had to be dropped. Call
+ * ecrt_slave_config_emerg_clear() to reset the counter.
+ *
+ * \return Number of overruns since last clear, or negative error code.
+ */
+int ecrt_slave_config_emerg_overruns(
+        ec_slave_config_t *sc /**< Slave configuration. */
+        );
+
 /** Create an SDO request to exchange SDOs during realtime operation.
  *
  * The created SDO request object is freed automatically when the master is
  * released.
+ *
+ * This method has to be called in non-realtime context before
+ * ecrt_master_activate().
+ *
+ * \return New SDO request, or NULL on error.
  */
 ec_sdo_request_t *ecrt_slave_config_create_sdo_request(
         ec_slave_config_t *sc, /**< Slave configuration. */
@@ -1288,12 +1544,36 @@
  *
  * The created VoE handler object is freed automatically when the master is
  * released.
+ *
+ * This method has to be called in non-realtime context before
+ * ecrt_master_activate().
+ *
+ * \return New VoE handler, or NULL on error.
  */
 ec_voe_handler_t *ecrt_slave_config_create_voe_handler(
         ec_slave_config_t *sc, /**< Slave configuration. */
         size_t size /**< Data size to reserve. */
         );
 
+/** Create a register request to exchange EtherCAT register contents during
+ * realtime operation.
+ *
+ * This interface should not be used to take over master functionality,
+ * instead it is intended for debugging and monitoring reasons.
+ *
+ * The created register request object is freed automatically when the master
+ * is released.
+ *
+ * This method has to be called in non-realtime context before
+ * ecrt_master_activate().
+ *
+ * \return New register request, or NULL on error.
+ */
+ec_reg_request_t *ecrt_slave_config_create_reg_request(
+        ec_slave_config_t *sc, /**< Slave configuration. */
+        size_t size /**< Data size to reserve. */
+        );
+
 /** Outputs the state of the slave configuration.
  *
  * Stores the state information in the given \a state structure. The state
@@ -1316,13 +1596,16 @@
  * activation, but can be repeated subsequently, for example after the slave's
  * power supply failed.
  *
- * The \a idn parameter can be separated into serveral sections:
+ * The \a idn parameter can be separated into several sections:
  *  - Bit 15: Standard data (0) or Product data (1)
  *  - Bit 14 - 12: Parameter set (0 - 7)
  *  - Bit 11 - 0: Data block number (0 - 4095)
  *
- * Please note that the this function does not do any endianess correction.
- * Multi-byte data have to be passed in EtherCAT endianess (little-endian).
+ * Please note that the this function does not do any endianness correction.
+ * Multi-byte data have to be passed in EtherCAT endianness (little-endian).
+ *
+ * This method has to be called in non-realtime context before
+ * ecrt_master_activate().
  *
  * \retval  0 Success.
  * \retval <0 Error code.
@@ -1343,7 +1626,11 @@
 
 /** Registers a bunch of PDO entries for a domain.
  *
- * \todo doc
+ * This method has to be called in non-realtime context before
+ * ecrt_master_activate().
+ *
+ * \see ecrt_slave_config_reg_pdo_entry()
+ *
  * \attention The registration array has to be terminated with an empty
  *            structure, or one with the \a index field set to zero!
  * \return 0 on success, else non-zero.
@@ -1354,16 +1641,16 @@
                                                    registrations. */
         );
 
-#ifdef __KERNEL__
-
 /** Returns the current size of the domain's process data.
  *
- * \return Size of the process data image.
+ * \return Size of the process data image, or a negative error code.
  */
 size_t ecrt_domain_size(
         const ec_domain_t *domain /**< Domain. */
         );
 
+#ifdef __KERNEL__
+
 /** Provide external memory to store the domain's process data.
  *
  * Call this after all PDO entries have been registered and before activating
@@ -1371,6 +1658,10 @@
  *
  * The size of the allocated memory must be at least ecrt_domain_size(), after
  * all PDO entries have been registered.
+ *
+ * This method has to be called in non-realtime context before
+ * ecrt_master_activate().
+ *
  */
 void ecrt_domain_external_memory(
         ec_domain_t *domain, /**< Domain. */
@@ -1433,6 +1724,18 @@
  * SDO request methods.
  ****************************************************************************/
 
+/** Set the SDO index and subindex.
+ *
+ * \attention If the SDO index and/or subindex is changed while
+ * ecrt_sdo_request_state() returns EC_REQUEST_BUSY, this may lead to
+ * unexpected results.
+ */
+void ecrt_sdo_request_index(
+        ec_sdo_request_t *req, /**< SDO request. */
+        uint16_t index, /**< SDO index. */
+        uint8_t subindex /**< SDO subindex. */
+        );
+
 /** Set the timeout for an SDO request.
  *
  * If the request cannot be processed in the specified time, if will be marked
@@ -1503,7 +1806,7 @@
 /** Schedule an SDO write operation.
  *
  * \attention This method may not be called while ecrt_sdo_request_state()
- * returns EC_SDO_REQUEST_BUSY.
+ * returns EC_REQUEST_BUSY.
  */
 void ecrt_sdo_request_write(
         ec_sdo_request_t *req /**< SDO request. */
@@ -1512,11 +1815,11 @@
 /** Schedule an SDO read operation.
  *
  * \attention This method may not be called while ecrt_sdo_request_state()
- * returns EC_SDO_REQUEST_BUSY.
+ * returns EC_REQUEST_BUSY.
  *
  * \attention After calling this function, the return value of
  * ecrt_sdo_request_data() must be considered as invalid while
- * ecrt_sdo_request_state() returns EC_SDO_REQUEST_BUSY.
+ * ecrt_sdo_request_state() returns EC_REQUEST_BUSY.
  */
 void ecrt_sdo_request_read(
         ec_sdo_request_t *req /**< SDO request. */
@@ -1643,8 +1946,8 @@
 
 /** Execute the handler.
  *
- * This method executes the VoE handler. It has to be called in every bus cycle
- * as long as it returns EC_REQUEST_BUSY.
+ * This method executes the VoE handler. It has to be called in every bus
+ * cycle as long as it returns EC_REQUEST_BUSY.
  *
  * \return Handler state.
  */
@@ -1652,6 +1955,75 @@
     ec_voe_handler_t *voe /**< VoE handler. */
     );
 
+/*****************************************************************************
+ * Register request methods.
+ ****************************************************************************/
+
+/** Access to the register request's data.
+ *
+ * This function returns a pointer to the request's internal memory.
+ *
+ * - After a read operation was successful, integer data can be evaluated
+ *   using the EC_READ_*() macros as usual. Example:
+ *   \code
+ *   uint16_t value = EC_READ_U16(ecrt_reg_request_data(reg_request)));
+ *   \endcode
+ * - If a write operation shall be triggered, the data have to be written to
+ *   the internal memory. Use the EC_WRITE_*() macros, if you are writing
+ *   integer data. Be sure, that the data fit into the memory. The memory size
+ *   is a parameter of ecrt_slave_config_create_reg_request().
+ *   \code
+ *   EC_WRITE_U16(ecrt_reg_request_data(reg_request), 0xFFFF);
+ *   \endcode
+ *
+ * \return Pointer to the internal memory.
+ */
+uint8_t *ecrt_reg_request_data(
+        ec_reg_request_t *req /**< Register request. */
+        );
+
+/** Get the current state of the register request.
+ *
+ * \return Request state.
+ */
+#ifdef __KERNEL__
+ec_request_state_t ecrt_reg_request_state(
+        const ec_reg_request_t *req /**< Register request. */
+    );
+#else
+ec_request_state_t ecrt_reg_request_state(
+        ec_reg_request_t *req /**< Register request. */
+    );
+#endif
+
+/** Schedule an register write operation.
+ *
+ * \attention This method may not be called while ecrt_reg_request_state()
+ * returns EC_REQUEST_BUSY.
+ *
+ * \attention The \a size parameter is truncated to the size given at request
+ * creation.
+ */
+void ecrt_reg_request_write(
+        ec_reg_request_t *req, /**< Register request. */
+        uint16_t address, /**< Register address. */
+        size_t size /**< Size to write. */
+        );
+
+/** Schedule a register read operation.
+ *
+ * \attention This method may not be called while ecrt_reg_request_state()
+ * returns EC_REQUEST_BUSY.
+ *
+ * \attention The \a size parameter is truncated to the size given at request
+ * creation.
+ */
+void ecrt_reg_request_read(
+        ec_reg_request_t *req, /**< Register request. */
+        uint16_t address, /**< Register address. */
+        size_t size /**< Size to write. */
+        );
+
 /*****************************************************************************/
 
 #ifdef __cplusplus