diff --git a/examples/user/main.c b/examples/user/main.c index 7c69c29575488e3f4084d5af6c3de03e524a7db4..f545a1c6e008b2c492290ebe47a3bea2bbe2ed63 100644 --- a/examples/user/main.c +++ b/examples/user/main.c @@ -4,15 +4,39 @@ * ****************************************************************************/ +#include <unistd.h> +#include <sys/time.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> +#include <signal.h> + #include "ecrt.h" /****************************************************************************/ +static unsigned int sig_alarms = 0; +static unsigned int user_alarms = 0; + +/****************************************************************************/ + +void signal_handler(int signum) { + switch (signum) { + case SIGALRM: + sig_alarms++; + break; + } +} + +/****************************************************************************/ + int main(int argc, char **argv) { ec_master_t *master; ec_domain_t *domain; ec_slave_config_t *sc; + struct sigaction sa; + struct itimerval tv; master = ecrt_request_master(0); if (!master) @@ -26,8 +50,41 @@ int main(int argc, char **argv) if (!sc) return -1; + if (ecrt_master_activate(master)) + return -1; + + sa.sa_handler = signal_handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = 0; + if (sigaction(SIGALRM, &sa, 0)) { + fprintf(stderr, "Failed to install signal handler!\n"); + return -1; + } + + tv.it_interval.tv_sec = 0; + tv.it_interval.tv_usec = 10000; + tv.it_value.tv_sec = 0; + tv.it_value.tv_usec = 1; + if (setitimer(ITIMER_REAL, &tv, NULL)) { + fprintf(stderr, "Failed to start timer: %s\n", strerror(errno)); + return 1; + } + while (1) { - sleep(1); + sleep(1); + + while (sig_alarms != user_alarms) { + +#if 0 + struct timeval t; + gettimeofday(&t, NULL); + printf("%u %u\n", t.tv_sec, t.tv_usec); +#endif + ecrt_master_receive(master); + ecrt_master_send(master); + + user_alarms++; + } } return 0; diff --git a/lib/master.c b/lib/master.c index eb28d83d5acb85b6d2a9c66036282cf94cefc018..3be9c33cb66f94af7abc71afa435a3029d27b60f 100644 --- a/lib/master.c +++ b/lib/master.c @@ -102,6 +102,12 @@ ec_slave_config_t *ecrt_master_slave_config(ec_master_t *master, int ecrt_master_activate(ec_master_t *master) { + if (ioctl(master->fd, EC_IOCTL_ACTIVATE, NULL) == -1) { + fprintf(stderr, "Failed to activate master: %s\n", + strerror(errno)); + return -1; + } + return 0; } @@ -109,12 +115,18 @@ int ecrt_master_activate(ec_master_t *master) void ecrt_master_send(ec_master_t *master) { + if (ioctl(master->fd, EC_IOCTL_SEND, NULL) == -1) { + fprintf(stderr, "Failed to send: %s\n", strerror(errno)); + } } /*****************************************************************************/ void ecrt_master_receive(ec_master_t *master) { + if (ioctl(master->fd, EC_IOCTL_RECEIVE, NULL) == -1) { + fprintf(stderr, "Failed to receive: %s\n", strerror(errno)); + } } /*****************************************************************************/ @@ -123,5 +135,4 @@ void ecrt_master_state(const ec_master_t *master, ec_master_state_t *state) { } - /*****************************************************************************/ diff --git a/master/cdev.c b/master/cdev.c index 76ac1ee07846b5edddbbe1dcd2612b01c8c8d854..7999a1de8c9ab1a55803b83e20a23b50232e44da 100644 --- a/master/cdev.c +++ b/master/cdev.c @@ -1452,6 +1452,63 @@ int ec_cdev_ioctl_create_slave_config( return 0; } +/*****************************************************************************/ + +/** Activates the master. + */ +int ec_cdev_ioctl_activate( + ec_master_t *master, /**< EtherCAT master. */ + unsigned long arg, /**< ioctl() argument. */ + ec_cdev_priv_t *priv /**< Private data structure of file handle. */ + ) +{ + if (unlikely(!priv->requested)) + return -EPERM; + + if (ecrt_master_activate(master)) + return -EIO; + + return 0; +} + +/*****************************************************************************/ + +/** Send frames. + */ +int ec_cdev_ioctl_send( + ec_master_t *master, /**< EtherCAT master. */ + unsigned long arg, /**< ioctl() argument. */ + ec_cdev_priv_t *priv /**< Private data structure of file handle. */ + ) +{ + if (unlikely(!priv->requested)) + return -EPERM; + + spin_lock_bh(&master->internal_lock); + ecrt_master_send(master); + spin_unlock_bh(&master->internal_lock); + return 0; +} + +/*****************************************************************************/ + +/** Receive frames. + */ +int ec_cdev_ioctl_receive( + ec_master_t *master, /**< EtherCAT master. */ + unsigned long arg, /**< ioctl() argument. */ + ec_cdev_priv_t *priv /**< Private data structure of file handle. */ + ) +{ + if (unlikely(!priv->requested)) + return -EPERM; + + spin_lock_bh(&master->internal_lock); + ecrt_master_receive(master); + spin_unlock_bh(&master->internal_lock); + return 0; +} + /****************************************************************************** * File operations *****************************************************************************/ @@ -1577,6 +1634,18 @@ long eccdev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (!(filp->f_mode & FMODE_WRITE)) return -EPERM; return ec_cdev_ioctl_create_slave_config(master, arg, priv); + case EC_IOCTL_ACTIVATE: + if (!(filp->f_mode & FMODE_WRITE)) + return -EPERM; + return ec_cdev_ioctl_activate(master, arg, priv); + case EC_IOCTL_SEND: + if (!(filp->f_mode & FMODE_WRITE)) + return -EPERM; + return ec_cdev_ioctl_send(master, arg, priv); + case EC_IOCTL_RECEIVE: + if (!(filp->f_mode & FMODE_WRITE)) + return -EPERM; + return ec_cdev_ioctl_receive(master, arg, priv); default: return -ENOTTY; } diff --git a/master/ioctl.h b/master/ioctl.h index a261c9629c5004d5e9e58c3a28748c6c1c385beb..2188a77ec0b449d1c7dfa30077257d4989293ac7 100644 --- a/master/ioctl.h +++ b/master/ioctl.h @@ -82,6 +82,9 @@ #define EC_IOCTL_REQUEST EC_IO(0x16) #define EC_IOCTL_CREATE_DOMAIN EC_IO(0x17) #define EC_IOCTL_CREATE_SLAVE_CONFIG EC_IOWR(0x18, ec_ioctl_config_t) +#define EC_IOCTL_ACTIVATE EC_IO(0x19) +#define EC_IOCTL_SEND EC_IO(0x1a) +#define EC_IOCTL_RECEIVE EC_IO(0x1b) #define EC_IOCTL_STRING_SIZE 64