diff --git a/Doxyfile.in b/Doxyfile.in index 2fab9b99..5a888750 100644 --- a/Doxyfile.in +++ b/Doxyfile.in @@ -193,7 +193,8 @@ TAB_SIZE = 4 # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. -ALIASES = +ALIASES = \ + "apiusage{1}=@par API Usage^^@ref apiusage \"\1\"" # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding diff --git a/include/ecrt.h b/include/ecrt.h index 0d545dc5..3ab462fb 100644 --- a/include/ecrt.h +++ b/include/ecrt.h @@ -24,19 +24,13 @@ * * EtherCAT master application interface. * - * \defgroup ApplicationInterface EtherCAT Application Interface (non-RT) + * \defgroup ApplicationInterface EtherCAT Application Interface + * + * EtherCAT interface for realtime applications. This interface is designed + * for realtime modules that want to use EtherCAT. There are functions to + * request a master, to map process data, to communicate with slaves via CoE + * and to configure and activate the bus. * - * Interface for configuring the EtherCAT master for realtime applications. - * There are functions to request a master, to map process data, to - * communicate with slaves via CoE and to configure and activate the network. - * All methods in this group should be used before the application switches to - * operation (real-time) mode by calling ecrt_master_activate(). After that, - * only calls to the functions in \ref ApplicationInterfaceRT are allowed. The - * real-time operation mode finishes by calling ecrt_master_deactivate(). Many - * functions in this group are blocking and/or they acquire locks. Do not use - * these functions in non-userspace contexts, e. g. in RTAI/Xenomai Real-Time - * tasks or in atomic/softirq/tasklet context in kernel modules. You have been - * warned. * * Changes in version 1.6.0: * @@ -138,17 +132,6 @@ * ad-hoc via the user-space library. * - Added ecrt_master_reset() to initiate retrying to configure slaves. * - * \defgroup ApplicationInterfaceRT EtherCAT Application Interface (RT) - * - * Interface to interact with the EtherCAT master with real-time contraints. - * - * After configuring the EtherCAT master the application switches to the - * operation mode by calling ecrt_master_activate(). In operation mode, - * do not call other methods than these listed in this group. Many of the - * methods in \ref ApplicationInterface are blocking, calling these in - * real-time context mode will result in a deadlock. - * - * \addtogroup ApplicationInterface * @{ */ @@ -645,6 +628,8 @@ extern "C" { #endif /** Returns the version magic of the realtime interface. + * + * \apiusage{master_any,rt_safe} * * \return Value of ECRT_VERSION_MAGIC() at EtherCAT master compile time. */ @@ -663,6 +648,8 @@ EC_PUBLIC_API unsigned int ecrt_version_magic(void); * The first master has index 0, the n-th master has index n - 1. The number * of masters has to be specified when loading the master module. * + * \apiusage{master_idle,blocking} + * * \return Pointer to the reserved master, otherwise \a NULL. */ EC_PUBLIC_API ec_master_t *ecrt_request_master( @@ -680,6 +667,8 @@ EC_PUBLIC_API ec_master_t *ecrt_request_master( * * For convenience, the function ecrt_request_master() can be used. * + * \apiusage{master_idle,blocking} + * * \return Pointer to the opened master, otherwise \a NULL. */ EC_PUBLIC_API ec_master_t *ecrt_open_master( @@ -697,6 +686,8 @@ EC_PUBLIC_API ec_master_t *ecrt_open_master( * realtime context. * * If the master was activated, ecrt_master_deactivate() is called internally. + * + * \apiusage{master_any,blocking} */ EC_PUBLIC_API void ecrt_release_master( ec_master_t *master /**< EtherCAT master */ @@ -713,6 +704,8 @@ EC_PUBLIC_API void ecrt_release_master( * Before an application can use PDO/domain registration functions or SDO * request functions on the master, it has to reserve one for exclusive use. * + * \apiusage{master_idle,blocking} + * * \return 0 in case of success, else < 0 */ EC_PUBLIC_API int ecrt_master_reserve( @@ -738,6 +731,8 @@ EC_PUBLIC_API int ecrt_master_reserve( * 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. * + * \apiusage{master_idle,blocking} + * * \attention This method has to be called before ecrt_master_activate(). */ void ecrt_master_callbacks( @@ -760,6 +755,8 @@ void ecrt_master_callbacks( * This method allocates memory and should be called in non-realtime context * before ecrt_master_activate(). * + * \apiusage{master_idle,blocking} + * * \return Pointer to the new domain on success, else NULL. */ EC_PUBLIC_API ec_domain_t *ecrt_master_create_domain( @@ -793,6 +790,8 @@ EC_PUBLIC_API ec_domain_t *ecrt_master_create_domain( * This method allocates memory and should be called in non-realtime context * before ecrt_master_activate(). * + * \apiusage{master_idle,blocking} + * * \retval >0 Pointer to the slave configuration structure. * \retval NULL in the error case. */ @@ -810,6 +809,8 @@ EC_PUBLIC_API ec_slave_config_t *ecrt_master_slave_config( * configuration pointer is NULL, then the first slave with DC functionality * will provide the reference clock. * + * \apiusage{master_idle,blocking} + * * \return 0 on success, otherwise negative error code. */ EC_PUBLIC_API int ecrt_master_select_reference_clock( @@ -820,8 +821,9 @@ EC_PUBLIC_API int ecrt_master_select_reference_clock( /** Obtains master information. * - * No memory is allocated on the heap in - * this function. + * No memory is allocated on the heap in this function. + * + * \apiusage{master_any,rt_safe} * * \attention The pointer to this structure must point to a valid variable. * @@ -837,9 +839,9 @@ EC_PUBLIC_API int ecrt_master( * * No memory is allocated on the heap in this function. * - * \attention The pointer to this structure must point to a valid variable. + * \apiusage{master_any,rt_safe} * - * \ingroup ApplicationInterfaceRT + * \attention The pointer to this structure must point to a valid variable. * * \return 0 in case of success, else < 0 */ @@ -855,6 +857,8 @@ EC_PUBLIC_API int ecrt_master_scan_progress( * information is stored in a structure. No memory is allocated on the heap in * this function. * + * \apiusage{master_any,blocking} + * * \attention The pointer to this structure must point to a valid variable. * * \return 0 in case of success, else < 0 @@ -874,6 +878,8 @@ EC_PUBLIC_API int ecrt_master_get_slave( * manager. The \a pdos field of the return value is left empty. Use * ecrt_master_get_pdo() to get the PDO information. * + * \apiusage{master_any,blocking} + * * \return zero on success, else non-zero */ EC_PUBLIC_API int ecrt_master_get_sync_manager( @@ -891,6 +897,8 @@ EC_PUBLIC_API int ecrt_master_get_sync_manager( * value is left empty. Use ecrt_master_get_pdo_entry() to get the PDO * entry information. * + * \apiusage{master_any,blocking} + * * \retval zero on success, else non-zero */ EC_PUBLIC_API int ecrt_master_get_pdo( @@ -907,6 +915,8 @@ EC_PUBLIC_API int ecrt_master_get_pdo( * Fills a given ec_pdo_entry_info_t structure with the attributes of a * currently mapped PDO entry of the given PDO. * + * \apiusage{master_any,blocking} + * * \retval zero on success, else non-zero */ EC_PUBLIC_API int ecrt_master_get_pdo_entry( @@ -927,6 +937,8 @@ EC_PUBLIC_API int ecrt_master_get_pdo_entry( * until the request has been processed and may not be called in realtime * context. * + * \apiusage{master_any,blocking} + * * \retval 0 Success. * \retval <0 Error code. */ @@ -947,6 +959,8 @@ EC_PUBLIC_API int ecrt_master_sdo_download( * until the request has been processed and may not be called in realtime * context. * + * \apiusage{master_any,blocking} + * * \retval 0 Success. * \retval <0 Error code. */ @@ -965,6 +979,8 @@ EC_PUBLIC_API int ecrt_master_sdo_download_complete( * until the request has been processed and may not be called in realtime * context. * + * \apiusage{master_any,blocking} + * * \retval 0 Success. * \retval <0 Error code. */ @@ -984,6 +1000,8 @@ EC_PUBLIC_API int ecrt_master_sdo_upload( * Starts writing an IDN and blocks until the request was processed, or an * error occurred. * + * \apiusage{master_any,blocking} + * * \retval 0 Success. * \retval <0 Error code. */ @@ -1003,6 +1021,8 @@ EC_PUBLIC_API int ecrt_master_write_idn( * Starts reading an IDN and blocks until the request was processed, or an * error occurred. * + * \apiusage{master_any,blocking} + * * \retval 0 Success. * \retval <0 Error code. */ @@ -1027,6 +1047,8 @@ EC_PUBLIC_API int ecrt_master_read_idn( * members. It tells the master state machine that the configuration is * now to be applied to the network. * + * \apiusage{master_idle,blocking} + * * \attention After this function has been called, the realtime application is * in charge of cyclically calling ecrt_master_send() and * ecrt_master_receive() to ensure network communication. Before calling this @@ -1048,6 +1070,8 @@ EC_PUBLIC_API int ecrt_master_activate( * ecrt_slave_config_create_voe_handler() are freed, so pointers to them * become invalid. * + * \apiusage{master_op,blocking} + * * This method should not be called in realtime context. * \return 0 on success, otherwise negative error code. * \retval 0 Success. @@ -1064,6 +1088,8 @@ EC_PUBLIC_API int ecrt_master_deactivate( * --enable-hrtimers, this is used to calculate the scheduling of the master * thread. * + * \apiusage{master_idle,blocking} + * * \retval 0 on success. * \retval <0 Error code. */ @@ -1080,7 +1106,8 @@ EC_PUBLIC_API int ecrt_master_set_send_interval( * Has to be called cyclically by the application after ecrt_master_activate() * has returned. * - * \ingroup ApplicationInterfaceRT + * \apiusage{master_op,rt_safe} + * * \return Zero on success, otherwise negative error code. */ EC_PUBLIC_API int ecrt_master_send( @@ -1097,7 +1124,8 @@ EC_PUBLIC_API int ecrt_master_send( * Has to be called cyclically by the realtime application after * ecrt_master_activate() has returned. * - * \ingroup ApplicationInterfaceRT + * \apiusage{master_op,rt_safe} + * * \return Zero on success, otherwise negative error code. */ EC_PUBLIC_API int ecrt_master_receive( @@ -1109,6 +1137,9 @@ EC_PUBLIC_API int ecrt_master_receive( * * This method has to be called in the send callback function passed via * ecrt_master_callbacks() to allow the sending of non-application datagrams. + * + * \apiusage{master_op,rt_safe} + * * \return Zero on success, otherwise negative error code. * \retval -EAGAIN Lock could not be acquired, try again later. */ @@ -1123,6 +1154,9 @@ int ecrt_master_send_ext( * * This method returns a global state. For the link-specific states in a * redundant network topology, use the ecrt_master_link_state() method. + * + * \apiusage{master_any,rt_safe} + * * \return Zero on success, otherwise negative error code. */ EC_PUBLIC_API int ecrt_master_state( @@ -1134,6 +1168,8 @@ EC_PUBLIC_API int ecrt_master_state( * * Stores the link state information in the given \a state structure. * + * \apiusage{master_any,rt_safe} + * * \return Zero on success, otherwise negative error code. */ EC_PUBLIC_API int ecrt_master_link_state( @@ -1154,6 +1190,7 @@ EC_PUBLIC_API int ecrt_master_link_state( * the slaves' SYNC0/1 interrupts. It should be called constantly at the same * point of the realtime cycle. So it is recommended to call it at the start * of the calculations to avoid deviancies due to changing execution times. + * Avoid calling this method before the realtime cycle is established. * * The time is used when setting the slaves' System Time Offset and * Cyclic Operation Start Time registers and when synchronizing the @@ -1164,7 +1201,8 @@ EC_PUBLIC_API int ecrt_master_link_state( * epoch time can be done with the EC_TIMEVAL2NANO() macro, but is not * necessary, since the absolute value is not of any interest. * - * \ingroup ApplicationInterfaceRT + * \apiusage{master_op,rt_safe} + * * \return Zero on success, otherwise negative error code. */ EC_PUBLIC_API int ecrt_master_application_time( @@ -1177,7 +1215,8 @@ EC_PUBLIC_API int ecrt_master_application_time( * The reference clock will by synchronized to the application time provided * by the last call off ecrt_master_application_time(). * - * \ingroup ApplicationInterfaceRT + * \apiusage{master_op,rt_safe} + * * \return Zero on success, otherwise negative error code. * \retval 0 Success. * \retval -ENXIO No reference clock found. @@ -1194,7 +1233,8 @@ EC_PUBLIC_API int ecrt_master_sync_reference_clock( * Has to be called by the application after ecrt_master_activate() * has returned. * - * \ingroup ApplicationInterfaceRT + * \apiusage{master_op,rt_safe} + * * \return Zero on success, otherwise negative error code. * \retval 0 Success. * \retval -ENXIO No reference clock found. @@ -1211,7 +1251,8 @@ EC_PUBLIC_API int ecrt_master_sync_reference_clock_to( * Has to be called by the application after ecrt_master_activate() * has returned. * - * \ingroup ApplicationInterfaceRT + * \apiusage{master_op,rt_safe} + * * \return 0 on success, otherwise negative error code. * \retval 0 Success. * \retval -ENXIO No reference clock found. @@ -1236,6 +1277,8 @@ EC_PUBLIC_API int ecrt_master_sync_slave_clocks( * activation), when the ecrt_master_sync_slave_clocks() method is called * cyclically. * + * \apiusage{master_op,rt_safe} + * * \retval 0 success, system time was written into \a time. * \retval -ENXIO No reference clock found. * \retval -EIO Slave synchronization datagram was not received. @@ -1251,7 +1294,9 @@ EC_PUBLIC_API int ecrt_master_reference_clock_time( * 0x092c) to get an upper estimation of the DC synchrony. The result can be * checked with the ecrt_master_sync_monitor_process() method. * - * \ingroup ApplicationInterfaceRT + * \apiusage{master_op,rt_safe} + * + * \return Zero on success, otherwise a negative error code. */ EC_PUBLIC_API int ecrt_master_sync_monitor_queue( ec_master_t *master /**< EtherCAT master. */ @@ -1263,9 +1308,10 @@ EC_PUBLIC_API int ecrt_master_sync_monitor_queue( * ecrt_master_sync_monitor_queue(), the result can be queried with this * method. * - * \ingroup ApplicationInterfaceRT + * \apiusage{master_op,rt_safe} * - * \return Upper estimation of the maximum time difference in ns. + * \return Upper estimation of the maximum time difference in ns, -1 on error. + * \retval (uint32_t)-1 Error. */ EC_PUBLIC_API uint32_t ecrt_master_sync_monitor_process( const ec_master_t *master /**< EtherCAT master. */ @@ -1281,7 +1327,8 @@ EC_PUBLIC_API uint32_t ecrt_master_sync_monitor_process( * Calling this method only makes sense in realtime context (after * activation), because slaves will not be configured before. * - * \ingroup ApplicationInterfaceRT + * \apiusage{master_op,rt_safe} + * * \return 0 on success, otherwise negative error code. */ EC_PUBLIC_API int ecrt_master_reset( @@ -1300,6 +1347,8 @@ EC_PUBLIC_API int ecrt_master_reset( * This method has to be called in non-realtime context before * ecrt_master_activate(). * + * \apiusage{master_idle,blocking} + * * \return zero on success, else non-zero */ EC_PUBLIC_API int ecrt_slave_config_sync_manager( @@ -1315,6 +1364,8 @@ EC_PUBLIC_API int ecrt_slave_config_sync_manager( * This method has to be called in non-realtime context before * ecrt_master_activate(). * + * \apiusage{master_idle,blocking} + * * \return 0 on success, otherwise negative error code. */ EC_PUBLIC_API int ecrt_slave_config_watchdog( @@ -1335,6 +1386,8 @@ EC_PUBLIC_API int ecrt_slave_config_watchdog( * This method has to be called in non-realtime context before * ecrt_master_activate(). * + * \apiusage{master_idle,blocking} + * * \see ecrt_slave_config_pdos() * \return zero on success, else non-zero */ @@ -1354,6 +1407,8 @@ EC_PUBLIC_API int ecrt_slave_config_pdo_assign_add( * This method has to be called in non-realtime context before * ecrt_master_activate(). * + * \apiusage{master_idle,blocking} + * * \see ecrt_slave_config_pdos() * \return 0 on success, otherwise negative error code. */ @@ -1368,6 +1423,8 @@ EC_PUBLIC_API int ecrt_slave_config_pdo_assign_clear( * This method has to be called in non-realtime context before * ecrt_master_activate(). * + * \apiusage{master_idle,blocking} + * * \see ecrt_slave_config_pdos() * \return zero on success, else non-zero */ @@ -1389,6 +1446,8 @@ EC_PUBLIC_API int ecrt_slave_config_pdo_mapping_add( * This method has to be called in non-realtime context before * ecrt_master_activate(). * + * \apiusage{master_idle,blocking} + * * \see ecrt_slave_config_pdos() * \return 0 on success, otherwise negative error code. */ @@ -1466,6 +1525,8 @@ EC_PUBLIC_API int ecrt_slave_config_pdo_mapping_clear( * This method has to be called in non-realtime context before * ecrt_master_activate(). * + * \apiusage{master_idle,blocking} + * * \return zero on success, else non-zero */ EC_PUBLIC_API int ecrt_slave_config_pdos( @@ -1491,6 +1552,8 @@ EC_PUBLIC_API int ecrt_slave_config_pdos( * This method has to be called in non-realtime context before * ecrt_master_activate(). * + * \apiusage{master_idle,blocking} + * * \retval >=0 Success: Offset of the PDO entry's process data. * \retval <0 Error code. */ @@ -1513,6 +1576,8 @@ EC_PUBLIC_API int ecrt_slave_config_reg_pdo_entry( * This method has to be called in non-realtime context before * ecrt_master_activate(). * + * \apiusage{master_idle,blocking} + * * \retval >=0 Success: Offset of the PDO entry's process data. * \retval <0 Error code. */ @@ -1538,6 +1603,8 @@ EC_PUBLIC_API int ecrt_slave_config_reg_pdo_entry_pos( * This method has to be called in non-realtime context before * ecrt_master_activate(). * + * \apiusage{master_idle,blocking} + * * \attention The \a sync1_shift time is ignored. * \return 0 on success, otherwise negative error code. */ @@ -1572,6 +1639,8 @@ EC_PUBLIC_API int ecrt_slave_config_dc( * This method has to be called in non-realtime context before * ecrt_master_activate(). * + * \apiusage{master_idle,blocking} + * * \retval 0 Success. * \retval <0 Error code. */ @@ -1590,6 +1659,8 @@ EC_PUBLIC_API int ecrt_slave_config_sdo( * * \see ecrt_slave_config_sdo(). * + * \apiusage{master_idle,blocking} + * * \retval 0 Success. * \retval <0 Error code. */ @@ -1607,6 +1678,8 @@ EC_PUBLIC_API int ecrt_slave_config_sdo8( * * \see ecrt_slave_config_sdo(). * + * \apiusage{master_idle,blocking} + * * \retval 0 Success. * \retval <0 Error code. */ @@ -1624,6 +1697,8 @@ EC_PUBLIC_API int ecrt_slave_config_sdo16( * * \see ecrt_slave_config_sdo(). * + * \apiusage{master_idle,blocking} + * * \retval 0 Success. * \retval <0 Error code. */ @@ -1644,6 +1719,8 @@ EC_PUBLIC_API int ecrt_slave_config_sdo32( * * \see ecrt_slave_config_sdo(). * + * \apiusage{master_idle,blocking} + * * \retval 0 Success. * \retval <0 Error code. */ @@ -1662,6 +1739,8 @@ EC_PUBLIC_API int ecrt_slave_config_complete_sdo( * This method has to be called in non-realtime context before * ecrt_master_activate(). * + * \apiusage{master_idle,blocking} + * * \return 0 on success, or negative error code. */ EC_PUBLIC_API int ecrt_slave_config_emerg_size( @@ -1683,7 +1762,7 @@ EC_PUBLIC_API int ecrt_slave_config_emerg_size( * \return 0 on success (record popped), or negative error code (i. e. * -ENOENT, if ring is empty). * - * \ingroup ApplicationInterfaceRT + * \apiusage{master_op,any_context} */ EC_PUBLIC_API int ecrt_slave_config_emerg_pop( ec_slave_config_t *sc, /**< Slave configuration. */ @@ -1696,9 +1775,10 @@ EC_PUBLIC_API int ecrt_slave_config_emerg_pop( * Calling this method makes only sense in realtime context (after master * activation). * + * \apiusage{master_op,any_context} + * * \return 0 on success, or negative error code. * - * \ingroup ApplicationInterfaceRT */ EC_PUBLIC_API int ecrt_slave_config_emerg_clear( ec_slave_config_t *sc /**< Slave configuration. */ @@ -1713,9 +1793,10 @@ EC_PUBLIC_API int ecrt_slave_config_emerg_clear( * Calling this method makes only sense in realtime context (after master * activation). * + * \apiusage{master_op,any_context} + * * \return Number of overruns since last clear, or negative error code. * - * \ingroup ApplicationInterfaceRT */ EC_PUBLIC_API int ecrt_slave_config_emerg_overruns( const ec_slave_config_t *sc /**< Slave configuration. */ @@ -1729,6 +1810,8 @@ EC_PUBLIC_API int ecrt_slave_config_emerg_overruns( * This method has to be called in non-realtime context before * ecrt_master_activate(). * + * \apiusage{master_idle,blocking} + * * \return New SDO request, or NULL on error. */ EC_PUBLIC_API ec_sdo_request_t *ecrt_slave_config_create_sdo_request( @@ -1746,6 +1829,8 @@ EC_PUBLIC_API ec_sdo_request_t *ecrt_slave_config_create_sdo_request( * This method has to be called in non-realtime context before * ecrt_master_activate(). * + * \apiusage{master_idle,blocking} + * * \return New SoE request, or NULL on error. */ EC_PUBLIC_API ec_soe_request_t *ecrt_slave_config_create_soe_request( @@ -1768,6 +1853,8 @@ EC_PUBLIC_API ec_soe_request_t *ecrt_slave_config_create_soe_request( * This method has to be called in non-realtime context before * ecrt_master_activate(). * + * \apiusage{master_idle,blocking} + * * \return New VoE handler, or NULL on error. */ EC_PUBLIC_API ec_voe_handler_t *ecrt_slave_config_create_voe_handler( @@ -1787,6 +1874,8 @@ EC_PUBLIC_API ec_voe_handler_t *ecrt_slave_config_create_voe_handler( * This method has to be called in non-realtime context before * ecrt_master_activate(). * + * \apiusage{master_idle,blocking} + * * \return New register request, or NULL on error. */ EC_PUBLIC_API ec_reg_request_t *ecrt_slave_config_create_reg_request( @@ -1803,10 +1892,13 @@ EC_PUBLIC_API ec_reg_request_t *ecrt_slave_config_create_reg_request( * \attention If the state of process data exchange shall be monitored in * realtime, ecrt_domain_state() should be used. * + * \apiusage{master_op,rt_safe} + * * This method is meant to be called in realtime context (after master * activation). * - * \ingroup ApplicationInterfaceRT + * \retval 0 Success. + * \retval <0 Error code. */ EC_PUBLIC_API int ecrt_slave_config_state( const ec_slave_config_t *sc, /**< Slave configuration */ @@ -1832,6 +1924,8 @@ EC_PUBLIC_API int ecrt_slave_config_state( * This method has to be called in non-realtime context before * ecrt_master_activate(). * + * \apiusage{master_idle,blocking} + * * \retval 0 Success. * \retval <0 Error code. */ @@ -1864,6 +1958,8 @@ EC_PUBLIC_API int ecrt_slave_config_idn( * This method has to be called in non-realtime context before * ecrt_master_activate(). * + * \apiusage{master_idle,blocking} + * * \retval 0 Success. * \retval <0 Error code. */ @@ -1881,6 +1977,8 @@ EC_PUBLIC_API int ecrt_slave_config_flag( * The MAC address is stored in the slave configuration object and will be * written to the slave during the configuration process. * + * \apiusage{master_idle,blocking} + * * \retval 0 Success. * \retval <0 Error code. */ @@ -1917,6 +2015,8 @@ EC_PUBLIC_API int ecrt_slave_config_eoe_mac_address( * \endcode * * + * \apiusage{master_idle,blocking} + * * \retval 0 Success. * \retval <0 Error code. */ @@ -1939,6 +2039,8 @@ EC_PUBLIC_API int ecrt_slave_config_eoe_ip_address( * See ecrt_slave_config_eoe_ip_address() on how to convert string-coded masks * to `struct in_addr`. * + * \apiusage{master_idle,blocking} + * * \retval 0 Success. * \retval <0 Error code. */ @@ -1961,6 +2063,8 @@ EC_PUBLIC_API int ecrt_slave_config_eoe_subnet_mask( * See ecrt_slave_config_eoe_ip_address() on how to convert string-coded IPv4 * addresses to `struct in_addr`. * + * \apiusage{master_idle,blocking} + * * \retval 0 Success. * \retval <0 Error code. */ @@ -1984,6 +2088,8 @@ EC_PUBLIC_API int ecrt_slave_config_eoe_default_gateway( * See ecrt_slave_config_eoe_ip_address() on how to convert string-coded IPv4 * addresses to `struct in_addr`. * + * \apiusage{master_idle,blocking} + * * \retval 0 Success. * \retval <0 Error code. */ @@ -2003,6 +2109,8 @@ EC_PUBLIC_API int ecrt_slave_config_eoe_dns_address( * The maximum size of the host name is 32 bytes (including the zero * terminator). * + * \apiusage{master_idle,blocking} + * * \retval 0 Success. * \retval <0 Error code. */ @@ -2022,6 +2130,8 @@ EC_PUBLIC_API int ecrt_slave_config_eoe_hostname( * This method has to be called in non-realtime context before * ecrt_master_activate(). * + * \apiusage{master_idle,blocking} + * * \retval 0 Success. * \retval <0 Error code. */ @@ -2045,6 +2155,9 @@ EC_PUBLIC_API int ecrt_slave_config_state_timeout( * * \attention The registration array has to be terminated with an empty * structure, or one with the \a index field set to zero! + * + * \apiusage{master_idle,blocking} + * * \return 0 on success, else non-zero. */ EC_PUBLIC_API int ecrt_domain_reg_pdo_entry_list( @@ -2054,6 +2167,10 @@ EC_PUBLIC_API int ecrt_domain_reg_pdo_entry_list( ); /** Returns the current size of the domain's process data. + * + * The domain size is calculated after master activation. + * + * \apiusage{master_op,rt_safe} * * \return Size of the process data image, or a negative error code. */ @@ -2074,6 +2191,7 @@ EC_PUBLIC_API size_t ecrt_domain_size( * This method has to be called in non-realtime context before * ecrt_master_activate(). * + * \apiusage{master_idle,blocking} */ void ecrt_domain_external_memory( ec_domain_t *domain, /**< Domain. */ @@ -2094,6 +2212,8 @@ void ecrt_domain_external_memory( * - In userspace context: This method has to be called after * ecrt_master_activate() to get the mapped domain process data memory. * + * \apiusage{master_op,rt_safe} + * * \return Pointer to the process data memory. */ EC_PUBLIC_API uint8_t *ecrt_domain_data( @@ -2107,7 +2227,8 @@ EC_PUBLIC_API uint8_t *ecrt_domain_data( * is expected to receive the domain datagrams in order to make * ecrt_domain_state() return the result of the last process data exchange. * - * \ingroup ApplicationInterfaceRT + * \apiusage{master_op,rt_safe} + * * \return 0 on success, otherwise negative error code. */ EC_PUBLIC_API int ecrt_domain_process( @@ -2119,7 +2240,8 @@ EC_PUBLIC_API int ecrt_domain_process( * Call this function to mark the domain's datagrams for exchanging at the * next call of ecrt_master_send(). * - * \ingroup ApplicationInterfaceRT + * \apiusage{master_op,rt_safe} + * * \return 0 on success, otherwise negative error code. */ EC_PUBLIC_API int ecrt_domain_queue( @@ -2132,7 +2254,8 @@ EC_PUBLIC_API int ecrt_domain_queue( * * Using this method, the process data exchange can be monitored in realtime. * - * \ingroup ApplicationInterfaceRT + * \apiusage{master_op,rt_safe} + * * \return 0 on success, otherwise negative error code. */ EC_PUBLIC_API int ecrt_domain_state( @@ -2155,7 +2278,8 @@ EC_PUBLIC_API int ecrt_domain_state( * activation). To initialize the SDO request, the index and subindex can be * set via ecrt_slave_config_create_sdo_request(). * - * \ingroup ApplicationInterfaceRT + * \apiusage{master_op,rt_safe} + * * \return 0 on success, otherwise negative error code. */ EC_PUBLIC_API int ecrt_sdo_request_index( @@ -2174,6 +2298,9 @@ EC_PUBLIC_API int ecrt_sdo_request_index( * * The timeout should be defined in non-realtime context, but can also be * changed afterwards. + * + * \apiusage{master_any,rt_safe} + * * \return 0 on success, otherwise negative error code. */ EC_PUBLIC_API int ecrt_sdo_request_timeout( @@ -2206,9 +2333,10 @@ EC_PUBLIC_API int ecrt_sdo_request_timeout( * This method is meant to be called in realtime context (after master * activation), but can also be used to initialize data before. * + * \apiusage{master_any,rt_safe} + * * \return Pointer to the internal SDO data memory. * - * \ingroup ApplicationInterfaceRT */ EC_PUBLIC_API uint8_t *ecrt_sdo_request_data( const ec_sdo_request_t *req /**< SDO request. */ @@ -2223,9 +2351,10 @@ EC_PUBLIC_API uint8_t *ecrt_sdo_request_data( * This method is meant to be called in realtime context (after master * activation). * + * \apiusage{master_any,rt_safe} + * * \return SDO data size in bytes. * - * \ingroup ApplicationInterfaceRT */ EC_PUBLIC_API size_t ecrt_sdo_request_data_size( const ec_sdo_request_t *req /**< SDO request. */ @@ -2239,9 +2368,10 @@ EC_PUBLIC_API size_t ecrt_sdo_request_data_size( * This method is meant to be called in realtime context (after master * activation). * + * \apiusage{master_op,rt_safe} + * * \return Request state. * - * \ingroup ApplicationInterfaceRT */ EC_PUBLIC_API ec_request_state_t ecrt_sdo_request_state( #ifdef __KERNEL__ @@ -2258,7 +2388,8 @@ EC_PUBLIC_API ec_request_state_t ecrt_sdo_request_state( * This method is meant to be called in realtime context (after master * activation). * - * \ingroup ApplicationInterfaceRT + * \apiusage{master_op,rt_safe} + * * \return 0 on success, otherwise negative error code. * \retval -EINVAL Invalid input data, e.g. data size == 0. * \retval -ENOBUFS Reserved memory in ecrt_slave_config_create_sdo_request() @@ -2280,7 +2411,8 @@ EC_PUBLIC_API int ecrt_sdo_request_write( * This method is meant to be called in realtime context (after master * activation). * - * \ingroup ApplicationInterfaceRT + * \apiusage{master_op,rt_safe} + * * \return 0 on success, otherwise negative error code. */ EC_PUBLIC_API int ecrt_sdo_request_read( @@ -2301,7 +2433,8 @@ EC_PUBLIC_API int ecrt_sdo_request_read( * activation). To initialize the SoE request, the drive_no and IDN can be * set via ecrt_slave_config_create_soe_request(). * - * \ingroup ApplicationInterfaceRT + * \apiusage{master_op,rt_safe} + * * \return 0 on success, otherwise negative error code. */ EC_PUBLIC_API int ecrt_soe_request_idn( @@ -2320,6 +2453,9 @@ EC_PUBLIC_API int ecrt_soe_request_idn( * * The timeout should be defined in non-realtime context, but can also be * changed afterwards. + * + * \apiusage{master_any,rt_safe} + * * \return 0 on success, otherwise negative error code. */ EC_PUBLIC_API int ecrt_soe_request_timeout( @@ -2352,9 +2488,10 @@ EC_PUBLIC_API int ecrt_soe_request_timeout( * This method is meant to be called in realtime context (after master * activation), but can also be used to initialize data before. * + * \apiusage{master_any,rt_safe} + * * \return Pointer to the internal IDN data memory. * - * \ingroup ApplicationInterfaceRT */ EC_PUBLIC_API uint8_t *ecrt_soe_request_data( const ec_soe_request_t *req /**< SoE request. */ @@ -2366,6 +2503,8 @@ EC_PUBLIC_API uint8_t *ecrt_soe_request_data( * reserved memory. After a read operation the size is set to the size of the * read data. The size is not modified in any other situation. * + * \apiusage{master_any,rt_safe} + * * \return IDN data size in bytes. */ EC_PUBLIC_API size_t ecrt_soe_request_data_size( @@ -2382,7 +2521,7 @@ EC_PUBLIC_API size_t ecrt_soe_request_data_size( * In the user-space implementation, the method fetches the size of the * incoming data, so the request object is not const. * - * \ingroup ApplicationInterfaceRT + * \apiusage{master_op,rt_safe} */ EC_PUBLIC_API ec_request_state_t ecrt_soe_request_state( #ifdef __KERNEL__ @@ -2399,7 +2538,8 @@ EC_PUBLIC_API ec_request_state_t ecrt_soe_request_state( * This method is meant to be called in realtime context (after master * activation). * - * \ingroup ApplicationInterfaceRT + * \apiusage{master_op,rt_safe} + * * \return 0 on success, otherwise negative error code. * \retval -EINVAL Invalid input data, e.g. data size == 0. * \retval -ENOBUFS Reserved memory in ecrt_slave_config_create_soe_request() @@ -2421,7 +2561,8 @@ EC_PUBLIC_API int ecrt_soe_request_write( * This method is meant to be called in realtime context (after master * activation). * - * \ingroup ApplicationInterfaceRT + * \apiusage{master_op,rt_safe} + * * \return 0 on success, otherwise negative error code. */ EC_PUBLIC_API int ecrt_soe_request_read( @@ -2443,7 +2584,8 @@ EC_PUBLIC_API int ecrt_soe_request_read( * activation) to initialize the header data, but it is also safe to * change the header later on in realtime context. * - * \ingroup ApplicationInterfaceRT + * \apiusage{master_any,rt_safe} + * * \return 0 on success, otherwise negative error code. */ EC_PUBLIC_API int ecrt_voe_handler_send_header( @@ -2463,7 +2605,8 @@ EC_PUBLIC_API int ecrt_voe_handler_send_header( * This method is meant to be called in realtime context (after master * activation). * - * \ingroup ApplicationInterfaceRT + * \apiusage{master_op,rt_safe} + * * \return 0 on success, otherwise negative error code. */ EC_PUBLIC_API int ecrt_voe_handler_received_header( @@ -2490,6 +2633,8 @@ EC_PUBLIC_API int ecrt_voe_handler_received_header( * avoided by reserving enough memory via the \a size parameter of * ecrt_slave_config_create_voe_handler(). * + * \apiusage{master_any,rt_safe} + * * \return Pointer to the internal memory. */ EC_PUBLIC_API uint8_t *ecrt_voe_handler_data( @@ -2506,6 +2651,8 @@ EC_PUBLIC_API uint8_t *ecrt_voe_handler_data( * of bytes to write. After a read operation the size is set to the size of * the read data. The size is not modified in any other situation. * + * \apiusage{master_any,rt_safe} + * * \return Data size in bytes. */ EC_PUBLIC_API size_t ecrt_voe_handler_data_size( @@ -2522,7 +2669,8 @@ EC_PUBLIC_API size_t ecrt_voe_handler_data_size( * This method is meant to be called in realtime context (after master * activation). * - * \ingroup ApplicationInterfaceRT + * \apiusage{master_op,rt_safe} + * * \return 0 on success, otherwise negative error code. * \retval -ENOBUFS Reserved memory in ecrt_slave_config_create_voe_handler * too small. @@ -2550,7 +2698,8 @@ EC_PUBLIC_API int ecrt_voe_handler_write( * This method is meant to be called in realtime context (after master * activation). * - * \ingroup ApplicationInterfaceRT + * \apiusage{master_op,rt_safe} + * * \return 0 on success, otherwise negative error code. */ EC_PUBLIC_API int ecrt_voe_handler_read( @@ -2576,7 +2725,8 @@ EC_PUBLIC_API int ecrt_voe_handler_read( * This method is meant to be called in realtime context (after master * activation). * - * \ingroup ApplicationInterfaceRT + * \apiusage{master_op,rt_safe} + * * \return 0 on success, otherwise negative error code. */ EC_PUBLIC_API int ecrt_voe_handler_read_nosync( @@ -2593,7 +2743,8 @@ EC_PUBLIC_API int ecrt_voe_handler_read_nosync( * This method is meant to be called in realtime context (after master * activation). * - * \ingroup ApplicationInterfaceRT + * \apiusage{master_op,rt_safe} + * */ EC_PUBLIC_API ec_request_state_t ecrt_voe_handler_execute( ec_voe_handler_t *voe /**< VoE handler. */ @@ -2623,9 +2774,10 @@ EC_PUBLIC_API ec_request_state_t ecrt_voe_handler_execute( * This method is meant to be called in realtime context (after master * activation), but can also be used to initialize data before. * + * \apiusage{master_any,rt_safe} + * * \return Pointer to the internal memory. * - * \ingroup ApplicationInterfaceRT */ EC_PUBLIC_API uint8_t *ecrt_reg_request_data( const ec_reg_request_t *req /**< Register request. */ @@ -2636,9 +2788,10 @@ EC_PUBLIC_API uint8_t *ecrt_reg_request_data( * This method is meant to be called in realtime context (after master * activation). * + * \apiusage{master_op,rt_safe} + * * \return Request state. * - * \ingroup ApplicationInterfaceRT */ EC_PUBLIC_API ec_request_state_t ecrt_reg_request_state( const ec_reg_request_t *req /**< Register request. */ @@ -2655,7 +2808,8 @@ EC_PUBLIC_API ec_request_state_t ecrt_reg_request_state( * This method is meant to be called in realtime context (after master * activation). * - * \ingroup ApplicationInterfaceRT + * \apiusage{master_op,rt_safe} + * * \return 0 on success, otherwise negative error code. * \retval -ENOBUFS Reserved memory in ecrt_slave_config_create_reg_request * too small. @@ -2677,7 +2831,8 @@ EC_PUBLIC_API int ecrt_reg_request_write( * This method is meant to be called in realtime context (after master * activation). * - * \ingroup ApplicationInterfaceRT + * \apiusage{master_op,rt_safe} + * * \return 0 on success, otherwise negative error code. * \retval -ENOBUFS Reserved memory in ecrt_slave_config_create_reg_request * too small. @@ -2840,6 +2995,8 @@ EC_PUBLIC_API int ecrt_reg_request_read( #ifndef __KERNEL__ /** Read a 32-bit floating-point value from EtherCAT data. + * + * \apiusage{master_any,rt_safe} * * \param data EtherCAT data pointer * \return EtherCAT data value @@ -2854,6 +3011,8 @@ EC_PUBLIC_API float ecrt_read_real(const void *data); #define EC_READ_REAL(DATA) ecrt_read_real(DATA) /** Read a 64-bit floating-point value from EtherCAT data. + * + * \apiusage{master_any,rt_safe} * * \param data EtherCAT data pointer * \return EtherCAT data value @@ -2948,6 +3107,8 @@ EC_PUBLIC_API double ecrt_read_lreal(const void *data); #ifndef __KERNEL__ /** Write a 32-bit floating-point value to EtherCAT data. + * + * \apiusage{master_any,rt_safe} * * \param data EtherCAT data pointer * \param value new value @@ -2962,6 +3123,8 @@ EC_PUBLIC_API void ecrt_write_real(void *data, float value); #define EC_WRITE_REAL(DATA, VAL) ecrt_write_real(DATA, VAL) /** Write a 64-bit floating-point value to EtherCAT data. + * + * \apiusage{master_any,rt_safe} * * \param data EtherCAT data pointer * \param value new value diff --git a/master/api_usage_notes.md b/master/api_usage_notes.md new file mode 100644 index 00000000..1880866d --- /dev/null +++ b/master/api_usage_notes.md @@ -0,0 +1,51 @@ +Notes regaring API Usage {#apiusage} +======================== + +There are some restrictions on the +[Application Interface](@ref ApplicationInterface) with respect to the state of +the master instance and the calling context, which are explained in the +following. + +## Rules of Thumb + +All configuration (`ecrt_slave_config_*()`) has to be done in Linux process +context. They can be blocking, so take care when holding locks. After +ecrt_master_activate() ing the master, your application must not alter the +slave configuration. Instead, update process data using ecrt_domain_queue() +and ecrt_domain_process() or use the asynchronous interface like +ecrt_sdo_request_read(). Don't forget to ecrt_master_receive() and +ecrt_master_send(). These functions can be called from non-process context +too, like Xenomai/RTAI applications or custom kernel modules. + +## Master Phase + +The first distinction of cases is whether ecrt_master_activate() has been +called or not. Before ecrt_master_activate() (or after +ecrt_master_deactivate()), the master is in idle phase. Sending and receiving +EtherCAT frames will be done by the master itself, the application (e. g. you) +can store slave configurations for later use. After ecrt_master_activate(), +the master switches into operation mode. The application is now in charge of +steering the communication. Process data can be exchanged under real time +constraints. Altering the slave configuration is not possible anymore. + +| Tag | Description | +|---------------|---------------------------------------------------------------------------------------| +| `master_op` | Master must be in operation phase, so after `ecrt_master_activate()` has been called. | +| `master_idle` | Master must be in idle phase, so before `ecrt_master_activate()` has been called. | +| `master_any` | Master can be in idle or operation phase. | + +## Allowed Context + +The second distinction of cases is the calling context, which means how the +application is run. Most of the functions of the +[Application Interface](@ref ApplicationInterface) have to acquire locks or +allocate memory, so they are potentially sleeping. They are tagged as +`blocking`. Sleeping is not allowed in all contexts, for instance when using +Xenomai/RTAI or a kernel timer. Only a very limited set of functions can be +called from any context, marked as `rt_safe`. They do not allocate memory and +will not block. + +| Tag | Description | +|------------|-----------------------------------------------------------------------------------------------| +| `rt_safe` | Realtime context (RT userspace, atomic/softirq context in kernel, Xenomai/RTAI RT task) safe. | +| `blocking` | Linux process context only (userspace or kernel), might block. |