Re-worked and seamlessly integrated RTDM interface.

This commit is contained in:
Florian Pose
2012-09-20 15:28:25 +02:00
parent 592c2a8cea
commit 9faaa83212
30 changed files with 5751 additions and 3928 deletions
+26 -3
View File
@@ -2,7 +2,7 @@
#
# $Id$
#
# Copyright (C) 2006-2009 Florian Pose, Ingenieurgemeinschaft IgH
# Copyright (C) 2006-2012 Florian Pose, Ingenieurgemeinschaft IgH
#
# This file is part of the IgH EtherCAT master userspace library.
#
@@ -32,8 +32,6 @@ lib_LTLIBRARIES = libethercat.la
#------------------------------------------------------------------------------
libethercat_la_CFLAGS = -I$(srcdir)/.. -fno-strict-aliasing -Wall
libethercat_la_LDFLAGS = -version-info 1:0:0
libethercat_la_SOURCES = \
common.c \
domain.c \
@@ -49,4 +47,29 @@ noinst_HEADERS = \
slave_config.h \
voe_handler.h
libethercat_la_CFLAGS = -fno-strict-aliasing -Wall
libethercat_la_LDFLAGS = -version-info 1:0:0
#------------------------------------------------------------------------------
if ENABLE_RTDM
lib_LTLIBRARIES += libethercat_rtdm.la
libethercat_rtdm_la_SOURCES = $(libethercat_la_SOURCES)
libethercat_rtdm_la_CFLAGS = $(libethercat_la_CFLAGS) -DUSE_RTDM
libethercat_rtdm_la_LDFLAGS = $(libethercat_la_LDFLAGS)
if ENABLE_XENOMAI
libethercat_rtdm_la_CFLAGS += $(XENOMAI_RTDM_CFLAGS)
libethercat_rtdm_la_LDFLAGS += $(XENOMAI_RTDM_LDFLAGS)
endif
if ENABLE_RTAI
libethercat_rtdm_la_CFLAGS += $(RTAI_LXRT_CFLAGS)
libethercat_rtdm_la_LDFLAGS += $(RTAI_LXRT_LDFLAGS)
endif
endif
#------------------------------------------------------------------------------
+20 -9
View File
@@ -2,7 +2,7 @@
*
* $Id$
*
* Copyright (C) 2006-2009 Florian Pose, Ingenieurgemeinschaft IgH
* Copyright (C) 2006-2012 Florian Pose, Ingenieurgemeinschaft IgH
*
* This file is part of the IgH EtherCAT master userspace library.
*
@@ -33,15 +33,13 @@
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <unistd.h>
#include <sys/socket.h>
#include "ioctl.h"
#include "master.h"
#include "master/ioctl.h"
/*****************************************************************************/
@@ -75,6 +73,7 @@ ec_master_t *ecrt_open_master(unsigned int master_index)
char path[MAX_PATH_LEN];
ec_master_t *master = NULL;
ec_ioctl_module_t module_data;
int ret;
master = malloc(sizeof(ec_master_t));
if (!master) {
@@ -87,17 +86,29 @@ ec_master_t *ecrt_open_master(unsigned int master_index)
master->first_domain = NULL;
master->first_config = NULL;
snprintf(path, MAX_PATH_LEN - 1, "/dev/EtherCAT%u", master_index);
snprintf(path, MAX_PATH_LEN - 1,
#ifdef USE_RTDM
"EtherCAT%u",
#else
"/dev/EtherCAT%u",
#endif
master_index);
#ifdef USE_RTDM
master->fd = rt_dev_open(path, O_RDWR);
#else
master->fd = open(path, O_RDWR);
if (master->fd == -1) {
fprintf(stderr, "Failed to open %s: %s\n", path, strerror(errno));
#endif
if (EC_IOCTL_IS_ERROR(master->fd)) {
fprintf(stderr, "Failed to open %s: %s\n", path,
strerror(EC_IOCTL_ERRNO(master->fd)));
goto out_clear;
}
if (ioctl(master->fd, EC_IOCTL_MODULE, &module_data) < 0) {
ret = ioctl(master->fd, EC_IOCTL_MODULE, &module_data);
if (EC_IOCTL_IS_ERROR(ret)) {
fprintf(stderr, "Failed to get module information from %s: %s\n",
path, strerror(errno));
path, strerror(EC_IOCTL_ERRNO(ret)));
goto out_clear;
}
+23 -17
View File
@@ -2,7 +2,7 @@
*
* $Id$
*
* Copyright (C) 2006-2009 Florian Pose, Ingenieurgemeinschaft IgH
* Copyright (C) 2006-2012 Florian Pose, Ingenieurgemeinschaft IgH
*
* This file is part of the IgH EtherCAT master userspace library.
*
@@ -35,15 +35,13 @@
/*****************************************************************************/
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <errno.h> /* ENOENT */
#include "ioctl.h"
#include "domain.h"
#include "master.h"
#include "master/ioctl.h"
/*****************************************************************************/
@@ -64,11 +62,11 @@ int ecrt_domain_reg_pdo_entry_list(ec_domain_t *domain,
for (reg = regs; reg->index; reg++) {
if (!(sc = ecrt_master_slave_config(domain->master, reg->alias,
reg->position, reg->vendor_id, reg->product_code)))
return -1; // FIXME
return -ENOENT;
if ((ret = ecrt_slave_config_reg_pdo_entry(sc, reg->index,
reg->subindex, domain, reg->bit_position)) < 0)
return -1; // FIXME
return ret;
*reg->offset = ret;
}
@@ -85,9 +83,9 @@ uint8_t *ecrt_domain_data(ec_domain_t *domain)
offset = ioctl(domain->master->fd, EC_IOCTL_DOMAIN_OFFSET,
domain->index);
if (offset == -1) {
if (EC_IOCTL_IS_ERROR(offset)) {
fprintf(stderr, "Failed to get domain offset: %s\n",
strerror(errno));
strerror(EC_IOCTL_ERRNO(offset)));
return NULL;
}
@@ -101,9 +99,12 @@ uint8_t *ecrt_domain_data(ec_domain_t *domain)
void ecrt_domain_process(ec_domain_t *domain)
{
if (ioctl(domain->master->fd, EC_IOCTL_DOMAIN_PROCESS,
domain->index) == -1) {
fprintf(stderr, "Failed to process domain: %s\n", strerror(errno));
int ret;
ret = ioctl(domain->master->fd, EC_IOCTL_DOMAIN_PROCESS, domain->index);
if (EC_IOCTL_IS_ERROR(ret)) {
fprintf(stderr, "Failed to process domain: %s\n",
strerror(EC_IOCTL_ERRNO(ret)));
}
}
@@ -111,9 +112,12 @@ void ecrt_domain_process(ec_domain_t *domain)
void ecrt_domain_queue(ec_domain_t *domain)
{
if (ioctl(domain->master->fd, EC_IOCTL_DOMAIN_QUEUE,
domain->index) == -1) {
fprintf(stderr, "Failed to queue domain: %s\n", strerror(errno));
int ret;
ret = ioctl(domain->master->fd, EC_IOCTL_DOMAIN_QUEUE, domain->index);
if (EC_IOCTL_IS_ERROR(ret)) {
fprintf(stderr, "Failed to queue domain: %s\n",
strerror(EC_IOCTL_ERRNO(ret)));
}
}
@@ -122,13 +126,15 @@ void ecrt_domain_queue(ec_domain_t *domain)
void ecrt_domain_state(const ec_domain_t *domain, ec_domain_state_t *state)
{
ec_ioctl_domain_state_t data;
int ret;
data.domain_index = domain->index;
data.state = state;
if (ioctl(domain->master->fd, EC_IOCTL_DOMAIN_STATE, &data) == -1) {
ret = ioctl(domain->master->fd, EC_IOCTL_DOMAIN_STATE, &data);
if (EC_IOCTL_IS_ERROR(ret)) {
fprintf(stderr, "Failed to get domain state: %s\n",
strerror(errno));
strerror(EC_IOCTL_ERRNO(ret)));
}
}
+73
View File
@@ -0,0 +1,73 @@
/******************************************************************************
*
* $Id$
*
* Copyright (C) 2006-2012 Florian Pose, Ingenieurgemeinschaft IgH
*
* This file is part of the IgH EtherCAT master userspace library.
*
* The IgH EtherCAT master userspace library is free software; you can
* redistribute it and/or modify it under the terms of the GNU Lesser General
* Public License as published by the Free Software Foundation; version 2.1
* of the License.
*
* The IgH EtherCAT master userspace library is distributed in the hope that
* it will be useful, but WITHOUT ANY WARRANTY; without even the implied
* warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with the IgH EtherCAT master userspace library. If not, see
* <http://www.gnu.org/licenses/>.
*
* ---
*
* The license mentioned above concerns the source code only. Using the
* EtherCAT technology and brand is only permitted in compliance with the
* industrial property and similar rights of Beckhoff Automation GmbH.
*
*****************************************************************************/
#ifndef __EC_LIB_IOCTL_H__
#define __EC_LIB_IOCTL_H__
/*****************************************************************************/
#ifdef USE_RTDM
#include <rtdm/rtdm.h>
#else
#include <sys/ioctl.h>
#endif
/*****************************************************************************/
#include "master/ioctl.h"
/*****************************************************************************/
#ifdef USE_RTDM
#define ioctl rt_dev_ioctl
/* rt_dev_ioctl() returns negative error code */
#define EC_IOCTL_IS_ERROR(X) ((X) < 0)
#define EC_IOCTL_ERRNO(X) (-(X))
#else
#define ioctl ioctl
/* libc's ioctl() always returns -1 on error and sets errno */
#define EC_IOCTL_IS_ERROR(X) ((X) == -1)
#define EC_IOCTL_ERRNO(X) (errno)
#include <errno.h>
#endif
/*****************************************************************************/
#endif /* __EC_LIB_IOCTL_H__ */
/*****************************************************************************/
+164 -81
View File
File diff suppressed because it is too large Load Diff
+28 -19
View File
@@ -2,7 +2,7 @@
*
* $Id$
*
* Copyright (C) 2006-2009 Florian Pose, Ingenieurgemeinschaft IgH
* Copyright (C) 2006-2012 Florian Pose, Ingenieurgemeinschaft IgH
*
* This file is part of the IgH EtherCAT master userspace library.
*
@@ -35,12 +35,10 @@
/*****************************************************************************/
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <sys/ioctl.h>
#include "ioctl.h"
#include "sdo_request.h"
#include "master/ioctl.h"
#include "slave_config.h"
#include "master.h"
@@ -60,15 +58,17 @@ void ec_sdo_request_clear(ec_sdo_request_t *req)
void ecrt_sdo_request_timeout(ec_sdo_request_t *req, uint32_t timeout)
{
ec_ioctl_sdo_request_t data;
int ret;
data.config_index = req->config->index;
data.request_index = req->index;
data.timeout = timeout;
if (ioctl(req->config->master->fd, EC_IOCTL_SDO_REQUEST_TIMEOUT,
&data) == -1)
ret = ioctl(req->config->master->fd, EC_IOCTL_SDO_REQUEST_TIMEOUT, &data);
if (EC_IOCTL_IS_ERROR(ret)) {
fprintf(stderr, "Failed to set SDO request timeout: %s\n",
strerror(errno));
strerror(EC_IOCTL_ERRNO(ret)));
}
}
/*****************************************************************************/
@@ -90,14 +90,17 @@ size_t ecrt_sdo_request_data_size(const ec_sdo_request_t *req)
ec_request_state_t ecrt_sdo_request_state(ec_sdo_request_t *req)
{
ec_ioctl_sdo_request_t data;
int ret;
data.config_index = req->config->index;
data.request_index = req->index;
if (ioctl(req->config->master->fd, EC_IOCTL_SDO_REQUEST_STATE,
&data) == -1)
ret = ioctl(req->config->master->fd, EC_IOCTL_SDO_REQUEST_STATE, &data);
if (EC_IOCTL_IS_ERROR(ret)) {
fprintf(stderr, "Failed to get SDO request state: %s\n",
strerror(errno));
strerror(EC_IOCTL_ERRNO(ret)));
return EC_REQUEST_ERROR;
}
if (data.size) { // new data waiting to be copied
if (req->mem_size < data.size) {
@@ -108,9 +111,11 @@ ec_request_state_t ecrt_sdo_request_state(ec_sdo_request_t *req)
data.data = req->data;
if (ioctl(req->config->master->fd, EC_IOCTL_SDO_REQUEST_DATA,
&data) == -1) {
fprintf(stderr, "Failed to get SDO data: %s\n", strerror(errno));
ret = ioctl(req->config->master->fd,
EC_IOCTL_SDO_REQUEST_DATA, &data);
if (EC_IOCTL_IS_ERROR(ret)) {
fprintf(stderr, "Failed to get SDO data: %s\n",
strerror(EC_IOCTL_ERRNO(ret)));
return EC_REQUEST_ERROR;
}
req->data_size = data.size;
@@ -124,14 +129,16 @@ ec_request_state_t ecrt_sdo_request_state(ec_sdo_request_t *req)
void ecrt_sdo_request_read(ec_sdo_request_t *req)
{
ec_ioctl_sdo_request_t data;
int ret;
data.config_index = req->config->index;
data.request_index = req->index;
if (ioctl(req->config->master->fd, EC_IOCTL_SDO_REQUEST_READ,
&data) == -1)
ret = ioctl(req->config->master->fd, EC_IOCTL_SDO_REQUEST_READ, &data);
if (EC_IOCTL_IS_ERROR(ret)) {
fprintf(stderr, "Failed to command an SDO read operation : %s\n",
strerror(errno));
strerror(EC_IOCTL_ERRNO(ret)));
}
}
/*****************************************************************************/
@@ -139,16 +146,18 @@ void ecrt_sdo_request_read(ec_sdo_request_t *req)
void ecrt_sdo_request_write(ec_sdo_request_t *req)
{
ec_ioctl_sdo_request_t data;
int ret;
data.config_index = req->config->index;
data.request_index = req->index;
data.data = req->data;
data.size = req->data_size;
if (ioctl(req->config->master->fd, EC_IOCTL_SDO_REQUEST_WRITE,
&data) == -1)
ret = ioctl(req->config->master->fd, EC_IOCTL_SDO_REQUEST_WRITE, &data);
if (EC_IOCTL_IS_ERROR(ret)) {
fprintf(stderr, "Failed to command an SDO write operation : %s\n",
strerror(errno));
strerror(EC_IOCTL_ERRNO(ret)));
}
}
/*****************************************************************************/
+69 -40
View File
File diff suppressed because it is too large Load Diff
+30 -21
View File
@@ -2,7 +2,7 @@
*
* $Id$
*
* Copyright (C) 2006-2009 Florian Pose, Ingenieurgemeinschaft IgH
* Copyright (C) 2006-2012 Florian Pose, Ingenieurgemeinschaft IgH
*
* This file is part of the IgH EtherCAT master userspace library.
*
@@ -35,15 +35,13 @@
/*****************************************************************************/
#include <stdlib.h>
#include <sys/ioctl.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include "ioctl.h"
#include "voe_handler.h"
#include "slave_config.h"
#include "master.h"
#include "master/ioctl.h"
/*****************************************************************************/
@@ -60,16 +58,17 @@ void ecrt_voe_handler_send_header(ec_voe_handler_t *voe, uint32_t vendor_id,
uint16_t vendor_type)
{
ec_ioctl_voe_t data;
int ret;
data.config_index = voe->config->index;
data.voe_index = voe->index;
data.vendor_id = &vendor_id;
data.vendor_type = &vendor_type;
if (ioctl(voe->config->master->fd,
EC_IOCTL_VOE_SEND_HEADER, &data) == -1) {
ret = ioctl(voe->config->master->fd, EC_IOCTL_VOE_SEND_HEADER, &data);
if (EC_IOCTL_IS_ERROR(ret)) {
fprintf(stderr, "Failed to set VoE send header: %s\n",
strerror(errno));
strerror(EC_IOCTL_ERRNO(ret)));
}
}
@@ -79,16 +78,17 @@ void ecrt_voe_handler_received_header(const ec_voe_handler_t *voe,
uint32_t *vendor_id, uint16_t *vendor_type)
{
ec_ioctl_voe_t data;
int ret;
data.config_index = voe->config->index;
data.voe_index = voe->index;
data.vendor_id = vendor_id;
data.vendor_type = vendor_type;
if (ioctl(voe->config->master->fd,
EC_IOCTL_VOE_REC_HEADER, &data) == -1) {
ret = ioctl(voe->config->master->fd, EC_IOCTL_VOE_REC_HEADER, &data);
if (EC_IOCTL_IS_ERROR(ret)) {
fprintf(stderr, "Failed to get received VoE header: %s\n",
strerror(errno));
strerror(EC_IOCTL_ERRNO(ret)));
}
}
@@ -111,13 +111,15 @@ size_t ecrt_voe_handler_data_size(const ec_voe_handler_t *voe)
void ecrt_voe_handler_read(ec_voe_handler_t *voe)
{
ec_ioctl_voe_t data;
int ret;
data.config_index = voe->config->index;
data.voe_index = voe->index;
if (ioctl(voe->config->master->fd, EC_IOCTL_VOE_READ, &data) == -1) {
ret = ioctl(voe->config->master->fd, EC_IOCTL_VOE_READ, &data);
if (EC_IOCTL_IS_ERROR(ret)) {
fprintf(stderr, "Failed to initiate VoE reading: %s\n",
strerror(errno));
strerror(EC_IOCTL_ERRNO(ret)));
}
}
@@ -126,14 +128,15 @@ void ecrt_voe_handler_read(ec_voe_handler_t *voe)
void ecrt_voe_handler_read_nosync(ec_voe_handler_t *voe)
{
ec_ioctl_voe_t data;
int ret;
data.config_index = voe->config->index;
data.voe_index = voe->index;
if (ioctl(voe->config->master->fd,
EC_IOCTL_VOE_READ_NOSYNC, &data) == -1) {
ret = ioctl(voe->config->master->fd, EC_IOCTL_VOE_READ_NOSYNC, &data);
if (EC_IOCTL_IS_ERROR(ret)) {
fprintf(stderr, "Failed to initiate VoE reading: %s\n",
strerror(errno));
strerror(EC_IOCTL_ERRNO(ret)));
}
}
@@ -142,15 +145,17 @@ void ecrt_voe_handler_read_nosync(ec_voe_handler_t *voe)
void ecrt_voe_handler_write(ec_voe_handler_t *voe, size_t size)
{
ec_ioctl_voe_t data;
int ret;
data.config_index = voe->config->index;
data.voe_index = voe->index;
data.size = size;
data.data = voe->data;
if (ioctl(voe->config->master->fd, EC_IOCTL_VOE_WRITE, &data) == -1) {
ret = ioctl(voe->config->master->fd, EC_IOCTL_VOE_WRITE, &data);
if (EC_IOCTL_IS_ERROR(ret)) {
fprintf(stderr, "Failed to initiate VoE writing: %s\n",
strerror(errno));
strerror(EC_IOCTL_ERRNO(ret)));
}
}
@@ -159,13 +164,15 @@ void ecrt_voe_handler_write(ec_voe_handler_t *voe, size_t size)
ec_request_state_t ecrt_voe_handler_execute(ec_voe_handler_t *voe)
{
ec_ioctl_voe_t data;
int ret;
data.config_index = voe->config->index;
data.voe_index = voe->index;
if (ioctl(voe->config->master->fd, EC_IOCTL_VOE_EXEC, &data) == -1) {
ret = ioctl(voe->config->master->fd, EC_IOCTL_VOE_EXEC, &data);
if (EC_IOCTL_IS_ERROR(ret)) {
fprintf(stderr, "Failed to execute VoE handler: %s\n",
strerror(errno));
strerror(EC_IOCTL_ERRNO(ret)));
return EC_REQUEST_ERROR;
}
@@ -178,8 +185,10 @@ ec_request_state_t ecrt_voe_handler_execute(ec_voe_handler_t *voe)
data.data = voe->data;
if (ioctl(voe->config->master->fd, EC_IOCTL_VOE_DATA, &data) == -1) {
fprintf(stderr, "Failed to get VoE data: %s\n", strerror(errno));
ret = ioctl(voe->config->master->fd, EC_IOCTL_VOE_DATA, &data);
if (EC_IOCTL_IS_ERROR(ret)) {
fprintf(stderr, "Failed to get VoE data: %s\n",
strerror(EC_IOCTL_ERRNO(ret)));
return EC_REQUEST_ERROR;
}
voe->data_size = data.size;