mirror of
https://gitlab.com/etherlab.org/ethercat.git
synced 2026-02-06 03:41:52 +08:00
Separated master requesting into open and reserve for userspace library.
(thanks to Martin Troxler).
This commit is contained in:
4
NEWS
4
NEWS
@@ -28,6 +28,10 @@ Changes since 1.4.0:
|
||||
O. Zarges.
|
||||
* Going to the Bootstrap state is now supported by the state machines and the
|
||||
command-line tool.
|
||||
* Added ecrt_open_master() and ecrt_master_reserve() separation for
|
||||
the userspace libary (thanks to Martin Troxler).
|
||||
* Added ecrt_master() userspace interface, to get information about a
|
||||
master (thanks to Martin Troxler).
|
||||
* Introduced ecrt_master_slave() to get information about a certain slave.
|
||||
* SDO entry access rights are shown in 'ethercat sdos'.
|
||||
* Added 64-bit data access macros to application header.
|
||||
|
||||
@@ -47,6 +47,10 @@
|
||||
* ecrt_master_sync_reference_clock() and ecrt_master_sync_slave_clocks()
|
||||
* for offset and drift compensation. The EC_TIMEVAL2NANO() macro can be
|
||||
* used for epoch time conversion.
|
||||
* - Added ecrt_open_master() and ecrt_master_reserve() separation for
|
||||
* userspace.
|
||||
* - Added ecrt_master() userspace interface, to get information about a
|
||||
* master.
|
||||
* - Changed the meaning of the negative return values of
|
||||
* ecrt_slave_config_reg_pdo_entry() and ecrt_slave_config_sdo*().
|
||||
* - Imlemented the Vendor-specific over EtherCAT mailbox protocol. See
|
||||
@@ -192,6 +196,22 @@ typedef struct {
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifndef __KERNEL__
|
||||
|
||||
/** Master information.
|
||||
*
|
||||
* This is used as an output parameter of ecrt_master().
|
||||
*
|
||||
* \see ecrt_master().
|
||||
*/
|
||||
typedef struct {
|
||||
unsigned int slave_count; /**< Number of slaves in the bus. */
|
||||
unsigned int link_up : 1; /**< \a true, if the network link is up. */
|
||||
uint64_t app_time; /**< Application time. */
|
||||
} ec_master_info_t;
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Slave information.
|
||||
*
|
||||
* This is used as an output parameter of ecrt_master_slave().
|
||||
@@ -213,6 +233,8 @@ typedef struct {
|
||||
char name[EC_MAX_STRING_LENGTH]; /**< Name of the slave. */
|
||||
} ec_slave_info_t;
|
||||
|
||||
#endif // #ifndef __KERNEL__
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/** Domain working counter interpretation.
|
||||
@@ -354,6 +376,9 @@ unsigned int ecrt_version_magic(void);
|
||||
* Before an application can access an EtherCAT master, it has to reserve one
|
||||
* for exclusive use.
|
||||
*
|
||||
* In userspace, this is a convenience function for ecrt_open_master() and
|
||||
* ecrt_master_reserve().
|
||||
*
|
||||
* This function has to be the first function an application has to call to
|
||||
* use EtherCAT. The function takes the index of the master as its argument.
|
||||
* The first master has index 0, the n-th master has index n - 1. The number
|
||||
@@ -365,6 +390,25 @@ ec_master_t *ecrt_request_master(
|
||||
unsigned int master_index /**< Index of the master to request. */
|
||||
);
|
||||
|
||||
#ifndef __KERNEL__
|
||||
|
||||
/** Opens an EtherCAT master for userspace access.
|
||||
*
|
||||
* This function has to be the first function an application has to call to
|
||||
* use EtherCAT. The function takes the index of the master as its argument.
|
||||
* 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.
|
||||
*
|
||||
* For convenience, the function ecrt_request_master() can be used.
|
||||
*
|
||||
* \return Pointer to the opened master, otherwise \a NULL.
|
||||
*/
|
||||
ec_master_t *ecrt_open_master(
|
||||
unsigned int master_index /**< Index of the master to request. */
|
||||
);
|
||||
|
||||
#endif // #ifndef __KERNEL__
|
||||
|
||||
/** Releases a requested EtherCAT master.
|
||||
*
|
||||
* After use, a master it has to be released to make it available for other
|
||||
@@ -378,6 +422,22 @@ void ecrt_release_master(
|
||||
* Master methods
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef __KERNEL__
|
||||
|
||||
/** Reserves an EtherCAT master for realtime operation.
|
||||
*
|
||||
* Before an application can use PDO/domain registration functions or SDO
|
||||
* 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 */
|
||||
);
|
||||
|
||||
#endif // #ifndef __KERNEL__
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
/** Sets the locking callbacks.
|
||||
@@ -451,6 +511,21 @@ ec_slave_config_t *ecrt_master_slave_config(
|
||||
|
||||
#ifndef __KERNEL__
|
||||
|
||||
/** Obtains master information.
|
||||
*
|
||||
* No memory is allocated on the heap in
|
||||
* this function.
|
||||
*
|
||||
* \attention The pointer to this structure must point to a valid variable.
|
||||
*
|
||||
* \return 0 in case of success, else < 0
|
||||
*/
|
||||
int ecrt_master(
|
||||
ec_master_t *master, /**< EtherCAT master */
|
||||
ec_master_info_t *master_info /**< Structure that will output the
|
||||
information */
|
||||
);
|
||||
|
||||
/** Obtains slave information.
|
||||
*
|
||||
* Tries to find the slave with the given ring position. The obtained
|
||||
@@ -468,7 +543,7 @@ int ecrt_master_slave(
|
||||
information */
|
||||
);
|
||||
|
||||
#endif /* ifndef __KERNEL__ */
|
||||
#endif /* #ifndef __KERNEL__ */
|
||||
|
||||
/** Finishes the configuration phase and prepares for cyclic operation.
|
||||
*
|
||||
@@ -603,7 +678,7 @@ int ecrt_slave_sdo_upload(
|
||||
uint32_t *abort_code /**< Abort code of the SDO upload. */
|
||||
);
|
||||
|
||||
#endif /* ifndef __KERNEL__ */
|
||||
#endif /* #ifndef __KERNEL__ */
|
||||
|
||||
/******************************************************************************
|
||||
* Slave configuration methods
|
||||
|
||||
26
lib/common.c
26
lib/common.c
@@ -50,9 +50,25 @@ unsigned int ecrt_version_magic(void)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
ec_master_t *ecrt_request_master(unsigned int master_index)
|
||||
{
|
||||
ec_master_t *master = ecrt_open_master(master_index);
|
||||
if (master) {
|
||||
if (ecrt_master_reserve(master) < 0) {
|
||||
close(master->fd);
|
||||
free(master);
|
||||
master = 0;
|
||||
}
|
||||
}
|
||||
|
||||
return master;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define MAX_PATH_LEN 64
|
||||
|
||||
ec_master_t *ecrt_request_master(unsigned int master_index)
|
||||
ec_master_t *ecrt_open_master(unsigned int master_index)
|
||||
{
|
||||
char path[MAX_PATH_LEN];
|
||||
ec_master_t *master;
|
||||
@@ -75,14 +91,6 @@ ec_master_t *ecrt_request_master(unsigned int master_index)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ioctl(master->fd, EC_IOCTL_REQUEST, NULL) == -1) {
|
||||
fprintf(stderr, "Failed to request master %u: %s\n",
|
||||
master_index, strerror(errno));
|
||||
close(master->fd);
|
||||
free(master);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return master;
|
||||
}
|
||||
|
||||
|
||||
32
lib/master.c
32
lib/master.c
@@ -42,6 +42,17 @@
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int ecrt_master_reserve(ec_master_t *master)
|
||||
{
|
||||
if (ioctl(master->fd, EC_IOCTL_REQUEST, NULL) == -1) {
|
||||
fprintf(stderr, "Failed to reserve master: %s\n",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
ec_domain_t *ecrt_master_create_domain(ec_master_t *master)
|
||||
{
|
||||
ec_domain_t *domain;
|
||||
@@ -103,6 +114,23 @@ ec_slave_config_t *ecrt_master_slave_config(ec_master_t *master,
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int ecrt_master(ec_master_t* master, ec_master_info_t *master_info)
|
||||
{
|
||||
ec_ioctl_master_t data;
|
||||
|
||||
if (ioctl(master->fd, EC_IOCTL_MASTER, &data) < 0) {
|
||||
fprintf(stderr, "Failed to get master info: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
master_info->slave_count = data.slave_count;
|
||||
master_info->link_up = data.devices[0].link_state;
|
||||
master_info->app_time = data.app_time;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int ecrt_master_slave(ec_master_t *master, uint16_t position,
|
||||
ec_slave_info_t *slave_info)
|
||||
{
|
||||
@@ -112,8 +140,7 @@ int ecrt_master_slave(ec_master_t *master, uint16_t position,
|
||||
data.position = position;
|
||||
|
||||
if (ioctl(master->fd, EC_IOCTL_SLAVE, &data) == -1) {
|
||||
fprintf(stderr, "Failed to get slave info: %s\n",
|
||||
strerror(errno));
|
||||
fprintf(stderr, "Failed to get slave info: %s\n", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -129,7 +156,6 @@ int ecrt_master_slave(ec_master_t *master, uint16_t position,
|
||||
slave_info->sync_count = data.sync_count;
|
||||
slave_info->sdo_count = data.sdo_count;
|
||||
strncpy(slave_info->name, data.name, EC_IOCTL_STRING_SIZE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user