[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