[OSADL-svn-commits] r103 - in trunks/fddi-trunk: . src

OSADL repository commits osadl-svn-commits at lists.osadl.org
Tue Oct 2 11:47:51 CEST 2007


Author: robert
Date: Thu Aug  9 22:59:35 2007
New Revision: 103

Log:
add initial stubs for generic can backend

Added:
   trunks/fddi-trunk/src/libfddi_can.c
Modified:
   trunks/fddi-trunk/configure.ac
   trunks/fddi-trunk/src/GNUmakefile.am

Modified: trunks/fddi-trunk/configure.ac
==============================================================================
--- trunks/fddi-trunk/configure.ac	(original)
+++ trunks/fddi-trunk/configure.ac	Thu Aug  9 22:59:35 2007
@@ -125,10 +125,10 @@
 )
 AC_MSG_RESULT([${CONFIG_DEBUG}])
 if test "${CONFIG_DEBUG}" = "yes"; then
-    CFLAGS="${CFLAGS} -Werror -Wsign-compare -Wfloat-equal -Wformat-security -g -O1"
+    CFLAGS="${CFLAGS} -Wsign-compare -Wfloat-equal -Wformat-security -g -O1"
     AC_DEFINE(DEBUG, 1, [debugging])
 else
-    CFLAGS="${CFLAGS} -O2"
+    CFLAGS="${CFLAGS} -Werror -O2"
 fi
 
 #
@@ -192,6 +192,30 @@
 fi
 
 
