Improved bus information API.
This commit is contained in:
parent
4f4ac6e4fa
commit
a7521cc69d
16
NEWS
16
NEWS
|
|
@ -35,10 +35,15 @@ Changes since 1.4.0:
|
|||
* 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.
|
||||
the userspace library (thanks to Martin Troxler).
|
||||
* Added bus information interface (methods ecrt_master(),
|
||||
ecrt_master_get_slave(), ecrt_master_get_sync_manager(),
|
||||
ecrt_master_get_pdo() and ecrt_master_get_pdo_entry()) to get information
|
||||
about the currently connected slaves and the PDO entries provided (thanks to
|
||||
Martin Troxler and Stefan Weiser).
|
||||
* Added ecrt_master_sdo_download() and ecrt_master_sdo_upload()
|
||||
methods to let an application transfer SDOs before activating the master
|
||||
(thanks to Stefan Weiser).
|
||||
* Fixed SDO upload segment response (thanks to Christoph Peter).
|
||||
* SDO entry access rights are shown in 'ethercat sdos'.
|
||||
* Added 64-bit data access macros to application header.
|
||||
|
|
@ -48,9 +53,6 @@ Changes since 1.4.0:
|
|||
* Output device link state in 'ethercat master'.
|
||||
* Added 'ethercat graph' command which outputs the bus topology in
|
||||
DOT language.
|
||||
* Added ecrt_slave_sdo_upload() and ecrt_slave_sdo_download() methods to let
|
||||
an application transfer SDOs before activating the master. Thanks to Stefan
|
||||
Weiser.
|
||||
* Changed EC_MAX_SII_SIZE to 4096.
|
||||
* 'ethercat xml' creates valid XML <EtherCATInfoList> for more than one slave
|
||||
(thanks to E. Burgstaller).
|
||||
|
|
|
|||
154
include/ecrt.h
154
include/ecrt.h
|
|
@ -55,11 +55,12 @@
|
|||
* ecrt_slave_config_sync_manager()).
|
||||
* - Added ecrt_open_master() and ecrt_master_reserve() separation for
|
||||
* userspace.
|
||||
* - Added ecrt_master() userspace interface, to get information about a
|
||||
* master.
|
||||
* - Added ecrt_master_slave() to get information about a certain slave.
|
||||
* - Added ecrt_slave_sdo_upload() and ecrt_slave_sdo_download() methods to
|
||||
* let an application transfer SDOs before activating the master.
|
||||
* - Added bus information interface (methods ecrt_master(),
|
||||
* ecrt_master_get_slave(), ecrt_master_get_sync_manager(),
|
||||
* ecrt_master_get_pdo() and ecrt_master_get_pdo_entry()) to get information
|
||||
* about the currently connected slaves and the PDO entries provided.
|
||||
* - Added ecrt_master_sdo_download() and ecrt_master_sdo_upload()
|
||||
* methods to let an application transfer SDOs before activating the 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
|
||||
|
|
@ -220,9 +221,9 @@ typedef struct {
|
|||
|
||||
/** Slave information.
|
||||
*
|
||||
* This is used as an output parameter of ecrt_master_slave().
|
||||
* This is used as an output parameter of ecrt_master_get_slave().
|
||||
*
|
||||
* \see ecrt_master_slave().
|
||||
* \see ecrt_master_get_slave().
|
||||
*/
|
||||
typedef struct {
|
||||
uint16_t position; /**< Offset of the slave in the ring. */
|
||||
|
|
@ -557,13 +558,104 @@ int ecrt_master(
|
|||
*
|
||||
* \return 0 in case of success, else < 0
|
||||
*/
|
||||
int ecrt_master_slave(
|
||||
int ecrt_master_get_slave(
|
||||
ec_master_t *master, /**< EtherCAT master */
|
||||
uint16_t position, /**< Slave position. */
|
||||
uint16_t slave_position, /**< Slave position. */
|
||||
ec_slave_info_t *slave_info /**< Structure that will output the
|
||||
information */
|
||||
);
|
||||
|
||||
/** Returns the proposed configuration of a slave's sync manager.
|
||||
*
|
||||
* Fills a given ec_sync_info_t structure with the attributes of a sync
|
||||
* manager. The \a pdos field of the return value is left empty. Use
|
||||
* ecrt_master_get_pdo() to get the PDO information.
|
||||
*
|
||||
* \return zero on success, else non-zero
|
||||
*/
|
||||
int ecrt_master_get_sync_manager(
|
||||
ec_master_t *master, /**< EtherCAT master. */
|
||||
uint16_t slave_position, /**< Slave position. */
|
||||
uint8_t sync_index, /**< Sync manager index. Must be less
|
||||
than #EC_MAX_SYNC_MANAGERS. */
|
||||
ec_sync_info_t *sync /**< Pointer to output structure. */
|
||||
);
|
||||
|
||||
/** Returns information about a currently assigned PDO.
|
||||
*
|
||||
* Fills a given ec_pdo_info_t structure with the attributes of a currently
|
||||
* assigned PDO of the given sync manager. The \a entries field of the return
|
||||
* value is left empty. Use ecrt_master_get_pdo_entry() to get the PDO
|
||||
* entry information.
|
||||
*
|
||||
* \retval zero on success, else non-zero
|
||||
*/
|
||||
int ecrt_master_get_pdo(
|
||||
ec_master_t *master, /**< EtherCAT master. */
|
||||
uint16_t slave_position, /**< Slave position. */
|
||||
uint8_t sync_index, /**< Sync manager index. Must be less
|
||||
than #EC_MAX_SYNC_MANAGERS. */
|
||||
uint16_t pos, /**< Zero-based PDO position. */
|
||||
ec_pdo_info_t *pdo /**< Pointer to output structure. */
|
||||
);
|
||||
|
||||
/** Returns information about a currently mapped PDO entry.
|
||||
*
|
||||
* Fills a given ec_pdo_entry_info_t structure with the attributes of a
|
||||
* currently mapped PDO entry of the given PDO.
|
||||
*
|
||||
* \retval zero on success, else non-zero
|
||||
*/
|
||||
int ecrt_master_get_pdo_entry(
|
||||
ec_master_t *master, /**< EtherCAT master. */
|
||||
uint16_t slave_position, /**< Slave position. */
|
||||
uint8_t sync_index, /**< Sync manager index. Must be less
|
||||
than #EC_MAX_SYNC_MANAGERS. */
|
||||
uint16_t pdo_pos, /**< Zero-based PDO position. */
|
||||
uint16_t entry_pos, /**< Zero-based PDO entry position. */
|
||||
ec_pdo_entry_info_t *entry /**< Pointer to output structure. */
|
||||
);
|
||||
|
||||
/** Executes an SDO write request to download data.
|
||||
*
|
||||
* This function operates aside of the normal way to request SDOs. Before the
|
||||
* activation of the master, these requests are processed by the master state
|
||||
* machine itself. After activation the user has to ensure cyclic processing.
|
||||
*
|
||||
* \retval 0 Success.
|
||||
* \retval -1 An error occured.
|
||||
*/
|
||||
int ecrt_master_sdo_download(
|
||||
ec_master_t *master, /**< EtherCAT master. */
|
||||
uint16_t slave_position, /**< Slave position. */
|
||||
uint16_t index, /**< Index of the SDO. */
|
||||
uint8_t subindex, /**< Subindex of the SDO. */
|
||||
uint8_t *data, /**< Data buffer to download. */
|
||||
size_t data_size, /**< Size of the data buffer. */
|
||||
uint32_t *abort_code /**< Abort code of the SDO download. */
|
||||
);
|
||||
|
||||
/** Executes a SDO read request to upload data.
|
||||
*
|
||||
* This function operates aside of the normal way to request SDOs. Before the
|
||||
* activation of the master, these requests are processed by the master state
|
||||
* machine itself. After activation the user have to ensure cyclic
|
||||
* processing.
|
||||
*
|
||||
* \retval 0 Success.
|
||||
* \retval -1 Error occured.
|
||||
*/
|
||||
int ecrt_master_sdo_upload(
|
||||
ec_master_t *master, /**< EtherCAT master. */
|
||||
uint16_t slave_position, /**< Slave position. */
|
||||
uint16_t index, /**< Index of the SDO. */
|
||||
uint8_t subindex, /**< Subindex of the SDO. */
|
||||
uint8_t *target, /**< Target buffer for the upload. */
|
||||
size_t target_size, /**< Size of the target buffer. */
|
||||
size_t *result_size, /**< Uploaded data size. */
|
||||
uint32_t *abort_code /**< Abort code of the SDO upload. */
|
||||
);
|
||||
|
||||
#endif /* #ifndef __KERNEL__ */
|
||||
|
||||
/** Finishes the configuration phase and prepares for cyclic operation.
|
||||
|
|
@ -666,50 +758,6 @@ void ecrt_master_sync_slave_clocks(
|
|||
ec_master_t *master /**< EtherCAT master. */
|
||||
);
|
||||
|
||||
#ifndef __KERNEL__
|
||||
|
||||
/** Executes an SDO write request to download data.
|
||||
*
|
||||
* This function operates aside of the normal way to request SDOs. Before the
|
||||
* activation of the master, these requests are processed by the master state
|
||||
* machine itself. After activation the user has to ensure cyclic processing.
|
||||
*
|
||||
* \retval 0 Success.
|
||||
* \retval -1 An error occured.
|
||||
*/
|
||||
int ecrt_slave_sdo_download(
|
||||
ec_master_t* master, /**< EtherCAT master. */
|
||||
uint16_t slave_position, /**< Slave position. */
|
||||
uint16_t index, /**< Index of the SDO. */
|
||||
uint8_t subindex, /**< Subindex of the SDO. */
|
||||
uint8_t *data, /**< Data buffer to download. */
|
||||
size_t data_size, /**< Size of the data buffer. */
|
||||
uint32_t *abort_code /**< Abort code of the SDO download. */
|
||||
);
|
||||
|
||||
/** Executes a SDO read request to upload data.
|
||||
*
|
||||
* This function operates aside of the normal way to request SDOs. Before the
|
||||
* activation of the master, these requests are processed by the master state
|
||||
* machine itself. After activation the user have to ensure cyclic
|
||||
* processing.
|
||||
*
|
||||
* \retval 0 Success.
|
||||
* \retval -1 Error occured.
|
||||
*/
|
||||
int ecrt_slave_sdo_upload(
|
||||
ec_master_t* master, /**< EtherCAT master. */
|
||||
uint16_t slave_position, /**< Slave position. */
|
||||
uint16_t index, /**< Index of the SDO. */
|
||||
uint8_t subindex, /**< Subindex of the SDO. */
|
||||
uint8_t *target, /**< Target buffer for the upload. */
|
||||
size_t target_size, /**< Size of the target buffer. */
|
||||
size_t *result_size, /**< Uploaded data size. */
|
||||
uint32_t *abort_code /**< Abort code of the SDO upload. */
|
||||
);
|
||||
|
||||
#endif /* #ifndef __KERNEL__ */
|
||||
|
||||
/******************************************************************************
|
||||
* Slave configuration methods
|
||||
*****************************************************************************/
|
||||
|
|
|
|||
207
lib/master.c
207
lib/master.c
|
|
@ -131,13 +131,13 @@ int ecrt_master(ec_master_t* master, ec_master_info_t *master_info)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
int ecrt_master_slave(ec_master_t *master, uint16_t position,
|
||||
int ecrt_master_get_slave(ec_master_t *master, uint16_t slave_position,
|
||||
ec_slave_info_t *slave_info)
|
||||
{
|
||||
ec_ioctl_slave_t data;
|
||||
int index;
|
||||
|
||||
data.position = position;
|
||||
data.position = slave_position;
|
||||
|
||||
if (ioctl(master->fd, EC_IOCTL_SLAVE, &data) == -1) {
|
||||
fprintf(stderr, "Failed to get slave info: %s\n", strerror(errno));
|
||||
|
|
@ -161,6 +161,152 @@ int ecrt_master_slave(ec_master_t *master, uint16_t position,
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
int ecrt_master_get_sync_manager(ec_master_t *master, uint16_t slave_position,
|
||||
uint8_t sync_index, ec_sync_info_t *sync)
|
||||
{
|
||||
ec_ioctl_slave_sync_t data;
|
||||
|
||||
if (sync_index >= EC_MAX_SYNC_MANAGERS)
|
||||
return -ENOENT;
|
||||
|
||||
memset(&data, 0x00, sizeof(ec_ioctl_slave_sync_t));
|
||||
data.slave_position = slave_position;
|
||||
data.sync_index = sync_index;
|
||||
|
||||
if (ioctl(master->fd, EC_IOCTL_SLAVE_SYNC, &data) == -1) {
|
||||
fprintf(stderr, "Failed to get sync manager information: %s\n",
|
||||
strerror(errno));
|
||||
return -1; // FIXME
|
||||
}
|
||||
|
||||
sync->index = sync_index;
|
||||
sync->dir = EC_READ_BIT(&data.control_register, 2) ?
|
||||
EC_DIR_OUTPUT : EC_DIR_INPUT;
|
||||
sync->n_pdos = data.pdo_count;
|
||||
sync->pdos = NULL;
|
||||
sync->watchdog_mode = EC_READ_BIT(&data.control_register, 6) ?
|
||||
EC_WD_ENABLE : EC_WD_DISABLE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int ecrt_master_get_pdo(ec_master_t *master, uint16_t slave_position,
|
||||
uint8_t sync_index, uint16_t pos, ec_pdo_info_t *pdo)
|
||||
{
|
||||
ec_ioctl_slave_sync_pdo_t data;
|
||||
|
||||
if (sync_index >= EC_MAX_SYNC_MANAGERS)
|
||||
return -ENOENT;
|
||||
|
||||
memset(&data, 0x00, sizeof(ec_ioctl_slave_sync_pdo_t));
|
||||
data.slave_position = slave_position;
|
||||
data.sync_index = sync_index;
|
||||
data.pdo_pos = pos;
|
||||
|
||||
if (ioctl(master->fd, EC_IOCTL_SLAVE_SYNC_PDO, &data) == -1) {
|
||||
fprintf(stderr, "Failed to get pdo information: %s\n",
|
||||
strerror(errno));
|
||||
return -1; // FIXME
|
||||
}
|
||||
|
||||
pdo->index = data.index;
|
||||
pdo->n_entries = data.entry_count;
|
||||
pdo->entries = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int ecrt_master_get_pdo_entry(ec_master_t *master, uint16_t slave_position,
|
||||
uint8_t sync_index, uint16_t pdo_pos, uint16_t entry_pos,
|
||||
ec_pdo_entry_info_t *entry)
|
||||
{
|
||||
ec_ioctl_slave_sync_pdo_entry_t data;
|
||||
|
||||
if (sync_index >= EC_MAX_SYNC_MANAGERS)
|
||||
return -ENOENT;
|
||||
|
||||
memset(&data, 0x00, sizeof(ec_ioctl_slave_sync_pdo_entry_t));
|
||||
data.slave_position = slave_position;
|
||||
data.sync_index = sync_index;
|
||||
data.pdo_pos = pdo_pos;
|
||||
data.entry_pos = entry_pos;
|
||||
|
||||
if (ioctl(master->fd, EC_IOCTL_SLAVE_SYNC_PDO_ENTRY, &data) == -1) {
|
||||
fprintf(stderr, "Failed to get pdo entry information: %s\n",
|
||||
strerror(errno));
|
||||
return -1; // FIXME
|
||||
}
|
||||
|
||||
entry->index = data.index;
|
||||
entry->subindex = data.subindex;
|
||||
entry->bit_length = data.bit_length;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int ecrt_master_sdo_download(ec_master_t *master, uint16_t slave_position,
|
||||
uint16_t index, uint8_t subindex, uint8_t *data,
|
||||
size_t data_size, uint32_t *abort_code)
|
||||
{
|
||||
ec_ioctl_slave_sdo_download_t download;
|
||||
|
||||
download.slave_position = slave_position;
|
||||
download.sdo_index = index;
|
||||
download.sdo_entry_subindex = subindex;
|
||||
download.data_size = data_size;
|
||||
download.data = data;
|
||||
|
||||
if (ioctl(master->fd, EC_IOCTL_SLAVE_SDO_DOWNLOAD, &download) == -1) {
|
||||
if (errno == -EIO) {
|
||||
if (abort_code) {
|
||||
*abort_code = download.abort_code;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "Failed to execute SDO download: %s\n",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int ecrt_master_sdo_upload(ec_master_t *master, uint16_t slave_position,
|
||||
uint16_t index, uint8_t subindex, uint8_t *target,
|
||||
size_t target_size, size_t *result_size, uint32_t *abort_code)
|
||||
{
|
||||
ec_ioctl_slave_sdo_upload_t upload;
|
||||
|
||||
upload.slave_position = slave_position;
|
||||
upload.sdo_index = index;
|
||||
upload.sdo_entry_subindex = subindex;
|
||||
upload.target_size = target_size;
|
||||
upload.target = target;
|
||||
|
||||
if (ioctl(master->fd, EC_IOCTL_SLAVE_SDO_UPLOAD, &upload) == -1) {
|
||||
if (errno == -EIO) {
|
||||
if (abort_code) {
|
||||
*abort_code = upload.abort_code;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "Failed to execute SDO upload: %s\n",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
*result_size = upload.data_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int ecrt_master_activate(ec_master_t *master)
|
||||
{
|
||||
if (ioctl(master->fd, EC_IOCTL_ACTIVATE,
|
||||
|
|
@ -248,60 +394,3 @@ void ecrt_master_sync_slave_clocks(ec_master_t *master)
|
|||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int ecrt_slave_sdo_download(ec_master_t* master, uint16_t slave_position,
|
||||
uint16_t index, uint8_t subindex, uint8_t *data,
|
||||
size_t data_size, uint32_t *abort_code)
|
||||
{
|
||||
ec_ioctl_slave_sdo_download_t download;
|
||||
|
||||
download.slave_position = slave_position;
|
||||
download.sdo_index = index;
|
||||
download.sdo_entry_subindex = subindex;
|
||||
download.data_size = data_size;
|
||||
download.data = data;
|
||||
|
||||
if (ioctl(master->fd, EC_IOCTL_SLAVE_SDO_DOWNLOAD, &download) == -1) {
|
||||
if (errno == -EIO) {
|
||||
if (abort_code) {
|
||||
*abort_code = download.abort_code;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "Failed to execute SDO download: %s\n",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
int ecrt_slave_sdo_upload(ec_master_t* master, uint16_t slave_position,
|
||||
uint16_t index, uint8_t subindex, uint8_t *target,
|
||||
size_t target_size, size_t *result_size, uint32_t *abort_code)
|
||||
{
|
||||
ec_ioctl_slave_sdo_upload_t upload;
|
||||
|
||||
upload.slave_position = slave_position;
|
||||
upload.sdo_index = index;
|
||||
upload.sdo_entry_subindex = subindex;
|
||||
upload.target_size = target_size;
|
||||
upload.target = target;
|
||||
|
||||
if (ioctl(master->fd, EC_IOCTL_SLAVE_SDO_UPLOAD, &upload) == -1) {
|
||||
if (errno == -EIO) {
|
||||
if (abort_code) {
|
||||
*abort_code = upload.abort_code;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "Failed to execute SDO upload: %s\n",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
*result_size = upload.data_size;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
|||
Loading…
Reference in New Issue