Add ccat driver for Beckhoff CCAT communication controller in Beckhoff CX20xx device stable-1.5
authorPatrick Bruenn <p.bruenn@beckhoff.com>
Fri, 04 Apr 2014 08:32:09 +0200
branchstable-1.5
changeset 2549 933a1b36b05f
parent 2526 2eff7c993a63
child 2550 7e25950ea941
Add ccat driver for Beckhoff CCAT communication controller in Beckhoff CX20xx device
configure.ac
devices/Kbuild.in
devices/Makefile.am
devices/ccat/CCatDefinitions.h
devices/ccat/COPYING
devices/ccat/Kbuild.in
devices/ccat/Makefile.am
devices/ccat/module-3.4-ethercat.c
devices/ccat/module.h
devices/ccat/netdev-3.4-ethercat.c
devices/ccat/netdev.h
devices/ccat/print-3.4-ethercat.c
devices/ccat/print.h
devices/ccat/update-3.4-ethercat.c
devices/ccat/update.h
examples/user/main.c
--- a/configure.ac	Tue Feb 12 17:31:08 2013 +0100
+++ b/configure.ac	Fri Apr 04 08:32:09 2014 +0200
@@ -212,6 +212,61 @@
 AC_SUBST(KERNEL_8139TOO,[$kernel8139too])
 
 #------------------------------------------------------------------------------
+# CCAT driver
+#------------------------------------------------------------------------------
+
+AC_ARG_ENABLE([ccat],
+    AS_HELP_STRING([--enable-ccat],
+                   [Enable CCAT driver]),
+    [
+        case "${enableval}" in
+            yes) enableccat=1
+                ;;
+            no) enableccat=0
+                ;;
+            *) AC_MSG_ERROR([Invalid value for --enable-ccat])
+                ;;
+        esac
+    ],
+    [enableccat=0] # disabled by default
+)
+
+AM_CONDITIONAL(ENABLE_CCAT, test "x$enableccat" = "x1")
+AC_SUBST(ENABLE_CCAT,[$enableccat])
+
+AC_ARG_WITH([ccat-kernel],
+    AC_HELP_STRING(
+        [--with-ccat-kernel=<X.Y.Z>],
+        [ccat kernel (only if differing)]
+    ),
+    [
+        kernelccat=[$withval]
+    ],
+    [
+        kernelccat=$linuxversion
+    ]
+)
+
+if test "x${enableccat}" = "x1"; then
+    AC_MSG_CHECKING([for kernel for ccat driver])
+
+    kernels=`ls -1 ${srcdir}/devices/ccat/ | grep -oE "^netdev-.*" | cut -d "-" -f 2 | uniq`
+    found=0
+    for k in $kernels; do
+        if test "$kernelccat" = "$k"; then
+            found=1
+        fi
+    done
+    if test $found -ne 1; then
+        AC_MSG_ERROR([kernel $kernelccat not available for ccat driver!])
+    fi
+
+    AC_MSG_RESULT([$kernelccat])
+fi
+
+AC_SUBST(KERNEL_CCAT,[$kernelccat])
+
+#------------------------------------------------------------------------------
 # e100 driver
 #------------------------------------------------------------------------------
 
@@ -939,6 +994,8 @@
         Makefile
         devices/Kbuild
         devices/Makefile
+        devices/ccat/Kbuild
+        devices/ccat/Makefile
         devices/e1000/Kbuild
         devices/e1000/Makefile
         devices/e1000e/Kbuild
--- a/devices/Kbuild.in	Tue Feb 12 17:31:08 2013 +0100
+++ b/devices/Kbuild.in	Fri Apr 04 08:32:09 2014 +0200
@@ -51,6 +51,10 @@
 	CFLAGS_$(EC_8139TOO_OBJ) = -DREV=$(REV)
 endif
 
+ifeq (@ENABLE_CCAT@,1)
+	obj-m += ccat/
+endif
+
 ifeq (@ENABLE_E100@,1)
 	EC_E100_OBJ := e100-@KERNEL_E100@-ethercat.o
 	obj-m += ec_e100.o