+AC_MSG_CHECKING([whether to enable can backend])
+AC_ARG_ENABLE(backend-can,
+    AS_HELP_STRING([--enable-backend-can], [enable can backend @<:@default=no@:>@]),
+    [case "$enableval" in
+        y | yes) CONFIG_BACKEND_CAN=yes ;;
+        *)       CONFIG_BACKEND_CAN=no ;;
+        esac],
+    [CONFIG_BACKEND_CAN=no]
+)
+AM_CONDITIONAL(BACKEND_CAN, test "${CONFIG_BACKEND_CAN}" = "yes")
+AC_MSG_RESULT([${CONFIG_BACKEND_CAN}])
+
+if test "${CONFIG_BACKEND_CAN}" = "yes"; then
+
+    AC_CHECK_HEADER([linux/can.h], have_can_h=yes,, [[
+        #include <sys/socket.h>
+    ]])
+    if test "$have_can_h" != "yes"; then
+        AC_MSG_ERROR([linux/can.h must be available when building with --enable-backend-can])
+    fi
+
+fi
+
+
 AC_CONFIG_FILES([
 	GNUmakefile
 	config/libfddi.pc

Modified: trunks/fddi-trunk/src/GNUmakefile.am
==============================================================================
--- trunks/fddi-trunk/src/GNUmakefile.am	(original)
+++ trunks/fddi-trunk/src/GNUmakefile.am	Thu Aug  9 22:59:35 2007
@@ -2,6 +2,9 @@
 if BACKEND_LIBMODBUS
 BACKEND_LIBS += libfddi_libmodbus.la
 endif
+if BACKEND_CAN
+BACKEND_LIBS += libfddi_can.la
+endif
 
 lib_LTLIBRARIES = \
 	libfddi.la \
@@ -41,9 +44,18 @@
 	$(top_builddir)/src/libfddi.la \
 	$(libmodbus_LIBS)
 
-MAINTAINERCLEANFILES = \
-	GNUmakefile.in
+#
+# libfddi_can
+#
+
+libfddi_can_la_SOURCES = \
+	libfddi_can.c
 
+libfddi_can_la_CPPFLAGS = \
+	-DPF_CAN=29 -DAF_CAN=PF_CAN
 
+# libfddi_can_la_LIBADD =
 
+MAINTAINERCLEANFILES = \
+	GNUmakefile.in
 

Added: trunks/fddi-trunk/src/libfddi_can.c
==============================================================================
--- (empty file)
+++ trunks/fddi-trunk/src/libfddi_can.c	Thu Aug  9 22:59:35 2007
@@ -0,0 +1,363 @@
+/*
+ * fddi backend for arbitrary CAN messages
+ */
+
+/* FIXME: this file is an uggly hack which hardcodes everything, as long
+ * as we have a proper xml parser
+ */
+
+#if 0
+#include <pthread.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <time.h>
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <net/if.h>
+#include <sys/socket.h>
+#include <sys/ioctl.h>
+
+#include <linux/can.h>
+#include <linux/can/raw.h>
+
+#include <osadl/fddi.h>
+
+static fddi_tpu_t tpu1 = {
+	.id = {
+		.prefix = "cantpu",
+		.index = 0,
+		.suffix = "",
+	},
+	.direction = IN,
+	.cycletime = 0,
+};
+
+static fddi_tpu_t tpu2 = {
+	.id = {
+		.prefix = "cantpu",
+		.index = 1,
+		.suffix = "",
+	},
+	.direction = IN,
+	.cycletime = 0,
+};
+
+/* ----- */
+
+static fddi_pv_t pv_v_can = {
+	.id = {
+		.prefix = "v_can",
+		.index = -1,
+		.suffix = "",
+	},
+	.param_list_head = NULL,
+	.name = NULL,
+	.type = BE_UINT16,
+	.offset = 0,
+	.bit = 0,
+};
+
+static fddi_pv_t pv_n_can = {
+	.id = {
+		.prefix = "n_can",
+		.index = -1,
+		.suffix = "",
+	},
+	.param_list_head = NULL,
+	.name = NULL,
+	.type = BE_UINT16,
+	.offset = 2,
+	.bit = 0,
+};
+
+static fddi_pv_t pv_u_dc_can = {
+	.id = {
+		.prefix = "u_can",
+		.index = -1,
+		.suffix = "",
+	},
+	.param_list_head = NULL,
+	.name = NULL,
+	.type = BE_UINT16,
+	.offset = 4,
+	.bit = 0,
+};
+
+static fddi_pv_t pv_i_can = {
+	.id = {
+		.prefix = "i_can",
+		.index = -1,
+		.suffix = "",
+	},
+	.param_list_head = NULL,
+	.name = NULL,
+	.type = BE_UINT16,
+	.offset = 6,
+	.bit = 0,
+};
+
+static fddi_pv_t pv_arate_can = {
+	.id = {
+		.prefix = "arate_can",
+		.index = -1,
+		.suffix = "",
+	},
+	.param_list_head = NULL,
+	.name = NULL,
+	.type = BE_UINT16,
+	.offset = 0,
+	.bit = 0,
+};
+
+static fddi_pv_t pv_srate_can = {
+	.id = {
+		.prefix = "srate_can",
+		.index = -1,
+		.suffix = "",
+	},
+	.param_list_head = NULL,
+	.name = NULL,
+	.type = BE_UINT16,
+	.offset = 2,
+	.bit = 0,
+};
+
+#if 0
+struct modbus_tpu {
+	timer_t timer;
+	struct sigevent event;
+	struct itimerspec timer_spec;
+	modbus_dev_t *modbus_dev;
+};
+struct modbus_tpu modbus_tpu1;
+#endif
+
+typedef struct can_iface {
+	struct sockaddr_can addr;
+	struct can_frame frame;
+	struct ifreq ifr;
+	int socket;
+} can_iface_t;
+
+can_iface_t can_iface1;
+
+
+#if 0
+void _modbus_tpu_out(fddi_tpu_t *tpu)
+{
+	struct modbus_tpu *modbus_tpu = (struct modbus_tpu*)(tpu->priv);
+
+	/* application callback */
+	if (tpu->callback)
+		tpu->callback(tpu, NULL);
+
+	/* bus transfer */
+	modbus_w_single_coil(modbus_tpu->modbus_dev, 1, coil);
+	coil = coil == 0 ? 1:0;
+}
+
+void _modbus_tpu_in(fddi_tpu_t *tpu)
+{
+	/* bus transfer */
+
+	/* application callback */
+	if (tpu->callback)
+		tpu->callback(tpu, NULL);
+}
+
+
+void modbus_timer_handler(sigval_t sigval)
+{
+	fddi_tpu_t *tpu = (fddi_tpu_t*)sigval.sival_ptr;
+
+	if ((tpu->direction == OUT) || (tpu->direction == INOUT))
+		_modbus_tpu_out(tpu);
+
+	if ((tpu->direction == IN) || (tpu->direction == INOUT))
+		_modbus_tpu_in(tpu);
+
+	return;
+}
+#endif
+
+/*
+ * fddi backend functions
+ */
+
+int fddi_backend_init(fddi_iface_t *iface);
+int fddi_backend_destroy(fddi_iface_t *iface);
+int fddi_backend_configure(fddi_iface_t *iface, const char *configfile, void *data);
+int fddi_backend_setstate(fddi_iface_t *iface, fddi_state_enum_t state);
+int fddi_backend_cmd(fddi_iface_t *iface, fddi_cmd_enum_t cmd);
+
+int fddi_backend_init(fddi_iface_t *iface)
+{
+	if ((can_iface1.socket = socket(PF_CAN, SOCK_RAW, CAN_RAW)) < 0) {
+		perror("socket");
+		return -ESOCKTNOSUPPORT;
+	}
+
+	can_iface1.addr.can_family = AF_CAN;
+
+	strcpy(can_iface1.ifr.ifr_name, "vcan0");
+	if (ioctl(can_iface1.socket, SIOCGIFINDEX, &can_iface1.ifr) < 0) {
+		perror("SIOCGIFINDEX");
+		return 1;
+	}
+	can_iface1.addr.can_ifindex = can_iface1.ifr.ifr_ifindex;
+
+	if (bind(can_iface1.socket, (struct sockaddr *)&can_iface1.addr, sizeof(can_iface1.addr)) < 0) {
+		perror("bind");
+		return 1;
+	}
+
+	iface->priv = &can_iface1;
+	return 0;
+}
+
+int fddi_backend_destroy(fddi_iface_t *iface)
+{
+	can_iface_t *can_iface = (can_iface_t*)(iface->priv);
+
+	close(can_iface->socket);
+
+	return 0;
+}
+
+int fddi_backend_configure(fddi_iface_t *iface, const char *configfile, void *data)
+{
+#if 0
+	int ret;
+	modbus_dev_t *modbus_dev = (modbus_dev_t*)(iface->priv);
+
+	printf("parsing configfile: %s\n", configfile);
+	printf("for interface:      %s\n", iface->id.id_as_string); /* FIXME private */
+
+	/* FIXME: everything's hardcoded & static for now, we add an xml parser later */
+
+	iface->tpulist_head = &tpu1;
+	tpu1.pv_list_head = &pv1;
+
+	pv1.next = &pv2;
+	pv2.previous = &pv1;
+	pv2.next = &pv3;
+	pv3.previous = &pv2;
+
+	/* modbus has no hardware bus cycle, emulate one for each tpu */
+	/* FIXME: loop */
+	{
+		modbus_tpu1.event.sigev_notify = SIGEV_THREAD;
+		modbus_tpu1.event.sigev_notify_function = modbus_timer_handler;
+		modbus_tpu1.event.sigev_notify_attributes = NULL;
+		modbus_tpu1.event.sigev_value.sival_ptr = &tpu1;
+		tpu1.priv = &modbus_tpu1;
+
+		if ((ret = timer_create(CLOCK_REALTIME, &modbus_tpu1.event, &modbus_tpu1.timer)) < 0 ) {
+			perror("timer create");
+			return -1;
+		}
+	}
+
+	if (modbus_bind(modbus_dev, "192.168.23.242", 502) == -1) {
+		fprintf(stderr, "modbus_bind() failed\n");
+		return -1;
+	}
+
+	/* FIXME: modbus_dev must be put into the device, not iface! */
+	modbus_tpu1.modbus_dev = modbus_dev;
+
+	/* we are ready now and go into preoperational state */
+
+	fddi_backend_setstate(iface, STATE_PREOPERATIONAL);
+#endif
+	return 0;
+}
+
+int fddi_backend_setstate(fddi_iface_t *iface, fddi_state_enum_t state)
+{
+	int retval = -1;
+
+	switch(state) {
+	case STATE_UNCONFIGURED:
+	case STATE_MISSING:
+	case STATE_CONFIG_ERROR:
+	case STATE_PREOPERATIONAL:
+	case STATE_OPERATIONAL:
+	case STATE_OPERATION_ERROR:
+		iface->state = state;
+		retval = 0;
+		break;
+	default:
+		break;
+	}
+
+	return retval;
+}
+
+int fddi_backend_cmd(fddi_iface_t *iface, fddi_cmd_enum_t cmd)
+{
+	int retval = -1;
+
+	switch (cmd) {
+
+	case CMD_START:
+#if 0
+
+		printf("start\n");
+		/* FIXME loop over all tpus here */
+		{
+			struct modbus_tpu *mtpu = ((struct modbus_tpu*)(iface->tpulist_head->priv));
+
+			mtpu->timer_spec.it_value.tv_sec = 1;
+			mtpu->timer_spec.it_value.tv_nsec = 0;
+			mtpu->timer_spec.it_interval.tv_sec = 0;
+			mtpu->timer_spec.it_interval.tv_nsec = 500*1000*1000;
+
+			if ((retval = timer_settime(mtpu->timer, 0, &mtpu->timer_spec, NULL)) < 0 ) {
+				perror("timer settime");
+				/* FIXME: disarm timers here */
+				return -1;
+			}
+		}
+#endif
+		retval = 0;
+		break;
+
+	case CMD_STOP:
+#if 0
+		/* FIXME: loop over all tpus here */
+		{
+			struct modbus_tpu *mtpu = ((struct modbus_tpu*)(iface->tpulist_head->priv));
+
+			mtpu->timer_spec.it_value.tv_sec = 0;
+			mtpu->timer_spec.it_value.tv_nsec = 0;
+			mtpu->timer_spec.it_interval.tv_sec = 0;
+			mtpu->timer_spec.it_interval.tv_nsec = 0;
+
+			if ((retval = timer_settime(mtpu->timer, 0, &mtpu->timer_spec, NULL)) < 0 ) {
+				perror("timer settime");
+				return -1;
+			}
+		}
+#endif
+		retval = 0;
+		break;
+
+	case CMD_RESET:
+	case CMD_IDENTIFY:
+	case CMD_QUITERR:
+		retval = 0;
+		break;
+	default:
+		break;
+
+	}
+
+	return retval;
+}
+


More information about the OSADL-svn-commits mailing list