Separated master requesting into open and reserve for userspace library.

(thanks to Martin Troxler).
This commit is contained in:
Florian Pose
2009-07-10 10:07:48 +00:00
parent e4a8e667f4
commit fbb6b62eaf
4 changed files with 127 additions and 14 deletions

4
NEWS
View File

@@ -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.

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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;
}