--- a/devices/Makefile.am	Tue Feb 12 17:31:08 2013 +0100
+++ b/devices/Makefile.am	Fri Apr 04 08:32:09 2014 +0200
@@ -28,10 +28,12 @@
 #------------------------------------------------------------------------------
 
 SUBDIRS = \
+	ccat \
 	e1000 \
 	e1000e
 
 DIST_SUBDIRS = \
+	ccat \
 	e1000 \
 	e1000e
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/devices/ccat/CCatDefinitions.h	Fri Apr 04 08:32:09 2014 +0200
@@ -0,0 +1,1 @@
+../../../ccat/CCatDefinitions.h
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/devices/ccat/COPYING	Fri Apr 04 08:32:09 2014 +0200
@@ -0,0 +1,1 @@
+../../../ccat/COPYING
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/devices/ccat/Kbuild.in	Fri Apr 04 08:32:09 2014 +0200
@@ -0,0 +1,57 @@
+#------------------------------------------------------------------------------
+#
+#  $Id$
+#
+#  Copyright (C) 2006-2008  Florian Pose, Ingenieurgemeinschaft IgH
+#
+#  This file is part of the IgH EtherCAT Master.
+#
+#  The IgH EtherCAT Master is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License version 2, as
+#  published by the Free Software Foundation.
+#
+#  The IgH EtherCAT Master 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 General
+#  Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License along
+#  with the IgH EtherCAT Master; if not, write to the Free Software
+#  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#
+#  ---
+#
+#  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.
+#
+#  ---
+#
+#  vim: syntax=make
+#
+#------------------------------------------------------------------------------
+
+TOPDIR := $(src)/../..
+
+REV := $(shell if test -s $(TOPDIR)/revision; then \
+		cat $(TOPDIR)/revision; \
+	else \
+		hg id -i $(TOPDIR) 2>/dev/null || echo "unknown"; \
+	fi)
+
+ifeq (@ENABLE_CCAT@,1)
+	EC_CCAT_OBJ := \
+		module-@KERNEL_E1000@-ethercat.o \
+		netdev-@KERNEL_E1000@-ethercat.o \
+		print-@KERNEL_E1000@-ethercat.o \
+		update-@KERNEL_E1000@-ethercat.o
+	obj-m += ec_ccat.o
+	ec_ccat-objs := $(EC_CCAT_OBJ)
+	CFLAGS_ccat_main-@KERNEL_CCAT@-ethercat.o = -DREV=$(REV)
+endif
+
+KBUILD_EXTRA_SYMBOLS := \
+	@abs_top_builddir@/$(LINUX_SYMVERS) \
+	@abs_top_builddir@/master/$(LINUX_SYMVERS)
+
+#------------------------------------------------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/devices/ccat/Makefile.am	Fri Apr 04 08:32:09 2014 +0200
@@ -0,0 +1,55 @@
+#------------------------------------------------------------------------------
+#
+#  $Id$
+#
+#  Copyright (C) 2006-2008  Florian Pose, Ingenieurgemeinschaft IgH
+#
+#  This file is part of the IgH EtherCAT Master.
+#
+#  The IgH EtherCAT Master is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License version 2, as
+#  published by the Free Software Foundation.
+#
+#  The IgH EtherCAT Master 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 General
+#  Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License along
+#  with the IgH EtherCAT Master; if not, write to the Free Software
+#  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+#
+#  ---
+#
+#  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.
+#
+#------------------------------------------------------------------------------
+
+EXTRA_DIST = \
+	Kbuild.in \
+	COPYING \
+	module-3.4-ethercat.h \
+	module.h \
+	netdev-3.4-ethercat.h \
+	netdev.h \
+	print-3.4-ethercat.h \
+	print.h \
+	update-3.4-ethercat.h \
+	update.h
+
+BUILT_SOURCES = \
+	Kbuild
+
+modules:
+	$(MAKE) -C "$(LINUX_SOURCE_DIR)" M="@abs_srcdir@" modules
+
+modules_install:
+	$(MAKE) -C "$(LINUX_SOURCE_DIR)" M="@abs_srcdir@" \
+		INSTALL_MOD_DIR="$(INSTALL_MOD_DIR)" modules_install
+
+clean-local:
+	$(MAKE) -C "$(LINUX_SOURCE_DIR)" M="@abs_srcdir@" clean
+
+#------------------------------------------------------------------------------
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/devices/ccat/module-3.4-ethercat.c	Fri Apr 04 08:32:09 2014 +0200
@@ -0,0 +1,1 @@
+../../../ccat/module.c
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/devices/ccat/module.h	Fri Apr 04 08:32:09 2014 +0200
@@ -0,0 +1,1 @@
+../../../ccat/module.h
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/devices/ccat/netdev-3.4-ethercat.c	Fri Apr 04 08:32:09 2014 +0200
@@ -0,0 +1,1 @@
+../../../ccat/netdev.c
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/devices/ccat/netdev.h	Fri Apr 04 08:32:09 2014 +0200
@@ -0,0 +1,1 @@
+../../../ccat/netdev.h
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/devices/ccat/print-3.4-ethercat.c	Fri Apr 04 08:32:09 2014 +0200
@@ -0,0 +1,1 @@
+../../../ccat/print.c
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/devices/ccat/print.h	Fri Apr 04 08:32:09 2014 +0200
@@ -0,0 +1,1 @@
+../../../ccat/print.h
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/devices/ccat/update-3.4-ethercat.c	Fri Apr 04 08:32:09 2014 +0200
@@ -0,0 +1,1 @@
+../../../ccat/update.c
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/devices/ccat/update.h	Fri Apr 04 08:32:09 2014 +0200
@@ -0,0 +1,1 @@
+../../../ccat/update.h
\ No newline at end of file
--- a/examples/user/main.c	Tue Feb 12 17:31:08 2013 +0100
+++ b/examples/user/main.c	Fri Apr 04 08:32:09 2014 +0200
@@ -1,436 +1,1 @@
-/*****************************************************************************
- *
- *  $Id$
- *
- *  Copyright (C) 2007-2009  Florian Pose, Ingenieurgemeinschaft IgH
- *
- *  This file is part of the IgH EtherCAT Master.
- *
- *  The IgH EtherCAT Master is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU General Public License version 2, as
- *  published by the Free Software Foundation.
- *
- *  The IgH EtherCAT Master 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 General
- *  Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License along
- *  with the IgH EtherCAT Master; if not, write to the Free Software
- *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
- *
- *  ---
- *
- *  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.
- *
- ****************************************************************************/
-
-#include <errno.h>
-#include <signal.h>
-#include <stdio.h>
-#include <string.h>
-#include <sys/resource.h>
-#include <sys/time.h>
-#include <sys/types.h>
-#include <unistd.h>
-
-/****************************************************************************/
-
-#include "ecrt.h"
-
-/****************************************************************************/
-
-// Application parameters
-#define FREQUENCY 100
-#define PRIORITY 1
-
-// Optional features
-#define CONFIGURE_PDOS  1
-#define SDO_ACCESS      0
-
-/****************************************************************************/
-
-// EtherCAT
-static ec_master_t *master = NULL;
-static ec_master_state_t master_state = {};
-
-static ec_domain_t *domain1 = NULL;
-static ec_domain_state_t domain1_state = {};
-
-static ec_slave_config_t *sc_ana_in = NULL;
-static ec_slave_config_state_t sc_ana_in_state = {};
-
-// Timer
-static unsigned int sig_alarms = 0;
-static unsigned int user_alarms = 0;
-
-/****************************************************************************/
-
-// process data
-static uint8_t *domain1_pd = NULL;
-
-#define BusCouplerPos  0, 0
-#define DigOutSlavePos 0, 2
-#define AnaInSlavePos  0, 3
-#define AnaOutSlavePos 0, 4
-
-#define Beckhoff_EK1100 0x00000002, 0x044c2c52
-#define Beckhoff_EL2004 0x00000002, 0x07d43052
-#define Beckhoff_EL2032 0x00000002, 0x07f03052
-#define Beckhoff_EL3152 0x00000002, 0x0c503052
-#define Beckhoff_EL3102 0x00000002, 0x0c1e3052
-#define Beckhoff_EL4102 0x00000002, 0x10063052
-
-// offsets for PDO entries
-static unsigned int off_ana_in_status;
-static unsigned int off_ana_in_value;
-static unsigned int off_ana_out;
-static unsigned int off_dig_out;
-
-const static ec_pdo_entry_reg_t domain1_regs[] = {
-    {AnaInSlavePos,  Beckhoff_EL3102, 0x3101, 1, &off_ana_in_status},
-    {AnaInSlavePos,  Beckhoff_EL3102, 0x3101, 2, &off_ana_in_value},
-    {AnaOutSlavePos, Beckhoff_EL4102, 0x3001, 1, &off_ana_out},
-    {DigOutSlavePos, Beckhoff_EL2032, 0x3001, 1, &off_dig_out},
-    {}
-};
-
-static unsigned int counter = 0;
-static unsigned int blink = 0;
-
-/*****************************************************************************/
-
-#if CONFIGURE_PDOS
-
-// Analog in --------------------------
-
-static ec_pdo_entry_info_t el3102_pdo_entries[] = {
-    {0x3101, 1,  8}, // channel 1 status
-    {0x3101, 2, 16}, // channel 1 value
-    {0x3102, 1,  8}, // channel 2 status
-    {0x3102, 2, 16}, // channel 2 value
-    {0x6401, 1, 16}, // channel 1 value (alt.)
-    {0x6401, 2, 16}  // channel 2 value (alt.)
-};
-
-static ec_pdo_info_t el3102_pdos[] = {
-    {0x1A00, 2, el3102_pdo_entries},
-    {0x1A01, 2, el3102_pdo_entries + 2}
-};
-
-static ec_sync_info_t el3102_syncs[] = {
-    {2, EC_DIR_OUTPUT},
-    {3, EC_DIR_INPUT, 2, el3102_pdos},
-    {0xff}
-};
-
-// Analog out -------------------------
-
-static ec_pdo_entry_info_t el4102_pdo_entries[] = {
-    {0x3001, 1, 16}, // channel 1 value
-    {0x3002, 1, 16}, // channel 2 value
-};
-
-static ec_pdo_info_t el4102_pdos[] = {
-    {0x1600, 1, el4102_pdo_entries},
-    {0x1601, 1, el4102_pdo_entries + 1}
-};
-
-static ec_sync_info_t el4102_syncs[] = {
-    {2, EC_DIR_OUTPUT, 2, el4102_pdos},
-    {3, EC_DIR_INPUT},
-    {0xff}
-};
-
-// Digital out ------------------------
-
-static ec_pdo_entry_info_t el2004_channels[] = {
-    {0x3001, 1, 1}, // Value 1
-    {0x3001, 2, 1}, // Value 2
-    {0x3001, 3, 1}, // Value 3
-    {0x3001, 4, 1}  // Value 4
-};
-
-static ec_pdo_info_t el2004_pdos[] = {
-    {0x1600, 1, &el2004_channels[0]},
-    {0x1601, 1, &el2004_channels[1]},
-    {0x1602, 1, &el2004_channels[2]},
-    {0x1603, 1, &el2004_channels[3]}
-};
-
-static ec_sync_info_t el2004_syncs[] = {
-    {0, EC_DIR_OUTPUT, 4, el2004_pdos},
-    {1, EC_DIR_INPUT},
-    {0xff}
-};
-#endif
-
-/*****************************************************************************/
-
-#if SDO_ACCESS
-static ec_sdo_request_t *sdo;
-#endif
-
-/*****************************************************************************/
-
-void check_domain1_state(void)
-{
-    ec_domain_state_t ds;
-
-    ecrt_domain_state(domain1, &ds);
-
-    if (ds.working_counter != domain1_state.working_counter)
-        printf("Domain1: WC %u.\n", ds.working_counter);
-    if (ds.wc_state != domain1_state.wc_state)
-        printf("Domain1: State %u.\n", ds.wc_state);
-
-    domain1_state = ds;
-}
-
-/*****************************************************************************/
-
-void check_master_state(void)
-{
-    ec_master_state_t ms;
-
-    ecrt_master_state(master, &ms);
-
-    if (ms.slaves_responding != master_state.slaves_responding)
-        printf("%u slave(s).\n", ms.slaves_responding);
-    if (ms.al_states != master_state.al_states)
-        printf("AL states: 0x%02X.\n", ms.al_states);
-    if (ms.link_up != master_state.link_up)
-        printf("Link is %s.\n", ms.link_up ? "up" : "down");
-
-    master_state = ms;
-}
-
-/*****************************************************************************/
-
-void check_slave_config_states(void)
-{
-    ec_slave_config_state_t s;
-
-    ecrt_slave_config_state(sc_ana_in, &s);
-
-    if (s.al_state != sc_ana_in_state.al_state)
-        printf("AnaIn: State 0x%02X.\n", s.al_state);
-    if (s.online != sc_ana_in_state.online)
-        printf("AnaIn: %s.\n", s.online ? "online" : "offline");
-    if (s.operational != sc_ana_in_state.operational)
-        printf("AnaIn: %soperational.\n",
-                s.operational ? "" : "Not ");
-
-    sc_ana_in_state = s;
-}
-
-/*****************************************************************************/
-
-#if SDO_ACCESS
-void read_sdo(void)
-{
-    switch (ecrt_sdo_request_state(sdo)) {
-        case EC_REQUEST_UNUSED: // request was not used yet
-            ecrt_sdo_request_read(sdo); // trigger first read
-            break;
-        case EC_REQUEST_BUSY:
-            fprintf(stderr, "Still busy...\n");
-            break;
-        case EC_REQUEST_SUCCESS:
-            fprintf(stderr, "SDO value: 0x%04X\n",
-                    EC_READ_U16(ecrt_sdo_request_data(sdo)));
-            ecrt_sdo_request_read(sdo); // trigger next read
-            break;
-        case EC_REQUEST_ERROR:
-            fprintf(stderr, "Failed to read SDO!\n");
-            ecrt_sdo_request_read(sdo); // retry reading
-            break;
-    }
-}
-#endif
-
-/****************************************************************************/
-
-void cyclic_task()
-{
-    // receive process data
-    ecrt_master_receive(master);
-    ecrt_domain_process(domain1);
-
-    // check process data state (optional)
-    check_domain1_state();
-
-    if (counter) {
-        counter--;
-    } else { // do this at 1 Hz
-        counter = FREQUENCY;
-
-        // calculate new process data
-        blink = !blink;
-
-        // check for master state (optional)
-        check_master_state();
-
-        // check for islave configuration state(s) (optional)
-        check_slave_config_states();
-
-#if SDO_ACCESS
-        // read process data SDO
-        read_sdo();
-#endif
-
-    }
-
-#if 0
-    // read process data
-    printf("AnaIn: state %u value %u\n",
-            EC_READ_U8(domain1_pd + off_ana_in_status),
-            EC_READ_U16(domain1_pd + off_ana_in_value));
-#endif
-
-#if 1
-    // write process data
-    EC_WRITE_U8(domain1_pd + off_dig_out, blink ? 0x06 : 0x09);
-#endif
-
-    // send process data
-    ecrt_domain_queue(domain1);
-    ecrt_master_send(master);
-}
-
-/****************************************************************************/
-
-void signal_handler(int signum) {
-    switch (signum) {
-        case SIGALRM:
-            sig_alarms++;
-            break;
-    }
-}
-
-/****************************************************************************/
-
-int main(int argc, char **argv)
-{
-    ec_slave_config_t *sc;
-    struct sigaction sa;
-    struct itimerval tv;
-
-    master = ecrt_request_master(0);
-    if (!master)
-        return -1;
-
-    domain1 = ecrt_master_create_domain(master);
-    if (!domain1)
-        return -1;
-
-    if (!(sc_ana_in = ecrt_master_slave_config(
-                    master, AnaInSlavePos, Beckhoff_EL3102))) {
-        fprintf(stderr, "Failed to get slave configuration.\n");
-        return -1;
-    }
-
-#if SDO_ACCESS
-    fprintf(stderr, "Creating SDO requests...\n");
-    if (!(sdo = ecrt_slave_config_create_sdo_request(sc_ana_in, 0x3102, 2, 2))) {
-        fprintf(stderr, "Failed to create SDO request.\n");
-        return -1;
-    }
-    ecrt_sdo_request_timeout(sdo, 500); // ms
-#endif
-
-#if CONFIGURE_PDOS
-    printf("Configuring PDOs...\n");
-    if (ecrt_slave_config_pdos(sc_ana_in, EC_END, el3102_syncs)) {
-        fprintf(stderr, "Failed to configure PDOs.\n");
-        return -1;
-    }
-
-    if (!(sc = ecrt_master_slave_config(
-                    master, AnaOutSlavePos, Beckhoff_EL4102))) {
-        fprintf(stderr, "Failed to get slave configuration.\n");
-        return -1;
-    }
-
-    if (ecrt_slave_config_pdos(sc, EC_END, el4102_syncs)) {
-        fprintf(stderr, "Failed to configure PDOs.\n");
-        return -1;
-    }
-
-    if (!(sc = ecrt_master_slave_config(
-                    master, DigOutSlavePos, Beckhoff_EL2032))) {
-        fprintf(stderr, "Failed to get slave configuration.\n");
-        return -1;
-    }
-
-    if (ecrt_slave_config_pdos(sc, EC_END, el2004_syncs)) {
-        fprintf(stderr, "Failed to configure PDOs.\n");
-        return -1;
-    }
-#endif
-
-    // Create configuration for bus coupler
-    sc = ecrt_master_slave_config(master, BusCouplerPos, Beckhoff_EK1100);
-    if (!sc)
-        return -1;
-
-    if (ecrt_domain_reg_pdo_entry_list(domain1, domain1_regs)) {
-        fprintf(stderr, "PDO entry registration failed!\n");
-        return -1;
-    }
-
-    printf("Activating master...\n");
-    if (ecrt_master_activate(master))
-        return -1;
-
-    if (!(domain1_pd = ecrt_domain_data(domain1))) {
-        return -1;
-    }
-
-#if PRIORITY
-    pid_t pid = getpid();
-    if (setpriority(PRIO_PROCESS, pid, -19))
-        fprintf(stderr, "Warning: Failed to set priority: %s\n",
-                strerror(errno));
-#endif
-
-    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;
-    }
-
-    printf("Starting timer...\n");
-    tv.it_interval.tv_sec = 0;
-    tv.it_interval.tv_usec = 1000000 / FREQUENCY;
-    tv.it_value.tv_sec = 0;
-    tv.it_value.tv_usec = 1000;
-    if (setitimer(ITIMER_REAL, &tv, NULL)) {
-        fprintf(stderr, "Failed to start timer: %s\n", strerror(errno));
-        return 1;
-    }
-
-    printf("Started.\n");
-    while (1) {
-        pause();
-
-#if 0
-        struct timeval t;
-        gettimeofday(&t, NULL);
-        printf("%u.%06u\n", t.tv_sec, t.tv_usec);
-#endif
-
-        while (sig_alarms != user_alarms) {
-            cyclic_task();
-            user_alarms++;
-        }
-    }
-
-    return 0;
-}
-
-/****************************************************************************/
+../../../ccat/unittest/main.c
\ No newline at end of file