# HG changeset patch
# User etisserant
# Date 1175684671 -7200
# Node ID e747d2e26af0e6f0bd3a1e50f62988d9f0ec96cc
# Parent 3ebf16150b2e41325dc59bcb12b5e89dbcd05e6c
Win32 Native support and dynamicaly loaded CAN drivers for Linux, Cygwin and Win32.
diff -r 3ebf16150b2e -r e747d2e26af0 .cvsignore
--- a/.cvsignore Tue Apr 03 20:20:27 2007 +0200
+++ b/.cvsignore Wed Apr 04 13:04:31 2007 +0200
@@ -3,3 +3,15 @@
.settings
.externalToolBuilders
Makefile
+_UpgradeReport_Files
+debug
+Debug UNICODE
+UpgradeLog3.XML
+CanFestival-3.vc8.vcproj.KONG.edouard.user
+UpgradeLog.XML
+CanFestival-3.vc8.suo
+UpgradeLog2.XML
+CanFestival-3.vc8.ncb
+Pcan_2pcc.dll
+Pcan_pcc.dll
+Release
diff -r 3ebf16150b2e -r e747d2e26af0 CanFestival-3.vc8.sln
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CanFestival-3.vc8.sln Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,66 @@
+
+Microsoft Visual Studio Solution File, Format Version 9.00
+# Visual C++ Express 2005
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CanFestival-3", "CanFestival-3.vc8.vcproj", "{50EF2507-9B87-4525-8B19-80EB42E67079}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "can_uvccm_win32", "drivers\can_uvccm_win32\can_uvccm_win32.vcproj", "{39E3300A-29B4-4AA7-AF62-3B181FC26155}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "win32test", "examples\win32test\win32test.vcproj", "{BD8B1FE1-89CD-4F89-8275-0F553FA71059}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "can_peak_win32", "drivers\can_peak_win32\can_peak_win32.vcproj", "{732EC5B6-C6F1-4783-9BC8-924FFF67BF5A}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TestMasterSlave", "examples\TestMasterSlave\TestMasterSalve.vcproj", "{B51A176D-5320-4534-913B-3025CED5B27E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug UNICODE|Win32 = Debug UNICODE|Win32
+ Debug|Win32 = Debug|Win32
+ Release UNICODE|Win32 = Release UNICODE|Win32
+ Release|Win32 = Release|Win32
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {50EF2507-9B87-4525-8B19-80EB42E67079}.Debug UNICODE|Win32.ActiveCfg = Debug UNICODE|Win32
+ {50EF2507-9B87-4525-8B19-80EB42E67079}.Debug UNICODE|Win32.Build.0 = Debug UNICODE|Win32
+ {50EF2507-9B87-4525-8B19-80EB42E67079}.Debug|Win32.ActiveCfg = Debug|Win32
+ {50EF2507-9B87-4525-8B19-80EB42E67079}.Debug|Win32.Build.0 = Debug|Win32
+ {50EF2507-9B87-4525-8B19-80EB42E67079}.Release UNICODE|Win32.ActiveCfg = Release UNICODE|Win32
+ {50EF2507-9B87-4525-8B19-80EB42E67079}.Release UNICODE|Win32.Build.0 = Release UNICODE|Win32
+ {50EF2507-9B87-4525-8B19-80EB42E67079}.Release|Win32.ActiveCfg = Release|Win32
+ {50EF2507-9B87-4525-8B19-80EB42E67079}.Release|Win32.Build.0 = Release|Win32
+ {39E3300A-29B4-4AA7-AF62-3B181FC26155}.Debug UNICODE|Win32.ActiveCfg = Debug UNICODE|Win32
+ {39E3300A-29B4-4AA7-AF62-3B181FC26155}.Debug UNICODE|Win32.Build.0 = Debug UNICODE|Win32
+ {39E3300A-29B4-4AA7-AF62-3B181FC26155}.Debug|Win32.ActiveCfg = Debug|Win32
+ {39E3300A-29B4-4AA7-AF62-3B181FC26155}.Debug|Win32.Build.0 = Debug|Win32
+ {39E3300A-29B4-4AA7-AF62-3B181FC26155}.Release UNICODE|Win32.ActiveCfg = Release UNICODE|Win32
+ {39E3300A-29B4-4AA7-AF62-3B181FC26155}.Release UNICODE|Win32.Build.0 = Release UNICODE|Win32
+ {39E3300A-29B4-4AA7-AF62-3B181FC26155}.Release|Win32.ActiveCfg = Release|Win32
+ {39E3300A-29B4-4AA7-AF62-3B181FC26155}.Release|Win32.Build.0 = Release|Win32
+ {BD8B1FE1-89CD-4F89-8275-0F553FA71059}.Debug UNICODE|Win32.ActiveCfg = Debug|Win32
+ {BD8B1FE1-89CD-4F89-8275-0F553FA71059}.Debug UNICODE|Win32.Build.0 = Debug|Win32
+ {BD8B1FE1-89CD-4F89-8275-0F553FA71059}.Debug|Win32.ActiveCfg = Debug|Win32
+ {BD8B1FE1-89CD-4F89-8275-0F553FA71059}.Debug|Win32.Build.0 = Debug|Win32
+ {BD8B1FE1-89CD-4F89-8275-0F553FA71059}.Release UNICODE|Win32.ActiveCfg = Release|Win32
+ {BD8B1FE1-89CD-4F89-8275-0F553FA71059}.Release UNICODE|Win32.Build.0 = Release|Win32
+ {BD8B1FE1-89CD-4F89-8275-0F553FA71059}.Release|Win32.ActiveCfg = Release|Win32
+ {BD8B1FE1-89CD-4F89-8275-0F553FA71059}.Release|Win32.Build.0 = Release|Win32
+ {732EC5B6-C6F1-4783-9BC8-924FFF67BF5A}.Debug UNICODE|Win32.ActiveCfg = Debug UNICODE|Win32
+ {732EC5B6-C6F1-4783-9BC8-924FFF67BF5A}.Debug UNICODE|Win32.Build.0 = Debug UNICODE|Win32
+ {732EC5B6-C6F1-4783-9BC8-924FFF67BF5A}.Debug|Win32.ActiveCfg = Debug|Win32
+ {732EC5B6-C6F1-4783-9BC8-924FFF67BF5A}.Debug|Win32.Build.0 = Debug|Win32
+ {732EC5B6-C6F1-4783-9BC8-924FFF67BF5A}.Release UNICODE|Win32.ActiveCfg = Release UNICODE|Win32
+ {732EC5B6-C6F1-4783-9BC8-924FFF67BF5A}.Release UNICODE|Win32.Build.0 = Release UNICODE|Win32
+ {732EC5B6-C6F1-4783-9BC8-924FFF67BF5A}.Release|Win32.ActiveCfg = Release|Win32
+ {732EC5B6-C6F1-4783-9BC8-924FFF67BF5A}.Release|Win32.Build.0 = Release|Win32
+ {B51A176D-5320-4534-913B-3025CED5B27E}.Debug UNICODE|Win32.ActiveCfg = Debug|Win32
+ {B51A176D-5320-4534-913B-3025CED5B27E}.Debug UNICODE|Win32.Build.0 = Debug|Win32
+ {B51A176D-5320-4534-913B-3025CED5B27E}.Debug|Win32.ActiveCfg = Debug|Win32
+ {B51A176D-5320-4534-913B-3025CED5B27E}.Debug|Win32.Build.0 = Debug|Win32
+ {B51A176D-5320-4534-913B-3025CED5B27E}.Release UNICODE|Win32.ActiveCfg = Release|Win32
+ {B51A176D-5320-4534-913B-3025CED5B27E}.Release UNICODE|Win32.Build.0 = Release|Win32
+ {B51A176D-5320-4534-913B-3025CED5B27E}.Release|Win32.ActiveCfg = Release|Win32
+ {B51A176D-5320-4534-913B-3025CED5B27E}.Release|Win32.Build.0 = Release|Win32
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff -r 3ebf16150b2e -r e747d2e26af0 CanFestival-3.vc8.vcproj
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/CanFestival-3.vc8.vcproj Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,532 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 3ebf16150b2e -r e747d2e26af0 configure
--- a/configure Tue Apr 03 20:20:27 2007 +0200
+++ b/configure Wed Apr 04 13:04:31 2007 +0200
@@ -74,8 +74,6 @@
# Install prefix
SUB_PREFIX=
-SUB_TIMERS_ENABLE=YES
-
# Used for C compiler test/detection
CFLAGS=
test=conftest
@@ -99,12 +97,12 @@
--timers=*) SUB_TIMERS_DRIVER=$optarg;;
--disable-Ox) DISABLE_OPT=1;
echo "On user request: Won't optimize with \"-Ox\"";;
+ --disable-dll) DISABLE_DLL=1;
+ echo "On user request: Won't create and link to dll";;
--debug) DEBUG=1;
echo "Debug messages enabled !!";;
--debugPDO) DEBUG=PDO;
echo "Debug messages (PDO) enabled !!";;
- --desable-timers) SUB_TIMERS_ENABLE=NO;
- echo "On user request: Will enable built-in timer dispatch Feature";;
--MAX_CAN_BUS_ID=*) MAX_CAN_BUS_ID=$1;;
--SDO_MAX_LENGTH_TRANSFERT=*) SDO_MAX_LENGTH_TRANSFERT=$1;;
--SDO_MAX_SIMULTANEOUS_TRANSFERTS=*) SDO_MAX_SIMULTANEOUS_TRANSFERTS=$1;;
@@ -114,20 +112,31 @@
--MAX_NB_TIMER=*) MAX_NB_TIMER=$1;;
--help) echo "Usage: ./configure [options]"
echo "Options:"
- echo " --cc=foo Use compiler 'foo' instead of defaults ${CC1} or ${CC2}."
- echo " --arch=foo Use architecture 'foo' instead of trying to autodetect."
- echo " --os=foo Use operative system 'foo' instead of trying to autodetect."
- echo " --prefix=foo Use prefix 'foo' instead of default ${SUB_PREFIX}."
- echo " --target=foo Use 'foo' as build target."
- echo " \"generic\" for have independant CAN and TIMERS driver"
- echo " \"unix\" for unix-like systems"
- echo " \"win32\" for win32 systems"
- echo " \"hcs12\" for HCS12 micro-controller"
- echo " --can=foo Use 'foo' as CAN driver (can be either 'peak', 'lincan' or 'virtual')"
- echo " --timers=foo Use 'foo' as TIMERS driver (can be either 'unix' or 'xeno')"
- echo " --disable-Ox Disable gcc \"-Ox\" optimizations."
- echo " --debug Enable debug messages."
- echo " --debugPDO Enable debug messages, using PDO."
+ echo " --cc=foo Use compiler 'foo' instead of defaults ${CC1} or ${CC2}."
+ echo " --arch=foo Use architecture 'foo' instead of trying to autodetect."
+ echo " --os=foo Use operative system 'foo' instead of trying to autodetect."
+ echo " --prefix=foo Use prefix 'foo' instead of default ${SUB_PREFIX}."
+ echo " --target=foo Use 'foo' as build target."
+ echo " \"generic\" for have independant CAN and TIMERS driver"
+ echo " \"unix\" for unix-like systems"
+ echo " \"win32\" for win32 systems"
+ echo " \"hcs12\" for HCS12 micro-controller"
+ echo " \"ecos_lpc2138_sja1000\" for eCOS + Philips ARM LPC21381 + Philips SJA1000"
+ echo " --can=foo Use 'foo' as CAN driver"
+ echo " \"peak_linux\" use Linux build host installed Peak driver and library"
+ echo " please see http://www.peak-system.com/linux/"
+ echo " \"peak_win32\" use win32 PcanLight Peak driver and library with Cygwin"
+ echo " please see http://www.peak-system.com/themen/download_gb.html"
+ echo " \"virtual\" use unix pipe based virtual can driver"
+ echo " \"socket\" use socket-can "
+ echo " please see http://developer.berlios.de/projects/socketcan/"
+ echo " \"lincan\" for HCS12 micro-controller"
+ echo " please see http://www.ocera.org/download/components/WP7/lincan-0.3.3.html"
+ echo " --timers=foo Use 'foo' as TIMERS driver (can be either 'unix' or 'xeno')"
+ echo " --disable-dll Disable run-time dynamic linking of can, led and nvram drivers"
+ echo " --disable-Ox Disable gcc \"-Ox\" optimizations."
+ echo " --debug Enable debug messages."
+ echo " --debugPDO Enable debug messages, using PDO."
echo
echo "Stack compilation constants"
echo " --MAX_CAN_BUS_ID [=1] Number of can bus to use"
@@ -217,11 +226,6 @@
SUB_ARCH_NAME=sparc64
fi
-
-#
-# The following has not been verified
-#
-
# ppc
if [ "$A_NAME" = "powerpc" ]; then
SUB_ARCH_NAME=ppc
@@ -335,15 +339,15 @@
if [ "$SUB_TARGET" = "unix" ]; then
if [ -e /usr/lib/libpcan.so ]; then
echo "Choosing installed Peak driver as CAN driver."
- SUB_CAN_DRIVER=peak
+ SUB_CAN_DRIVER=peak_linux
+ elif [ "$SUB_OS_NAME" = "CYGWIN" -a "PCAN_LIB" != "" ]; then
+ echo "Choosing installed Peak driver as CAN driver."
+ SUB_CAN_DRIVER=peak_win32
else
echo "Choosing virtual CAN driver."
SUB_CAN_DRIVER=virtual
fi
fi
- if [ "$SUB_TARGET" = "win32" ]; then
- echo "CAN driver for windows --Not Implemented--"
- fi
fi
# If target is unix, default timers also
@@ -399,36 +403,34 @@
#### CAN_DRIVER ####
-if [ "$SUB_CAN_DRIVER" = "peak" ]; then
- if [ "$SUB_TIMERS_DRIVER" = "xeno" ]; then
- SUB_EXE_CFLAGS=$SUB_EXE_CFLAGS\ -lrtdm
- fi
- SUB_EXE_CFLAGS=$SUB_EXE_CFLAGS\ -lpcan
-fi
-
+if [ "$SUB_CAN_DRIVER" = "peak_linux" ]; then
+ SUB_CAN_DLL_CFLAGS=$SUB_CAN_DLL_CFLAGS\ -lpcan
+fi
+
+PW32DIR=drivers/can_peak_win32
if [ "$SUB_CAN_DRIVER" = "peak_win32" ]; then
if [ "$PCAN_HEADER" = "" -o "PCAN_LIB" = "" ]; then
echo "!!! ERROR !!! Please set PCAN_LIB PCAN_HEADER [PCAN_INCLUDE] to appropriate paths ! "
fi
- SUB_EXE_CFLAGS=$SUB_EXE_CFLAGS\ -liberty\ \'$PCAN_LIB\'
- echo "Converting PcanLib header files for gcc -> /drivers/can_peak_win32/cancfg.h"
- cat include/can_peak_win32/cancfg.h.head $PCAN_INCLUDE/$PCAN_HEADER > include/can_peak_win32/cancfg.h
+ SUB_CAN_DLL_CFLAGS=$SUB_CAN_DLL_CFLAGS\ -liberty\ \'$PCAN_LIB\'
+ echo "Converting PcanLib header files for gcc -> $PW32DIR/cancfg.h"
+ cat $PW32DIR/cancfg.h.head $PCAN_INCLUDE/$PCAN_HEADER > $PW32DIR/cancfg.h
# second port handling
if [ "$PCAN2_HEADER" != "" ]; then
echo "Stripping down second Pcan Light header "
- echo >> include/can_peak_win32/cancfg.h
- echo "// Stripped PcanLight header to prevent typedef conflicts ">> include/can_peak_win32/cancfg.h
- echo >> include/can_peak_win32/cancfg.h
- grep __stdcall $PCAN_INCLUDE/$PCAN2_HEADER >> include/can_peak_win32/cancfg.h
- SUB_EXE_CFLAGS=$SUB_EXE_CFLAGS\ \'$PCAN2_LIB\'
- echo '#define PCAN2_HEADER_' >> include/can_peak_win32/cancfg.h
- fi
- if grep -q CANHwType include/can_peak_win32/cancfg.h ; then
+ echo >> $PW32DIR/cancfg.h
+ echo "// Stripped PcanLight header to prevent typedef conflicts ">> $PW32DIR/cancfg.h
+ echo >> $PW32DIR/cancfg.h
+ grep __stdcall $PCAN_INCLUDE/$PCAN2_HEADER >> $PW32DIR/cancfg.h
+ echo '#define PCAN2_HEADER_' >> $PW32DIR/cancfg.h
+ SUB_CAN_DLL_CFLAGS=$SUB_CAN_DLL_CFLAGS\ \'$PCAN2_LIB\'
+ fi
+ if grep -q CANHwType $PW32DIR/cancfg.h ; then
echo "Peak Init HwType, IO_Port and IRQ will be passed in environment :"
echo " PCANHwType PCANIO_Port PCANInterupt"
- echo '#define extra_PCAN_init_params' >> include/can_peak_win32/cancfg.h
- fi
- cat include/can_peak_win32/cancfg.h.tail >> include/can_peak_win32/cancfg.h
+ echo '#define extra_PCAN_init_params' >> $PW32DIR/cancfg.h
+ fi
+ cat $PW32DIR/cancfg.h.tail >> $PW32DIR/cancfg.h
fi
if [ "$SUB_CAN_DRIVER" = "none" ]; then
@@ -603,6 +605,19 @@
SUB_OPT_CFLAGS=\$\(OPT_CFLAGS\)
fi
+if [ "$DISABLE_DLL" = "1" ]; then
+ SUB_PROG_CFLAGS=$SUB_PROG_CFLAGS\ -DNOT_USE_DYNAMIC_LOADING
+ SUB_ENABLE_DLL_DRIVERS=0
+else
+ SUB_ENABLE_DLL_DRIVERS=1
+ SUB_EXE_CFLAGS=$SUB_EXE_CFLAGS\ -ldl
+fi
+
+
+if [ "$DISABLE_DLL" = "1" ]; then
+ SUB_EXE_CFLAGS=$SUB_EXE_CFLAGS\ $SUB_CAN_DLL_CFLAGS
+fi
+
###########################################################################
# CREATE MAKEFILES #
###########################################################################
@@ -650,9 +665,10 @@
s:SUB_OPT_CFLAGS:${SUB_OPT_CFLAGS}:
s:SUB_TARGET:${SUB_TARGET}:
s:SUB_BINUTILS_PREFIX:${SUB_BINUTILS_PREFIX}:
- s:SUB_TIMERS_ENABLE:${SUB_TIMERS_ENABLE}:
s:SUB_TIMERS_DRIVER:timers_${SUB_TIMERS_DRIVER}:
s:SUB_CAN_DRIVER:can_${SUB_CAN_DRIVER}:
+ s:SUB_CAN_DLL_CFLAGS:${SUB_CAN_DLL_CFLAGS}:
+ s:SUB_ENABLE_DLL_DRIVERS:${SUB_ENABLE_DLL_DRIVERS}:
" > $makefile
done
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/can_lincan/.cvsignore
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_lincan/.cvsignore Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,1 @@
+Makefile
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/can_lincan/Makefile.in
--- a/drivers/can_lincan/Makefile.in Tue Apr 03 20:20:27 2007 +0200
+++ b/drivers/can_lincan/Makefile.in Wed Apr 04 13:04:31 2007 +0200
@@ -29,26 +29,35 @@
TARGET = SUB_TARGET
CAN_DRIVER = SUB_CAN_DRIVER
TIMERS_DRIVER = SUB_TIMERS_DRIVER
+ENABLE_DLL_DRIVERS=SUB_ENABLE_DLL_DRIVERS
-INCLUDES = -I../../include -I../../include/$(TARGET) -I../../include/$(CAN_DRIVER) -I../../include/$(TIMERS_DRIVER)
+INCLUDES = -I../../include -I../../include/$(TARGET) -I../../include/$(CAN_DRIVER)
OBJS = $(CAN_DRIVER).o
-SRC_HFILES = ../../include/$(CAN_DRIVER)/cancfg.h
+ifeq ($(ENABLE_DLL_DRIVERS),1)
+CFLAGS += -fPIC
+DRIVER = libcanfestival_$(CAN_DRIVER).so
+else
+DRIVER = $(OBJS)
+endif
-TARGET_HFILES = $(PREFIX)/include/canfestival/cancfg.h
+TARGET_SOFILES = $(PREFIX)/lib/$(DRIVER)
all: driver
-driver: $(OBJS)
+driver: $(DRIVER)
%o: %c
$(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -c $<
-install:
- mkdir -p $(PREFIX)/include/canfestival
- cp $(SRC_HFILES) $(PREFIX)/include/canfestival
+libcanfestival_$(CAN_DRIVER).so: $(OBJS)
+ gcc -shared -Wl,-soname,libcanfestival_$(CAN_DRIVER).so -o $@ $<
+install: libcanfestival_$(CAN_DRIVER).so
+ mkdir -p $(PREFIX)/lib/
+ cp $@ $(PREFIX)/lib/
+
uninstall:
rm -f $(TARGET_HFILES)
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/can_lincan/can_lincan.c
--- a/drivers/can_lincan/can_lincan.c Tue Apr 03 20:20:27 2007 +0200
+++ b/drivers/can_lincan/can_lincan.c Wed Apr 04 13:04:31 2007 +0200
@@ -22,36 +22,16 @@
#include
#include
-#include
#include
-#include /* for NULL */
-#include
#include
-#include
-#include
-#include
#include "canmsg.h"
#include "lincan.h"
-struct CANPort;
-#define CAN_HANDLE struct CANPort *
-
-#include
-
-#include "timer.h"
#include "can_driver.h"
-#include "timers_driver.h"
-
-typedef struct CANPort {
- char used;
- HANDLE fd;
- TASK_HANDLE receiveTask;
- CO_Data* d;
-} CANPort;
/*********functions which permit to communicate with the board****************/
-UNS8 canReceive(CAN_HANDLE fd0, Message *m)
+UNS8 canReceive_driver(CAN_HANDLE fd0, Message *m)
{
int res;
struct canmsg_t canmsg;
@@ -59,7 +39,7 @@
canmsg.flags = 0; /* Ensure standard receive, not required for LinCAN>=0.3.1 */
do{
- res = read(fd0->fd,&canmsg,sizeof(canmsg_t));
+ res = read(fd0,&canmsg,sizeof(canmsg_t));
if((res<0)&&(errno == -EAGAIN)) res = 0;
}while(res==0);
@@ -82,25 +62,8 @@
return 0;
}
-void canReceiveLoop(CAN_HANDLE fd0)
-{
- CO_Data* d = fd0->d;
- Message m;
- while (fd0->used) {
- if(!canReceive(fd0, &m))
- {
- EnterMutex();
- canDispatch(d, &m);
- LeaveMutex();
- }else{
- printf("canReceive returned error\n");
- break;
- }
- }
-}
-
/***************************************************************************/
-UNS8 canSend(CAN_HANDLE fd0, Message *m)
+UNS8 canSend_driver(CAN_HANDLE fd0, Message *m)
{
int res;
struct canmsg_t canmsg;
@@ -119,7 +82,7 @@
canmsg.flags |= MSG_EXT;
}
- res = write(fd0->fd,&canmsg,sizeof(canmsg_t));
+ res = write(fd0,&canmsg,sizeof(canmsg_t));
if(res!=sizeof(canmsg_t))
return 1;
@@ -129,7 +92,7 @@
/***************************************************************************/
static const char lnx_can_dev_prefix[] = "/dev/can";
-CAN_HANDLE canOpen(s_BOARD *board)
+CAN_HANDLE canOpen_driver(s_BOARD *board)
{
int name_len = strlen(board->busname);
int prefix_len = strlen(lnx_can_dev_prefix);
@@ -147,15 +110,12 @@
memcpy(dev_name+prefix_len,board->busname,name_len);
dev_name[prefix_len+name_len] = 0;
- fd0->fd = open(dev_name, O_RDWR|o_flags);
- if(fd0->fd < 0){
+ fd0 = open(dev_name, O_RDWR|o_flags);
+ if(fd0 < 0){
fprintf(stderr,"!!! Board %s is unknown. See can_lincan.c\n", board->busname);
goto error_ret;
}
- fd0->d = board->d;
- fd0->used = 1;
- CreateReceiveTask(fd0, &fd0->receiveTask);
return fd0;
error_ret:
@@ -164,13 +124,10 @@
}
/***************************************************************************/
-int canClose(CAN_HANDLE fd0)
+int canClose_driver(CAN_HANDLE fd0)
{
if(!fd0)
return 0;
- fd0->used = 0;
- WaitReceiveTaskEnd(&fd0->receiveTask);
- close(fd0->fd);
- free(fd0);
+ close(fd0);
return 0;
}
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/can_lincan/canmsg.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_lincan/canmsg.h Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,136 @@
+/* canmsg.h - common kernel-space and user-space CAN message structure
+ * Linux CAN-bus device driver.
+ * Written by Pavel Pisa - OCERA team member
+ * email:pisa@cmp.felk.cvut.cz
+ * This software is released under the GPL-License.
+ * Version lincan-0.3 17 Jun 2004
+ */
+
+#ifndef _CANMSG_T_H
+#define _CANMSG_T_H
+
+#ifdef __KERNEL__
+
+#include
+#include
+
+#else /* __KERNEL__ */
+
+#include
+#include
+
+#endif /* __KERNEL__ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * CAN_MSG_VERSION_2 enables new canmsg_t layout compatible with
+ * can4linux project from http://www.port.de/
+ *
+ */
+#define CAN_MSG_VERSION_2
+
+/* Number of data bytes in one CAN message */
+#define CAN_MSG_LENGTH 8
+
+#ifdef CAN_MSG_VERSION_2
+
+typedef struct timeval canmsg_tstamp_t ;
+
+typedef unsigned long canmsg_id_t;
+
+/**
+ * struct canmsg_t - structure representing CAN message
+ * @flags: message flags
+ * %MSG_RTR .. message is Remote Transmission Request,
+ * %MSG_EXT .. message with extended ID,
+ * %MSG_OVR .. indication of queue overflow condition,
+ * %MSG_LOCAL .. message originates from this node.
+ * @cob: communication object number (not used)
+ * @id: ID of CAN message
+ * @timestamp: not used
+ * @length: length of used data
+ * @data: data bytes buffer
+ *
+ * Header: canmsg.h
+ */
+struct canmsg_t {
+ int flags;
+ int cob;
+ canmsg_id_t id;
+ canmsg_tstamp_t timestamp;
+ unsigned short length;
+ unsigned char data[CAN_MSG_LENGTH];
+};
+
+#else /*CAN_MSG_VERSION_2*/
+#ifndef PACKED
+#define PACKED __attribute__((packed))
+#endif
+/* Old, deprecated version of canmsg_t structure */
+struct canmsg_t {
+ short flags;
+ int cob;
+ canmsg_id_t id;
+ unsigned long timestamp;
+ unsigned int length;
+ unsigned char data[CAN_MSG_LENGTH];
+} PACKED;
+#endif /*CAN_MSG_VERSION_2*/
+
+typedef struct canmsg_t canmsg_t;
+
+/**
+ * struct canfilt_t - structure for acceptance filter setup
+ * @flags: message flags
+ * %MSG_RTR .. message is Remote Transmission Request,
+ * %MSG_EXT .. message with extended ID,
+ * %MSG_OVR .. indication of queue overflow condition,
+ * %MSG_LOCAL .. message originates from this node.
+ * there are corresponding mask bits
+ * %MSG_RTR_MASK, %MSG_EXT_MASK, %MSG_LOCAL_MASK.
+ * %MSG_PROCESSLOCAL enables local messages processing in the
+ * combination with global setting
+ * @queid: CAN queue identification in the case of the multiple
+ * queues per one user (open instance)
+ * @cob: communication object number (not used)
+ * @id: selected required value of cared ID id bits
+ * @mask: select bits significand for the comparation;
+ * 1 .. take care about corresponding ID bit, 0 .. don't care
+ *
+ * Header: canmsg.h
+ */
+struct canfilt_t {
+ int flags;
+ int queid;
+ int cob;
+ canmsg_id_t id;
+ canmsg_id_t mask;
+};
+
+typedef struct canfilt_t canfilt_t;
+
+/* Definitions to use for canmsg_t and canfilt_t flags */
+#define MSG_RTR (1<<0)
+#define MSG_OVR (1<<1)
+#define MSG_EXT (1<<2)
+#define MSG_LOCAL (1<<3)
+/* If you change above lines, check canque_filtid2internal function */
+
+/* Additional definitions used for canfilt_t only */
+#define MSG_FILT_MASK_SHIFT 8
+#define MSG_RTR_MASK (MSG_RTR<
+#include
+#include
+
+#else /* __KERNEL__ */
+
+#include
+#include
+#include
+
+#endif /* __KERNEL__ */
+
+#include "./canmsg.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* CAN ioctl magic number */
+#define CAN_IOC_MAGIC 'd'
+
+typedef unsigned long bittiming_t;
+typedef unsigned short channel_t;
+
+/**
+ * struct can_baudparams_t - datatype for calling CONF_BAUDPARAMS IOCTL
+ * @flags: reserved for additional flags for chip configuration, should be written -1 or 0
+ * @baudrate: baud rate in Hz
+ * @sjw: synchronization jump width (0-3) prescaled clock cycles
+ * @sampl_pt: sample point in % (0-100) sets (TSEG1+1)/(TSEG1+TSEG2+2) ratio
+ *
+ * The structure is used to configure new set of parameters into CAN controller chip.
+ * If default value of some field should be preserved, fill field by value -1.
+ */
+struct can_baudparams_t {
+ long flags;
+ long baudrate;
+ long sjw;
+ long sample_pt;
+};
+
+/* CAN ioctl functions */
+#define CAN_DRV_QUERY _IO(CAN_IOC_MAGIC, 0)
+#define CAN_DRV_QRY_BRANCH 0 /* returns driver branch value - "LINC" for LinCAN driver */
+#define CAN_DRV_QRY_VERSION 1 /* returns driver version as (major<<16) | (minor<<8) | patch */
+#define CAN_DRV_QRY_MSGFORMAT 2 /* format of canmsg_t structure */
+
+#define CMD_START _IOW(CAN_IOC_MAGIC, 1, channel_t)
+#define CMD_STOP _IOW(CAN_IOC_MAGIC, 2, channel_t)
+//#define CMD_RESET 3
+
+#define CONF_BAUD _IOW(CAN_IOC_MAGIC, 4, bittiming_t)
+//#define CONF_ACCM
+//#define CONF_XTDACCM
+//#define CONF_TIMING
+//#define CONF_OMODE
+#define CONF_FILTER _IOW(CAN_IOC_MAGIC, 8, unsigned char)
+
+//#define CONF_FENABLE
+//#define CONF_FDISABLE
+
+#define STAT _IO(CAN_IOC_MAGIC, 9)
+#define CANQUE_FILTER _IOW(CAN_IOC_MAGIC, 10, struct canfilt_t)
+#define CANQUE_FLUSH _IO(CAN_IOC_MAGIC, 11)
+#define CONF_BAUDPARAMS _IOW(CAN_IOC_MAGIC, 11, struct can_baudparams_t)
+#define CANRTR_READ _IOWR(CAN_IOC_MAGIC, 12, struct canmsg_t)
+
+#ifdef __cplusplus
+} /* extern "C"*/
+#endif
+
+#endif /*_CAN_DRVAPI_T_H*/
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/can_peak_linux/.cvsignore
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_peak_linux/.cvsignore Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,2 @@
+Makefile
+libcanfestival_can_peak_linux.so
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/can_peak_linux/Makefile.in
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_peak_linux/Makefile.in Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,68 @@
+#! gmake
+
+#
+# Copyright (C) 2006 Laurent Bessard
+#
+# This file is part of canfestival, a library implementing the canopen
+# stack
+#
+# This 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; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This 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 this library; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+CC = SUB_CC
+OPT_CFLAGS = -O2
+CFLAGS = SUB_OPT_CFLAGS
+PROG_CFLAGS = SUB_PROG_CFLAGS
+PREFIX = SUB_PREFIX
+TARGET = SUB_TARGET
+CAN_DRIVER = SUB_CAN_DRIVER
+TIMERS_DRIVER = SUB_TIMERS_DRIVER
+ENABLE_DLL_DRIVERS=SUB_ENABLE_DLL_DRIVERS
+CAN_DLL_CFLAGS=SUB_CAN_DLL_CFLAGS
+
+INCLUDES = -I../../include -I../../include/$(TARGET) -I../../include/$(CAN_DRIVER)
+
+OBJS = $(CAN_DRIVER).o
+
+ifeq ($(ENABLE_DLL_DRIVERS),1)
+CFLAGS += -fPIC
+DRIVER = libcanfestival_$(CAN_DRIVER).so
+else
+DRIVER = $(OBJS)
+endif
+
+TARGET_SOFILES = $(PREFIX)/lib/$(DRIVER)
+
+all: driver
+
+driver: $(DRIVER)
+
+%o: %c
+ $(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -c $<
+
+libcanfestival_$(CAN_DRIVER).so: $(OBJS)
+ gcc -shared -Wl,-soname,libcanfestival_$(CAN_DRIVER).so $(CAN_DLL_CFLAGS) -o $@ $<
+
+install: libcanfestival_$(CAN_DRIVER).so
+ mkdir -p $(PREFIX)/lib/
+ cp $@ $(PREFIX)/lib/
+
+uninstall:
+ rm -f $(TARGET_HFILES)
+
+clean:
+ rm -f $(OBJS)
+
+mrproper: clean
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/can_peak_linux/can_peak_linux.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_peak_linux/can_peak_linux.c Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,129 @@
+/*
+This file is part of CanFestival, a library implementing CanOpen Stack.
+
+Copyright (C): Edouard TISSERANT and Francis DUPIN
+
+See COPYING file for copyrights details.
+
+This 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; either
+version 2.1 of the License, or (at your option) any later version.
+
+This 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 this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#include
+#include
+#include
+#include
+
+/* driver pcan pci for Peak board */
+//#include "libpcan.h"
+//#include "pcan.h"
+
+#include "libpcan.h" // for CAN_HANDLE
+
+#include "can_driver.h"
+
+// Define for rtr CAN message
+#define CAN_INIT_TYPE_ST_RTR MSGTYPE_STANDARD | MSGTYPE_RTR
+
+/*********functions which permit to communicate with the board****************/
+UNS8 canReceive_driver(CAN_HANDLE fd0, Message *m)
+{
+ UNS8 data;
+ TPCANMsg peakMsg;
+ if ((errno = CAN_Read(fd0, & peakMsg))) { // Blocks until no new message or error.
+ if(errno != -EIDRM && errno != -EPERM) // error is not "Can Port closed while reading"
+ {
+ perror("!!! Peak board : error of reading. (from f_can_receive function) \n");
+ }
+ return 1;
+ }
+ m->cob_id.w = peakMsg.ID;
+ if (peakMsg.MSGTYPE == CAN_INIT_TYPE_ST) /* bits of MSGTYPE_*/
+ m->rtr = 0;
+ else
+ m->rtr = 1;
+ m->len = peakMsg.LEN; /* count of data bytes (0..8) */
+ for(data = 0 ; data < peakMsg.LEN ; data++)
+ m->data[data] = peakMsg.DATA[data]; /* data bytes, up to 8 */
+
+ return 0;
+}
+
+/***************************************************************************/
+UNS8 canSend_driver(CAN_HANDLE fd0, Message *m)
+{
+ UNS8 data;
+ TPCANMsg peakMsg;
+ peakMsg.ID=m -> cob_id.w; /* 11/29 bit code */
+ if(m->rtr == 0)
+ peakMsg.MSGTYPE = CAN_INIT_TYPE_ST; /* bits of MSGTYPE_*/
+ else {
+ peakMsg.MSGTYPE = CAN_INIT_TYPE_ST_RTR; /* bits of MSGTYPE_*/
+ }
+ peakMsg.LEN = m->len;
+ /* count of data bytes (0..8) */
+ for(data = 0 ; data < m->len; data ++)
+ peakMsg.DATA[data] = m->data[data]; /* data bytes, up to 8 */
+
+ if((errno = CAN_Write(fd0, & peakMsg))) {
+ perror("!!! Peak board : error of writing. (from canSend function) \n");
+ return 1;
+ }
+ return 0;
+
+}
+
+
+/***************************************************************************/
+int TranslateBaudeRate(char* optarg){
+ if(!strcmp( optarg, "1M")) return CAN_BAUD_1M;
+ if(!strcmp( optarg, "500K")) return CAN_BAUD_500K;
+ if(!strcmp( optarg, "250K")) return CAN_BAUD_250K;
+ if(!strcmp( optarg, "125K")) return CAN_BAUD_125K;
+ if(!strcmp( optarg, "100K")) return CAN_BAUD_100K;
+ if(!strcmp( optarg, "50K")) return CAN_BAUD_50K;
+ if(!strcmp( optarg, "20K")) return CAN_BAUD_20K;
+ if(!strcmp( optarg, "10K")) return CAN_BAUD_10K;
+ if(!strcmp( optarg, "5K")) return CAN_BAUD_5K;
+ if(!strcmp( optarg, "none")) return 0;
+ return 0x0000;
+}
+
+/***************************************************************************/
+CAN_HANDLE canOpen_driver(s_BOARD *board)
+{
+ HANDLE fd0 = NULL;
+ char busname[64];
+ char* pEnd;
+ int i;
+ int baudrate;
+
+ if(strtol(board->busname, &pEnd,0) >= 0)
+ {
+ sprintf(busname,"/dev/pcan%s",board->busname);
+ fd0 = LINUX_CAN_Open(busname, O_RDWR);
+ }
+
+ if(baudrate = TranslateBaudeRate(board->baudrate))
+ CAN_Init(fd0, baudrate, CAN_INIT_TYPE_ST);
+
+ return (CAN_HANDLE)fd0;
+}
+
+/***************************************************************************/
+int canClose_driver(CAN_HANDLE fd0)
+{
+ CAN_Close(fd0);
+ return 0;
+}
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/can_peak_win32/.cvsignore
--- a/drivers/can_peak_win32/.cvsignore Tue Apr 03 20:20:27 2007 +0200
+++ b/drivers/can_peak_win32/.cvsignore Wed Apr 04 13:04:31 2007 +0200
@@ -1,2 +1,7 @@
Makefile
-obf
+cancfg.h
+Debug UNICODE
+cygcan_peak_win32.dll
+can_peak_win32.ncb
+can_peak_win32.vcproj.KONG.edouard.user
+Release
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/can_peak_win32/Makefile.in
--- a/drivers/can_peak_win32/Makefile.in Tue Apr 03 20:20:27 2007 +0200
+++ b/drivers/can_peak_win32/Makefile.in Wed Apr 04 13:04:31 2007 +0200
@@ -29,27 +29,41 @@
TARGET = SUB_TARGET
CAN_DRIVER = SUB_CAN_DRIVER
TIMERS_DRIVER = SUB_TIMERS_DRIVER
-BINUTILS_PREFIX = SUB_BINUTILS_PREFIX
+ENABLE_DLL_DRIVERS=SUB_ENABLE_DLL_DRIVERS
+CAN_DLL_CFLAGS=SUB_CAN_DLL_CFLAGS
-INCLUDES = -I../../include -I../../include/$(TARGET) -I../../include/$(CAN_DRIVER) -I../../include/$(TIMERS_DRIVER)
+INCLUDES = -I../../include -I../../include/$(TARGET) -I../../include/$(CAN_DRIVER)
OBJS = $(CAN_DRIVER).o
-SRC_HFILES = ../../include/$(CAN_DRIVER)/cancfg.h
+ifeq ($(ENABLE_DLL_DRIVERS),1)
+CFLAGS += -fPIC
+DRIVER = cyg$(CAN_DRIVER).dll
+else
+DRIVER = $(OBJS)
+endif
-TARGET_HFILES = $(PREFIX)/include/canfestival/cancfg.h
+TARGET_SOFILES = $(PREFIX)/lib/$(DRIVER)
all: driver
-driver: $(OBJS)
+driver: $(DRIVER)
%o: %c
$(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -c $<
-install:
- mkdir -p $(PREFIX)/include/canfestival
- cp $(SRC_HFILES) $(PREFIX)/include/canfestival
-
+cyg$(CAN_DRIVER).dll: $(OBJS)
+ gcc -shared -o $@ \
+ -Wl,--export-all-symbols \
+ -Wl,--enable-auto-import \
+ -Wl,--whole-archive $< \
+ -Wl,--no-whole-archive $(CAN_DLL_CFLAGS) \
+ -Wl,--exclude-libs,ALL
+
+install: libcanfestival_$(CAN_DRIVER).so
+ mkdir -p $(PREFIX)/lib/
+ cp $@ $(PREFIX)/lib/
+
uninstall:
rm -f $(TARGET_HFILES)
@@ -57,12 +71,3 @@
rm -f $(OBJS)
mrproper: clean
-
-#********** make obfuscated translation *************************************
-.PHONY : obfuscate
-obfuscate:
- cobf -p obf/pp_gnu -o obf -c can_peak_win32.c -t obf/tlist.tok -m obf/mlist.tok -x pcan_ obf/can_peak_win32_org.c;\
- cat obf/can_peak_win32.c.header obf/can_peak_win32.c > can_peak_win32.c;\
- cat obf/cobf.h.header obf/cobf.h > cobf.h;\
- rm -f obf/can_peak_win32.c obf/cobf.h obf/cobf.log obf/uncobf.h
-
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/can_peak_win32/can_peak_win32.c
--- a/drivers/can_peak_win32/can_peak_win32.c Tue Apr 03 20:20:27 2007 +0200
+++ b/drivers/can_peak_win32/can_peak_win32.c Wed Apr 04 13:04:31 2007 +0200
@@ -1,119 +1,253 @@
/*
-
-This file is not part of CanFestival.
-This is third party contributed file.
-
-It is provided as-this and without any warranty
-
+This file is part of CanFestival, a library implementing CanOpen Stack.
+
+Copyright (C): Edouard TISSERANT and Francis DUPIN
+
+See COPYING file for copyrights details.
+
+This 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; either
+version 2.1 of the License, or (at your option) any later version.
+
+This 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 this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-//****************************************************************************
-// Copyright (C) 2006 PEAK System-Technik GmbH
-//
-// linux@peak-system.com
-// www.peak-system.com
-//
-// This part of software is proprietary. It is allowed to
-// distribute it with CanFestival.
-//
-// No warranty at all is given.
-//
-// Maintainer(s): Edouard TISSERANT (edouard.tisserant@lolitech.fr)
-//****************************************************************************
-
-/*
- Obfuscated by COBF (Version 1.06 2006-01-07 by BB) at Wed Aug 9 08:28:43 2006
-*/
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include"timer.h"
-#include"can_driver.h"
-#include"timers_driver.h"
-#include"cobf.h"
+#if defined(WIN32) && !defined(__CYGWIN__)
+#define usleep(micro) Sleep(micro%1000 ? (micro/1000) + 1 : (micro/1000))
+#else
+#include
+#include
+#include
+#include
+#endif
+
+#include "cancfg.h"
+#include "can_driver.h"
+
#ifndef extra_PCAN_init_params
-#define extra_PCAN_init_params
-#else
-#define extra_PCAN_init_params , pcan_o("PCANHwType") ? pcan_6( \
-pcan_o("PCANHwType"), pcan_v,0):0 , pcan_o("PCANIO_Port") ? pcan_6( \
-pcan_o("PCANIO_Port"), pcan_v,0):0 , pcan_o("PCANInterupt") ? pcan_6( \
- pcan_o("PCANInterupt"), pcan_v,0):0
-#endif
-#ifdef PCAN2_HEADER_
-#define pcan_t 2
-#else
-#define pcan_t 1
-#endif
-pcan_37 pcan_53{pcan_11 pcan_r;pcan_41 pcan_5;pcan_26*pcan_s;pcan_27*
-pcan_l;}pcan_c;pcan_c pcan_h[pcan_t]={{0,},};pcan_48 pcan_k=pcan_40;
-pcan_14 pcan_0(pcan_m pcan_b){
-#ifdef PCAN2_HEADER_
-pcan_d(pcan_h!=((pcan_c* )pcan_b))pcan_55(((pcan_c* )pcan_b)->pcan_l
-->pcan_20,pcan_y extra_PCAN_init_params);pcan_j
-#endif
-pcan_57(((pcan_c* )pcan_b)->pcan_l->pcan_20,pcan_y
-extra_PCAN_init_params);}pcan_u pcan_17(pcan_m pcan_b,pcan_8*pcan_e){
-pcan_u pcan_f;pcan_24 pcan_a;pcan_13 pcan_i;pcan_19(&pcan_k);
-#ifdef PCAN2_HEADER_
-pcan_d(pcan_h!=((pcan_c* )pcan_b))pcan_i=pcan_31(&pcan_a);pcan_j
-#endif
-pcan_i=pcan_51(&pcan_a);pcan_d(pcan_i==pcan_w){pcan_d(pcan_a.pcan_n&~
-(pcan_28|pcan_15)){pcan_d(pcan_a.pcan_n==pcan_23){pcan_2("\x21\x21"
-"\x21\x20\x50\x65\x61\x6b\x20\x62\x6f\x61\x72\x64\x20\x72\x65\x61\x64"
-"\x20\x3a\x20\x72\x65\x2d\x69\x6e\x69\x74\n");pcan_0(pcan_b);pcan_x(
-10000);}pcan_z(&pcan_k);pcan_q pcan_a.pcan_n==pcan_32?pcan_a.pcan_12[
-2]:pcan_50;}pcan_e->pcan_16.pcan_25=pcan_a.pcan_18;pcan_d(pcan_a.
-pcan_n==pcan_y)pcan_e->pcan_9=0;pcan_j pcan_e->pcan_9=1;pcan_e->
-pcan_1=pcan_a.pcan_7;pcan_3(pcan_f=0;pcan_fpcan_f[pcan_f]=pcan_a.pcan_12[pcan_f];}pcan_z(&pcan_k);pcan_q pcan_i
-;}pcan_14 pcan_47(pcan_m pcan_b){pcan_26*pcan_s=((pcan_c* )pcan_b)->
-pcan_s;pcan_8 pcan_e;pcan_21(((pcan_c* )pcan_b)->pcan_r){pcan_13
-pcan_i;pcan_d((pcan_i=pcan_17(pcan_b,&pcan_e))==pcan_w){pcan_30();
-pcan_54(pcan_s,&pcan_e);pcan_35();}pcan_j{pcan_d(!(pcan_i&pcan_33||
-pcan_i&pcan_42||pcan_i&pcan_49)){pcan_2("\x63\x61\x6e\x52\x65\x63\x65"
-"\x69\x76\x65\x20\x72\x65\x74\x75\x72\x6e\x65\x64\x20\x65\x72\x72\x6f"
-"\x72\x20\x28\x25\x64\x29\n",pcan_i);}pcan_x(1000);}}}pcan_u pcan_43(
-pcan_m pcan_b,pcan_8*pcan_e){pcan_u pcan_f;pcan_24 pcan_a;pcan_a.
-pcan_18=pcan_e->pcan_16.pcan_25;pcan_d(pcan_e->pcan_9==0)pcan_a.
-pcan_n=pcan_y;pcan_j{pcan_a.pcan_n=pcan_28|pcan_15;}pcan_a.pcan_7=
-pcan_e->pcan_1;pcan_3(pcan_f=0;pcan_fpcan_1;pcan_f++)pcan_a.
-pcan_12[pcan_f]=pcan_e->pcan_f[pcan_f];pcan_p=pcan_w;pcan_36{pcan_19(
-&pcan_k);
-#ifdef PCAN2_HEADER_
-pcan_d(pcan_h!=((pcan_c* )pcan_b))pcan_p=pcan_56(&pcan_a);pcan_j
-#endif
-pcan_p=pcan_46(&pcan_a);pcan_d(pcan_p){pcan_d(pcan_p==pcan_23){pcan_2
-("\x21\x21\x21\x20\x50\x65\x61\x6b\x20\x62\x6f\x61\x72\x64\x20\x77"
-"\x72\x69\x74\x65\x20\x3a\x20\x72\x65\x2d\x69\x6e\x69\x74\n");pcan_0(
-pcan_b);pcan_x(10000);}pcan_z(&pcan_k);pcan_x(100);}pcan_j{pcan_z(&
-pcan_k);}}pcan_21(pcan_p!=pcan_w&&((pcan_c* )pcan_b)->pcan_r);pcan_q 0
-;}pcan_m pcan_44(pcan_27*pcan_l){pcan_11 pcan_58[64];pcan_11*pcan_39;
-pcan_22 pcan_g;pcan_3(pcan_g=0;pcan_gpcan_s;
-pcan_0((pcan_c* )&pcan_h[pcan_g]);pcan_34((pcan_c* )&pcan_h[pcan_g],&
-pcan_h[pcan_g].pcan_5);pcan_q(pcan_c* )&pcan_h[pcan_g];}pcan_22
-pcan_59(pcan_m pcan_b){((pcan_c* )pcan_b)->pcan_r=0;
-#ifdef PCAN2_HEADER_
-pcan_d(pcan_h!=((pcan_c* )pcan_b))pcan_52();pcan_j
-#endif
-pcan_38();pcan_29(&((pcan_c* )pcan_b)->pcan_5);pcan_q 0;}
+ #define extra_PCAN_init_params /**/
+#else
+ #define extra_PCAN_init_params\
+ ,getenv("PCANHwType") ? strtol(getenv("PCANHwType"),NULL,0):0\
+ ,getenv("PCANIO_Port") ? strtol(getenv("PCANIO_Port"),NULL,0):0\
+ ,getenv("PCANInterupt") ? strtol(getenv("PCANInterupt"),NULL,0):0
+#endif
+
+static s_BOARD *first_board = NULL;
+#ifdef PCAN2_HEADER_
+static s_BOARD *second_board = NULL;
+#endif
+
+//pthread_mutex_t PeakCan_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+// Define for rtr CAN message
+#define CAN_INIT_TYPE_ST_RTR MSGTYPE_STANDARD | MSGTYPE_RTR
+
+/***************************************************************************/
+int TranslateBaudeRate(char* optarg){
+ if(!strcmp( optarg, "1M")) return CAN_BAUD_1M;
+ if(!strcmp( optarg, "500K")) return CAN_BAUD_500K;
+ if(!strcmp( optarg, "250K")) return CAN_BAUD_250K;
+ if(!strcmp( optarg, "125K")) return CAN_BAUD_125K;
+ if(!strcmp( optarg, "100K")) return CAN_BAUD_100K;
+ if(!strcmp( optarg, "50K")) return CAN_BAUD_50K;
+ if(!strcmp( optarg, "20K")) return CAN_BAUD_20K;
+ if(!strcmp( optarg, "10K")) return CAN_BAUD_10K;
+ if(!strcmp( optarg, "5K")) return CAN_BAUD_5K;
+ if(!strcmp( optarg, "none")) return 0;
+ return 0x0000;
+}
+
+void
+canInit (s_BOARD *board)
+{
+ int baudrate;
+
+#ifdef PCAN2_HEADER_
+ // if not the first handler
+ if(second_board == (s_BOARD *)board)
+ if(baudrate = TranslateBaudeRate(board->baudrate))
+ CAN2_Init (baudrate,
+ CAN_INIT_TYPE_ST extra_PCAN_init_params);
+#endif
+ if(first_board == (s_BOARD *)board)
+ if(baudrate = TranslateBaudeRate(board->baudrate))
+ CAN_Init (baudrate,
+ CAN_INIT_TYPE_ST extra_PCAN_init_params);
+}
+
+/*********functions which permit to communicate with the board****************/
+UNS8
+canReceive_driver (CAN_HANDLE fd0, Message * m)
+{
+ UNS8 data;
+ TPCANMsg peakMsg;
+
+ DWORD Res;
+
+ do{
+ // We read the queue looking for messages.
+ //
+ //pthread_mutex_lock (&PeakCan_mutex);
+#ifdef PCAN2_HEADER_
+ // if not the first handler
+ if(second_board == (s_BOARD *)fd0)
+ Res = CAN2_Read (&peakMsg);
+ else
+#endif
+ if(first_board == (s_BOARD *)fd0)
+ Res = CAN_Read (&peakMsg);
+ else
+ Res = CAN_ERR_BUSOFF;
+
+ // A message was received
+ // We process the message(s)
+ //
+ if (Res == CAN_ERR_OK)
+ {
+ // if something different that 11bit or rtr... problem
+ if (peakMsg.MSGTYPE & ~(MSGTYPE_STANDARD | MSGTYPE_RTR))
+ {
+ if (peakMsg.MSGTYPE == CAN_ERR_BUSOFF)
+ {
+ printf ("!!! Peak board read : re-init\n");
+ canInit((s_BOARD*) fd0);
+ usleep (10000);
+ }
+
+ // If status, return status if 29bit, return overrun
+ //pthread_mutex_unlock (&PeakCan_mutex);
+ return peakMsg.MSGTYPE ==
+ MSGTYPE_STATUS ? peakMsg.DATA[2] : CAN_ERR_OVERRUN;
+ }
+ m->cob_id.w = peakMsg.ID;
+ if (peakMsg.MSGTYPE == CAN_INIT_TYPE_ST) /* bits of MSGTYPE_ */
+ m->rtr = 0;
+ else
+ m->rtr = 1;
+ m->len = peakMsg.LEN; /* count of data bytes (0..8) */
+ for (data = 0; data < peakMsg.LEN; data++)
+ m->data[data] = peakMsg.DATA[data]; /* data bytes, up to 8 */
+
+ }else{
+ //pthread_mutex_unlock (&PeakCan_mutex);
+ //if (Res != CAN_ERR_OK)
+ //{
+ if (!
+ (Res & CAN_ERR_QRCVEMPTY || Res & CAN_ERR_BUSLIGHT
+ || Res & CAN_ERR_BUSHEAVY))
+ {
+ printf ("canReceive returned error (%d)\n", Res);
+ return 1;
+ }
+ usleep (1000);
+ }
+ }while(Res != CAN_ERR_OK);
+ return 0;
+}
+
+/***************************************************************************/
+UNS8
+canSend_driver (CAN_HANDLE fd0, Message * m)
+{
+ UNS8 data;
+ TPCANMsg peakMsg;
+ peakMsg.ID = m->cob_id.w; /* 11/29 bit code */
+ if (m->rtr == 0)
+ peakMsg.MSGTYPE = CAN_INIT_TYPE_ST; /* bits of MSGTYPE_ */
+ else
+ {
+ peakMsg.MSGTYPE = CAN_INIT_TYPE_ST_RTR; /* bits of MSGTYPE_ */
+ }
+ peakMsg.LEN = m->len;
+ /* count of data bytes (0..8) */
+ for (data = 0; data < m->len; data++)
+ peakMsg.DATA[data] = m->data[data]; /* data bytes, up to 8 */
+ do
+ {
+#ifdef PCAN2_HEADER_
+ // if not the first handler
+ if(second_board == (s_BOARD *)fd0)
+ errno = CAN2_Write (&peakMsg);
+ else
+#endif
+ if(first_board == (s_BOARD *)fd0)
+ errno = CAN_Write (&peakMsg);
+ else
+ goto fail;
+ if (errno)
+ {
+ if (errno == CAN_ERR_BUSOFF)
+ {
+ printf ("!!! Peak board write : re-init\n");
+ canInit((s_BOARD*)fd0);
+ usleep (10000);
+ }
+ usleep (1000);
+ }
+ }
+ while (errno != CAN_ERR_OK);
+ return 0;
+fail:
+ return 1;
+}
+
+/***************************************************************************/
+CAN_HANDLE
+canOpen_driver (s_BOARD * board)
+{
+#ifdef PCAN2_HEADER_
+ if(first_board != NULL && second_board != NULL)
+#else
+ if(first_board != NULL)
+#endif
+ {
+ fprintf (stderr, "Open failed.\n");
+ fprintf (stderr,
+ "can_peak_win32.c: no more can port available with this pcan library\n");
+ fprintf (stderr,
+ "can_peak_win32.c: please link another executable with another pcan lib\n");
+ return NULL;
+ }
+
+#ifdef PCAN2_HEADER_
+ if(first_board == NULL)
+ first_board = board;
+ else
+ second_board = board;
+#else
+ first_board = board;
+#endif
+
+ canInit(board);
+
+ return (CAN_HANDLE)board;
+}
+
+/***************************************************************************/
+int
+canClose_driver (CAN_HANDLE fd0)
+{
+#ifdef PCAN2_HEADER_
+ // if not the first handler
+ if(second_board == (s_BOARD *)fd0)
+ {
+ CAN2_Close ();
+ second_board = (s_BOARD *)NULL;
+ }else
+#endif
+ if(first_board == (s_BOARD *)fd0)
+ {
+ CAN_Close ();
+ first_board = (s_BOARD *)NULL;
+ }
+ return 0;
+}
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/can_peak_win32/can_peak_win32.def
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_peak_win32/can_peak_win32.def Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,7 @@
+LIBRARY can_peak_win32
+
+EXPORTS
+ canReceive_driver
+ canSend_driver
+ canOpen_driver
+ canClose_driver
\ No newline at end of file
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/can_peak_win32/can_peak_win32.vcproj
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_peak_win32/can_peak_win32.vcproj Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,386 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/can_peak_win32/cancfg.h.head
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_peak_win32/cancfg.h.head Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,37 @@
+/*
+This file is part of CanFestival, a library implementing CanOpen Stack.
+
+Copyright (C): Edouard TISSERANT and Francis DUPIN
+
+See COPYING file for copyrights details.
+
+This 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; either
+version 2.1 of the License, or (at your option) any later version.
+
+This 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 this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef __CANCFG_H__
+#define __CANCFG_H__
+
+
+#if defined(__CYGWIN__)
+#include
+#else
+#include
+#endif
+
+// Following part of the file is copied by configure script
+// from choosen PcanLight header file
+//-------------------------------------------------------------------------------
+//-------------------------------------------------------------------------------
+//-------------------------------------------------------------------------------
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/can_peak_win32/cancfg.h.tail
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_peak_win32/cancfg.h.tail Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,5 @@
+//-------------------------------------------------------------------------------
+//-------------------------------------------------------------------------------
+//-------------------------------------------------------------------------------
+
+#endif
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/can_socket/Makefile.in
--- a/drivers/can_socket/Makefile.in Tue Apr 03 20:20:27 2007 +0200
+++ b/drivers/can_socket/Makefile.in Wed Apr 04 13:04:31 2007 +0200
@@ -30,29 +30,37 @@
CAN_DRIVER = SUB_CAN_DRIVER
TIMERS_DRIVER = SUB_TIMERS_DRIVER
-INCLUDES = -I../../include -I../../include/$(TARGET) -I../../include/$(CAN_DRIVER) -I../../include/$(TIMERS_DRIVER)
+INCLUDES = -I../../include -I../../include/$(TARGET) -I../../include/$(CAN_DRIVER)
OBJS = $(CAN_DRIVER).o
-SRC_HFILES = ../../include/$(CAN_DRIVER)/cancfg.h
+ifeq ($(ENABLE_DLL_DRIVERS),1)
+CFLAGS += -fPIC
+DRIVER = libcanfestival_$(CAN_DRIVER).so
+else
+DRIVER = $(OBJS)
+endif
-TARGET_HFILES = $(PREFIX)/include/canfestival/cancfg.h
+TARGET_SOFILES = $(PREFIX)/lib/$(DRIVER)
all: driver
-driver: $(OBJS)
+driver: $(DRIVER)
%o: %c
- $(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -c $<
+ $(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -c $<
-install:
- mkdir -p $(PREFIX)/include/canfestival
- cp $(SRC_HFILES) $(PREFIX)/include/canfestival
+libcanfestival_$(CAN_DRIVER).so: $(OBJS)
+ gcc -shared -Wl,-soname,libcanfestival_$(CAN_DRIVER).so -o $@ $<
+install: libcanfestival_$(CAN_DRIVER).so
+ mkdir -p $(PREFIX)/lib/
+ cp $@ $(PREFIX)/lib/
+
uninstall:
- rm -f $(TARGET_HFILES)
+ rm -f $(TARGET_SOFILES)
clean:
- rm -f $(OBJS)
+ rm -f $(OBJS)
mrproper: clean
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/can_socket/can_socket.c
--- a/drivers/can_socket/can_socket.c Tue Apr 03 20:20:27 2007 +0200
+++ b/drivers/can_socket/can_socket.c Wed Apr 04 13:04:31 2007 +0200
@@ -47,28 +47,15 @@
#define CAN_IOCTL ioctl
#endif
-struct CANPort;
-#define CAN_HANDLE struct CANPort *
-
-#include
-
-#include "timer.h"
#include "can_driver.h"
-#include "timers_driver.h"
-
-typedef struct CANPort {
- int fd;
- TASK_HANDLE receiveTask;
- CO_Data* d;
-} CANPort;
/*********functions which permit to communicate with the board****************/
-UNS8 canReceive(CAN_HANDLE fd0, Message *m)
+UNS8 canReceive_driver(CAN_HANDLE fd0, Message *m)
{
int res;
struct can_frame frame;
- res = CAN_RECV(fd0->fd, &frame, sizeof(frame), 0);
+ res = CAN_RECV(fd0, &frame, sizeof(frame), 0);
if (res < 0)
return 1;
@@ -83,23 +70,9 @@
return 0;
}
-void canReceiveLoop(CAN_HANDLE fd0)
-{
- CO_Data* d = fd0->d;
- Message m;
-
- while (1) {
- if (canReceive(fd0, &m) != 0)
- break;
-
- EnterMutex();
- canDispatch(d, &m);
- LeaveMutex();
- }
-}
/***************************************************************************/
-UNS8 canSend(CAN_HANDLE fd0, Message *m)
+UNS8 canSend_driver(CAN_HANDLE fd0, Message *m)
{
int res;
struct can_frame frame;
@@ -113,7 +86,7 @@
else
memcpy(frame.data, m->data, 8);
- res = CAN_SEND(fd0->fd, &frame, sizeof(frame), 0);
+ res = CAN_SEND(fd0, &frame, sizeof(frame), 0);
if (res < 0)
return 1;
@@ -121,25 +94,21 @@
}
/***************************************************************************/
-CAN_HANDLE canOpen(s_BOARD *board)
+CAN_HANDLE canOpen_driver(s_BOARD *board)
{
CAN_HANDLE fd0;
struct ifreq ifr;
struct sockaddr_can addr;
int err;
- fd0 = malloc(sizeof(*fd0));
- if (!fd0)
- return NULL;
-
- fd0->fd = CAN_SOCKET(PF_CAN, SOCK_RAW, 0);
- if(fd0->fd < 0){
+ fd0 = CAN_SOCKET(PF_CAN, SOCK_RAW, 0);
+ if(fd0 < 0){
fprintf(stderr,"Socket creation failed.\n");
goto error_ret;
}
snprintf(ifr.ifr_name, IFNAMSIZ, CAN_IFNAME, board->busname);
- err = CAN_IOCTL(fd0->fd, SIOCGIFINDEX, &ifr);
+ err = CAN_IOCTL(fd0, SIOCGIFINDEX, &ifr);
if (err) {
fprintf(stderr, "Unknown device: %s\n", ifr.ifr_name);
goto error_close;
@@ -147,32 +116,27 @@
addr.can_family = AF_CAN;
addr.can_ifindex = ifr.ifr_ifindex;
- err = CAN_BIND(fd0->fd, (struct sockaddr *)&addr,
+ err = CAN_BIND(fd0, (struct sockaddr *)&addr,
sizeof(addr));
if (err) {
fprintf(stderr, "Binding failed.\n");
goto error_close;
}
- fd0->d = board->d;
- CreateReceiveTask(fd0, &fd0->receiveTask);
return fd0;
error_close:
- CAN_CLOSE(fd0->fd);
+ CAN_CLOSE(fd0);
error_ret:
- free(fd0);
return NULL;
}
/***************************************************************************/
-int canClose(CAN_HANDLE fd0)
+int canClose_driver(CAN_HANDLE fd0)
{
if (fd0) {
- WaitReceiveTaskEnd(&fd0->receiveTask);
- CAN_CLOSE(fd0->fd);
- free(fd0);
+ CAN_CLOSE(fd0);
}
return 0;
}
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/can_uvccm_win32/.cvsignore
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_uvccm_win32/.cvsignore Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,3 @@
+Debug UNICODE
+can_uvccm_win32.vcproj.KONG.edouard.user
+Release
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/can_uvccm_win32/can_uvccm_win32.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_uvccm_win32/can_uvccm_win32.cpp Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,331 @@
+// can_uvccm_win32 adapter (http://www.gridconnect.com)
+// driver for CanFestival-3 Win32 port
+// Copyright (C) 2007 Leonid Tochinski, ChattenAssociates, Inc.
+
+
+#include
+#include
+#if 0 // change to 1 if you use boost
+#include
+#else
+#include
+#endif
+
+extern "C" {
+#include "can_driver.h"
+}
+class can_uvccm_win32
+ {
+ public:
+ class error
+ {
+ };
+ can_uvccm_win32(s_BOARD *board);
+ ~can_uvccm_win32();
+ bool send(const Message *m);
+ bool receive(Message *m);
+ private:
+ bool open_rs232(int port = 1, int baud_rate = 57600);
+ bool close_rs232();
+ bool get_can_data(const char* can_cmd_buf, long& bufsize, Message* m);
+ bool set_can_data(const Message& m, std::string& can_cmd);
+ private:
+ HANDLE m_port;
+ HANDLE m_read_event;
+ HANDLE m_write_event;
+ std::string m_residual_buffer;
+ };
+
+can_uvccm_win32::can_uvccm_win32(s_BOARD *board) : m_port(INVALID_HANDLE_VALUE),
+ m_read_event(0),
+ m_write_event(0)
+ {
+ if (strcmp( board->baudrate, "125K") || !open_rs232(1))
+ throw error();
+ }
+
+can_uvccm_win32::~can_uvccm_win32()
+ {
+ close_rs232();
+ }
+
+bool can_uvccm_win32::send(const Message *m)
+ {
+ if (m_port == INVALID_HANDLE_VALUE)
+ return false;
+
+ // build can_uvccm_win32 command string
+ std::string can_cmd;
+ set_can_data(*m, can_cmd);
+
+ OVERLAPPED overlapped;
+ ::memset(&overlapped, 0, sizeof overlapped);
+ overlapped.hEvent = m_write_event;
+ ::ResetEvent(overlapped.hEvent);
+
+ unsigned long bytes_written = 0;
+ ::WriteFile(m_port, can_cmd.c_str(), (unsigned long)can_cmd.size(), &bytes_written, &overlapped);
+ // wait for write operation completion
+ enum { WRITE_TIMEOUT = 1000 };
+ ::WaitForSingleObject(overlapped.hEvent, WRITE_TIMEOUT);
+ // get number of bytes written
+ ::GetOverlappedResult(m_port, &overlapped, &bytes_written, FALSE);
+
+ bool result = (bytes_written == can_cmd.size());
+
+ return result;
+ }
+
+
+bool can_uvccm_win32::receive(Message *m)
+ {
+ if (m_port == INVALID_HANDLE_VALUE)
+ return false;
+
+ long res_buffer_size = (long)m_residual_buffer.size();
+ bool result = get_can_data(m_residual_buffer.c_str(), res_buffer_size, m);
+ if (result)
+ {
+ m_residual_buffer.erase(0, res_buffer_size);
+ return true;
+ }
+
+ enum { READ_TIMEOUT = 500 };
+
+ OVERLAPPED overlapped;
+ ::memset(&overlapped, 0, sizeof overlapped);
+ overlapped.hEvent = m_read_event;
+ ::ResetEvent(overlapped.hEvent);
+ unsigned long event_mask = 0;
+
+ if (FALSE == ::WaitCommEvent(m_port, &event_mask, &overlapped) && ERROR_IO_PENDING == ::GetLastError())
+ {
+ if (WAIT_TIMEOUT == ::WaitForSingleObject(overlapped.hEvent, READ_TIMEOUT))
+ return false;
+ }
+
+ // get number of bytes in the input que
+ COMSTAT stat;
+ ::memset(&stat, 0, sizeof stat);
+ unsigned long errors = 0;
+ ::ClearCommError(m_port, &errors, &stat);
+ if (stat.cbInQue == 0)
+ return false;
+ char buffer[3000];
+
+ unsigned long bytes_to_read = min(stat.cbInQue, sizeof (buffer));
+
+ unsigned long bytes_read = 0;
+ ::ReadFile(m_port, buffer, bytes_to_read, &bytes_read, &overlapped);
+ // wait for read operation completion
+ ::WaitForSingleObject(overlapped.hEvent, READ_TIMEOUT);
+ // get number of bytes read
+ ::GetOverlappedResult(m_port, &overlapped, &bytes_read, FALSE);
+ result = false;
+ if (bytes_read > 0)
+ {
+ m_residual_buffer.append(buffer, bytes_read);
+ res_buffer_size = (long)m_residual_buffer.size();
+ result = get_can_data(m_residual_buffer.c_str(), res_buffer_size, m);
+ if (result)
+ m_residual_buffer.erase(0, res_buffer_size);
+ }
+ return result;
+ }
+
+bool can_uvccm_win32::open_rs232(int port, int baud_rate)
+ {
+ if (m_port != INVALID_HANDLE_VALUE)
+ return true;
+
+ std::ostringstream device_name;
+ device_name << "COM" << port;
+
+ m_port = ::CreateFile(device_name.str().c_str(),
+ GENERIC_READ | GENERIC_WRITE,
+ 0, // exclusive access
+ NULL, // no security
+ OPEN_EXISTING,
+ FILE_FLAG_OVERLAPPED, // overlapped I/O
+ NULL); // null template
+
+ // Check the returned handle for INVALID_HANDLE_VALUE and then set the buffer sizes.
+ if (m_port == INVALID_HANDLE_VALUE)
+ return false;
+
+ // SetCommMask(m_hCom,EV_RXCHAR|EV_TXEMPTY|EV_CTS|EV_DSR|EV_RLSD|EV_BREAK|EV_ERR|EV_RING); //
+ ::SetCommMask(m_port, EV_RXFLAG);
+
+ COMMTIMEOUTS timeouts;
+ ::memset(&timeouts, 0, sizeof (timeouts));
+ timeouts.ReadIntervalTimeout = -1;
+ timeouts.ReadTotalTimeoutConstant = 0;
+ timeouts.ReadTotalTimeoutMultiplier = 0;
+ timeouts.WriteTotalTimeoutConstant = 5000;
+ timeouts.WriteTotalTimeoutMultiplier = 0;
+ SetCommTimeouts(m_port, &timeouts); //
+
+ ::SetupComm(m_port, 1024, 512); // set buffer sizes
+
+ // Port settings are specified in a Data Communication Block (DCB). The easiest way to initialize a DCB is to call GetCommState to fill in its default values, override the values that you want to change and then call SetCommState to set the values.
+ DCB dcb;
+ ::memset(&dcb, 0, sizeof (dcb));
+ ::GetCommState(m_port, &dcb);
+ dcb.BaudRate = baud_rate;
+ dcb.ByteSize = 8;
+ dcb.Parity = NOPARITY;
+ dcb.StopBits = ONESTOPBIT;
+ dcb.fAbortOnError = TRUE;
+ dcb.EvtChar = 0x0A; // '\n' character
+ ::SetCommState(m_port, &dcb);
+
+ ::PurgeComm(m_port, PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR);
+
+ m_read_event = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+ m_write_event = ::CreateEvent(NULL, TRUE, FALSE, NULL);
+
+ return true;
+ }
+
+bool can_uvccm_win32::close_rs232()
+ {
+ if (m_port != INVALID_HANDLE_VALUE)
+ {
+ ::PurgeComm(m_port, PURGE_RXABORT | PURGE_RXCLEAR | PURGE_TXABORT | PURGE_TXCLEAR);
+ ::CloseHandle(m_port);
+ m_port = INVALID_HANDLE_VALUE;
+ ::CloseHandle(m_read_event);
+ m_read_event = 0;
+ ::CloseHandle(m_write_event);
+ m_write_event = 0;
+ m_residual_buffer.clear();
+ }
+ return true;
+ }
+
+bool can_uvccm_win32::get_can_data(const char* can_cmd_buf, long& bufsize, Message* m)
+ {
+ if (bufsize < 5)
+ {
+ bufsize = 0;
+ return false;
+ }
+
+ Message msg;
+ ::memset(&msg, 0 , sizeof (msg));
+ char colon = 0, type = 0, request = 0;
+ std::istringstream buf(std::string(can_cmd_buf, bufsize));
+ buf >> colon >> type >> std::hex >> msg.cob_id.w >> request;
+ if (colon != ':' || (type != 'S' && type != 'X'))
+ {
+ bufsize = 0;
+ return false;
+ }
+ if (request == 'N')
+ {
+ msg.rtr = 0;
+ for (msg.len = 0; msg.len < 8; ++msg.len)
+ {
+ std::string data_byte_str;
+ buf >> std::setw(2) >> data_byte_str;
+ if (data_byte_str[0] == ';')
+ break;
+ long byte_val = -1;
+ std::istringstream(data_byte_str) >> std::hex >> byte_val;
+ if (byte_val == -1)
+ {
+ bufsize = 0;
+ return false;
+ }
+ msg.data[msg.len] = (UNS8)byte_val;
+ }
+ if (msg.len == 8)
+ {
+ char semicolon = 0;
+ buf >> semicolon;
+ if (semicolon != ';')
+ {
+ bufsize = 0;
+ return false;
+ }
+ }
+
+ }
+ else if (request == 'R')
+ {
+ msg.rtr = 1;
+ buf >> msg.len;
+ }
+ else
+ {
+ bufsize = 0;
+ return false;
+ }
+
+ bufsize = buf.tellg();
+
+ *m = msg;
+ return true;
+ }
+
+bool can_uvccm_win32::set_can_data(const Message& m, std::string& can_cmd)
+ {
+ // build can_uvccm_win32 command string
+ std::ostringstream can_cmd_str;
+ can_cmd_str << ":S" << std::hex << m.cob_id.w;
+ if (m.rtr == 1)
+ {
+ can_cmd_str << 'R' << (long)m.len;
+ }
+ else
+ {
+ can_cmd_str << 'N';
+ for (int i = 0; i < m.len; ++i)
+ can_cmd_str << std::hex << std::setfill('0') << std::setw(2) << (long)m.data[i];
+ }
+ can_cmd_str << ';';
+ can_cmd = can_cmd_str.str();
+#ifdef BOOST_VERSION
+ boost::to_upper(can_cmd);
+#else
+ std::transform(can_cmd.begin(),can_cmd.end(),can_cmd.begin(),::toupper);
+#endif
+ return true;
+ }
+
+
+//------------------------------------------------------------------------
+extern "C"
+ UNS8 canReceive_driver(CAN_HANDLE fd0, Message *m)
+ {
+ return (UNS8)(!(reinterpret_cast(fd0)->receive(m)));
+ }
+
+extern "C"
+ UNS8 canSend_driver(CAN_HANDLE fd0, Message *m)
+ {
+ return (UNS8)reinterpret_cast(fd0)->send(m);
+ }
+
+extern "C"
+ CAN_HANDLE canOpen_driver(s_BOARD *board)
+ {
+ try
+ {
+ return (CAN_HANDLE) new can_uvccm_win32(board);
+ }
+ catch (can_uvccm_win32::error&)
+ {
+ return NULL;
+ }
+ }
+
+extern "C"
+ int canClose_driver(CAN_HANDLE inst)
+ {
+ delete reinterpret_cast(inst);
+ return 1;
+ }
+
+
+
\ No newline at end of file
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/can_uvccm_win32/can_uvccm_win32.def
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_uvccm_win32/can_uvccm_win32.def Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,7 @@
+LIBRARY can_uvccm_win32
+
+EXPORTS
+ canReceive_driver
+ canSend_driver
+ canOpen_driver
+ canClose_driver
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/can_uvccm_win32/can_uvccm_win32.vcproj
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/can_uvccm_win32/can_uvccm_win32.vcproj Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,374 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/can_virtual/Makefile.in
--- a/drivers/can_virtual/Makefile.in Tue Apr 03 20:20:27 2007 +0200
+++ b/drivers/can_virtual/Makefile.in Wed Apr 04 13:04:31 2007 +0200
@@ -25,36 +25,40 @@
OPT_CFLAGS = -O2
CFLAGS = SUB_OPT_CFLAGS
PROG_CFLAGS = SUB_PROG_CFLAGS
-LIBS = -lm
-SHAREDLIBOPT = -shared
-OS_NAME = SUB_OS_NAME
-ARCH_NAME = SUB_ARCH_NAME
PREFIX = SUB_PREFIX
TARGET = SUB_TARGET
CAN_DRIVER = SUB_CAN_DRIVER
TIMERS_DRIVER = SUB_TIMERS_DRIVER
-INCLUDES = -I../../include -I../../include/$(TARGET) -I../../include/$(CAN_DRIVER) -I../../include/$(TIMERS_DRIVER)
+INCLUDES = -I../../include -I../../include/$(TARGET) -I../../include/$(CAN_DRIVER)
OBJS = $(CAN_DRIVER).o
-SRC_HFILES = ../../include/$(CAN_DRIVER)/cancfg.h
+ifeq ($(ENABLE_DLL_DRIVERS),1)
+CFLAGS += -fPIC
+DRIVER = libcanfestival_$(CAN_DRIVER).so
+else
+DRIVER = $(OBJS)
+endif
-TARGET_HFILES = $(PREFIX)/include/canfestival/cancfg.h
+TARGET_SOFILES = $(PREFIX)/lib/$(DRIVER)
all: driver
-driver: $(OBJS)
+driver: $(DRIVER)
%o: %c
$(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -c $<
-install:
- mkdir -p $(PREFIX)/include/canfestival
- cp $(SRC_HFILES) $(PREFIX)/include/canfestival
+libcanfestival_$(CAN_DRIVER).so: $(OBJS)
+ gcc -shared -Wl,-soname,libcanfestival_$(CAN_DRIVER).so -o $@ $<
+install: libcanfestival_$(CAN_DRIVER).so
+ mkdir -p $(PREFIX)/lib/
+ cp $@ $(PREFIX)/lib/
+
uninstall:
- rm -f $(TARGET_HFILES)
+ rm -f $(TARGET_SOFILES)
clean:
rm -f $(OBJS)
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/can_virtual/can_virtual.c
--- a/drivers/can_virtual/can_virtual.c Tue Apr 03 20:20:27 2007 +0200
+++ b/drivers/can_virtual/can_virtual.c Wed Apr 04 13:04:31 2007 +0200
@@ -24,30 +24,22 @@
Virtual CAN driver.
*/
-#include
+#include
+#include
-#include
-#include
-#include
+#include "can_driver.h"
-#include
-#include "timer.h"
-#include "can_driver.h"
-#include "timers_driver.h"
-
-#define MAX_NB_CAN_PIPES 10
+#define MAX_NB_CAN_PIPES 16
typedef struct {
char used;
int pipe[2];
- TASK_HANDLE receiveTask;
- CO_Data* d;
} CANPipe;
-CANPipe canpipes[MAX_NB_CAN_PIPES] = {{0,{0,0},},};
+CANPipe canpipes[MAX_NB_CAN_PIPES] = {{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},};
/*********functions which permit to communicate with the board****************/
-UNS8 canReceive(CAN_HANDLE fd0, Message *m)
+UNS8 canReceive_driver(CAN_HANDLE fd0, Message *m)
{
if(read(((CANPipe*)fd0)->pipe[0], m, sizeof(Message)) < sizeof(Message))
{
@@ -56,24 +48,8 @@
return 0;
}
-void canReceiveLoop(CAN_HANDLE fd0)
-{
- CO_Data* d = ((CANPipe*)fd0)->d;
- Message m;
- while (1) {
- if(!canReceive(fd0, &m))
- {
- EnterMutex();
- canDispatch(d, &m);
- LeaveMutex();
- }else{
- break;
- }
- }
-}
-
/***************************************************************************/
-UNS8 canSend(CAN_HANDLE fd0, Message *m)
+UNS8 canSend_driver(CAN_HANDLE fd0, Message *m)
{
int i;
// Send to all readers, except myself
@@ -86,9 +62,22 @@
}
return 0;
}
-
+/*
+int TranslateBaudeRate(char* optarg){
+ if(!strcmp( optarg, "1M")) return 1000;
+ if(!strcmp( optarg, "500K")) return 500;
+ if(!strcmp( optarg, "250K")) return 250;
+ if(!strcmp( optarg, "125K")) return 125;
+ if(!strcmp( optarg, "100K")) return 100;
+ if(!strcmp( optarg, "50K")) return 50;
+ if(!strcmp( optarg, "20K")) return 20;
+ if(!strcmp( optarg, "10K")) return 10;
+ if(!strcmp( optarg, "5K")) return 5;
+ if(!strcmp( optarg, "none")) return 0;
+ return 0;
+}*/
/***************************************************************************/
-CAN_HANDLE canOpen(s_BOARD *board)
+CAN_HANDLE canOpen_driver(s_BOARD *board)
{
int i;
for(i=0; i < MAX_NB_CAN_PIPES; i++)
@@ -105,20 +94,16 @@
}
canpipes[i].used = 1;
-
- canpipes[i].d = board->d;
- CreateReceiveTask((CAN_HANDLE) &canpipes[i], &canpipes[i].receiveTask);
-
return (CAN_HANDLE) &canpipes[i];
}
/***************************************************************************/
-int canClose(CAN_HANDLE fd0)
+int canClose_driver(CAN_HANDLE fd0)
{
close(((CANPipe*)fd0)->pipe[0]);
close(((CANPipe*)fd0)->pipe[1]);
((CANPipe*)fd0)->used = 0;
- WaitReceiveTaskEnd(&((CANPipe*)fd0)->receiveTask);
+ return 0;
}
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/generic/Makefile.in
--- a/drivers/generic/Makefile.in Tue Apr 03 20:20:27 2007 +0200
+++ b/drivers/generic/Makefile.in Wed Apr 04 13:04:31 2007 +0200
@@ -25,8 +25,6 @@
OPT_CFLAGS = -O2
CFLAGS = SUB_OPT_CFLAGS
PROG_CFLAGS = SUB_PROG_CFLAGS
-LIBS = -lm
-SHAREDLIBOPT = -shared
OS_NAME = SUB_OS_NAME
ARCH_NAME = SUB_ARCH_NAME
PREFIX = SUB_PREFIX
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/hcs12/Makefile.in
--- a/drivers/hcs12/Makefile.in Tue Apr 03 20:20:27 2007 +0200
+++ b/drivers/hcs12/Makefile.in Wed Apr 04 13:04:31 2007 +0200
@@ -24,8 +24,6 @@
CC = SUB_CC
CFLAGS =
PROG_CFLAGS = SUB_PROG_CFLAGS
-LIBS = -lm
-SHAREDLIBOPT = -shared
OS_NAME = SUB_OS_NAME
ARCH_NAME = SUB_ARCH_NAME
PREFIX = SUB_PREFIX
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/timers_unix/Makefile.in
--- a/drivers/timers_unix/Makefile.in Tue Apr 03 20:20:27 2007 +0200
+++ b/drivers/timers_unix/Makefile.in Wed Apr 04 13:04:31 2007 +0200
@@ -25,8 +25,6 @@
OPT_CFLAGS = -O2
CFLAGS = SUB_OPT_CFLAGS
PROG_CFLAGS = SUB_PROG_CFLAGS
-LIBS = -lm
-SHAREDLIBOPT = -shared
OS_NAME = SUB_OS_NAME
ARCH_NAME = SUB_ARCH_NAME
PREFIX = SUB_PREFIX
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/timers_unix/timers_unix.c
--- a/drivers/timers_unix/timers_unix.c Tue Apr 03 20:20:27 2007 +0200
+++ b/drivers/timers_unix/timers_unix.c Wed Apr 04 13:04:31 2007 +0200
@@ -5,7 +5,6 @@
#include
#include "applicfg.h"
-#include "can_driver.h"
#include "timer.h"
pthread_mutex_t CanFestival_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -28,7 +27,7 @@
pthread_mutex_unlock(&CanFestival_mutex);
}
-void timer_notify(int val)
+void timer_notify(sigval_t val)
{
gettimeofday(&last_sig,NULL);
EnterMutex();
@@ -65,20 +64,15 @@
SetAlarm(NULL, 0, init_callback, 0, 0);
}
-void ReceiveLoop(void* arg)
+void CreateReceiveTask(CAN_PORT port, TASK_HANDLE* Thread, void* ReceiveLoopPtr)
{
- canReceiveLoop((CAN_HANDLE)arg);
+ pthread_create(Thread, NULL, ReceiveLoopPtr, (void*)port);
}
-void CreateReceiveTask(CAN_HANDLE fd0, TASK_HANDLE* Thread)
+void WaitReceiveTaskEnd(TASK_HANDLE Thread)
{
- pthread_create(Thread, NULL, (void *)&ReceiveLoop, (void*)fd0);
-}
-
-void WaitReceiveTaskEnd(TASK_HANDLE *Thread)
-{
- pthread_kill(*Thread, SIGTERM);
- pthread_join(*Thread, NULL);
+ pthread_kill(Thread, SIGTERM);
+ pthread_join(Thread, NULL);
}
#define maxval(a,b) ((a>b)?a:b)
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/timers_xeno/Makefile.in
--- a/drivers/timers_xeno/Makefile.in Tue Apr 03 20:20:27 2007 +0200
+++ b/drivers/timers_xeno/Makefile.in Wed Apr 04 13:04:31 2007 +0200
@@ -25,8 +25,6 @@
OPT_CFLAGS = -O2
CFLAGS = SUB_OPT_CFLAGS
PROG_CFLAGS = SUB_PROG_CFLAGS
-LIBS = -lm
-SHAREDLIBOPT = -shared
OS_NAME = SUB_OS_NAME
ARCH_NAME = SUB_ARCH_NAME
PREFIX = SUB_PREFIX
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/timers_xeno/timers_xeno.c
--- a/drivers/timers_xeno/timers_xeno.c Tue Apr 03 20:20:27 2007 +0200
+++ b/drivers/timers_xeno/timers_xeno.c Wed Apr 04 13:04:31 2007 +0200
@@ -90,12 +90,7 @@
cleanup_all();
}
-void ReceiveLoop_task_proc(void* arg)
-{
- canReceiveLoop((CAN_HANDLE)arg);
-}
-
-void CreateReceiveTask(CAN_HANDLE fd0, TASK_HANDLE *ReceiveLoop_task)
+void CreateReceiveTask(CAN_PORT fd0, TASK_HANDLE *ReceiveLoop_task, void* ReceiveLoop_task_proc)
{
int ret;
static int id = 0;
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/unix/Makefile.in
--- a/drivers/unix/Makefile.in Tue Apr 03 20:20:27 2007 +0200
+++ b/drivers/unix/Makefile.in Wed Apr 04 13:04:31 2007 +0200
@@ -25,37 +25,35 @@
OPT_CFLAGS = -O2
CFLAGS = SUB_OPT_CFLAGS
PROG_CFLAGS = SUB_PROG_CFLAGS
-LIBS = -lm
-SHAREDLIBOPT = -shared
OS_NAME = SUB_OS_NAME
ARCH_NAME = SUB_ARCH_NAME
PREFIX = SUB_PREFIX
TARGET = SUB_TARGET
CAN_DRIVER = SUB_CAN_DRIVER
TIMERS_DRIVER = SUB_TIMERS_DRIVER
+ENABLE_DLL_DRIVERS = SUB_ENABLE_DLL_DRIVERS
-INCLUDES = -I../../include -I../../include/$(SUB_TARGET)
+INCLUDES = -I../../include -I../../include/$(TARGET) -I../../include/$(TIMERS_DRIVER)
-OBJS =
+OBJS = $(TARGET).o
# add timers driver if any
ifneq ($(TIMERS_DRIVER),timers_)
OBJS += ../$(TIMERS_DRIVER)/$(TIMERS_DRIVER).o
endif
-# add can driver if any
-ifneq ($(CAN_DRIVER),can_)
-OBJS += ../$(CAN_DRIVER)/$(CAN_DRIVER).o
-endif
+SRC_HFILES = ../../include/$(TARGET)/applicfg.h ../../include/$(TARGET)/canfestival.h
-SRC_HFILES = ../../include/$(TARGET)/applicfg.h
-
-TARGET_HFILES = $(PREFIX)/include/$(TARGET)/applicfg.h
+TARGET_HFILES = $(PREFIX)/include/$(TARGET)/applicfg.h $(PREFIX)/include/$(TARGET)/canfestival.h
all: driver
driver: $(OBJS)
+
+%o: %c
+ $(CC) $(CFLAGS) $(PROG_CFLAGS) ${PROGDEFINES} $(INCLUDES) -o $@ -c $<
+
#../$(TIMERS_DRIVER)/$(TIMERS_DRIVER).o:
# $(MAKE) -C ../$(TIMERS_DRIVER) driver
@@ -78,6 +76,7 @@
rm -f $(TARGET_HFILES)
clean:
+ rm -f $(OBJS)
rm -f libcanfestival_$(TARGET).a
mrproper: clean
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/unix/unix.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/unix/unix.c Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,200 @@
+/*
+This file is part of CanFestival, a library implementing CanOpen Stack.
+
+Copyright (C): Edouard TISSERANT and Francis DUPIN
+
+See COPYING file for copyrights details.
+
+This 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; either
+version 2.1 of the License, or (at your option) any later version.
+
+This 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 this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#include
+#include
+#include
+
+#ifndef NOT_USE_DYNAMIC_LOADING
+#define DLL_CALL(funcname) (* funcname##_driver)
+#define FCT_PTR_INIT =NULL
+
+#ifdef WIN32
+#define DLSYM(name)\
+ *(void **) (&_##name) = GetProcAddress(handle, TEXT(#name"_driver"));\
+ if (name##_driver == NULL) {\
+ fprintf (stderr, "Error loading symbol %s\n",#name"_driver");\
+ UnLoadCanDriver(handle);\
+ return NULL;\
+ }
+
+#else
+#define DLSYM(name)\
+ *(void **) (&name##_driver) = dlsym(handle, #name"_driver");\
+ if ((error = dlerror()) != NULL) {\
+ fprintf (stderr, "%s\n", error);\
+ UnLoadCanDriver(handle);\
+ return NULL;\
+ }
+#endif
+
+#else /*NOT_USE_DYNAMIC_LOADING*/
+
+/*Function call is direct*/
+#define DLL_CALL(funcname) funcname##_driver
+
+#endif /*NOT_USE_DYNAMIC_LOADING*/
+
+#include "data.h"
+#include "canfestival.h"
+#include "timers_driver.h"
+
+#define MAX_NB_CAN_PORTS 16
+
+typedef struct {
+ char used;
+ CAN_HANDLE fd;
+ TASK_HANDLE receiveTask;
+ CO_Data* d;
+} CANPort;
+
+#include "can_driver.h"
+
+/*Declares the funtion pointers for dll binding or simple protos*/
+/*UNS8 DLL_CALL(canReceive)(CAN_HANDLE, Message *);
+UNS8 DLL_CALL(canSend)(CAN_HANDLE, Message *);
+CAN_HANDLE DLL_CALL(canOpen)(s_BOARD *);
+int DLL_CALL(canClose)(CAN_HANDLE);
+*/
+CANPort canports[MAX_NB_CAN_PORTS] = {{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,},{0,}};
+
+#ifndef NOT_USE_DYNAMIC_LOADING
+
+/*UnLoads the dll*/
+UNS8 UnLoadCanDriver(LIB_HANDLE handle)
+{
+ if(handle!=NULL)
+ {
+#ifdef WIN32
+ FreeLibrary(handle);
+#else
+ dlclose(handle);
+#endif
+ handle=NULL;
+ return 0;
+ }
+ return -1;
+}
+
+/*Loads the dll and get funcs ptr*/
+LIB_HANDLE LoadCanDriver(char* driver_name)
+{
+ LIB_HANDLE handle = NULL;
+ char *error;
+
+#ifdef WIN32
+
+ if(handle==NULL)
+ {
+ handle = LoadLibrary(driver_name);
+ }
+
+ if (handle == NULL) {
+ fprintf(stderr,"Error loading Can Driver dll \n");
+ return -1;
+ }
+
+#else
+ if(handle==NULL)
+ {
+ handle = dlopen(driver_name, RTLD_LAZY);
+ }
+
+ if (!handle) {
+ fprintf (stderr, "%s\n", dlerror());
+ return NULL;
+ }
+#endif
+
+ /*Get function ptr*/
+ DLSYM(canReceive)
+ DLSYM(canSend)
+ DLSYM(canOpen)
+ DLSYM(canClose)
+
+ return 0;
+}
+
+#endif
+
+
+
+/*Not needed -- canReceiveLoop calls _canReceive directly *//*
+UNS8 canReceive(CAN_PORT port, Message *m)
+{
+ return DLL_CALL(canReceive)(port->fd, Message *m);
+}
+*/
+
+UNS8 canSend(CAN_PORT port, Message *m)
+{
+ return DLL_CALL(canSend)(((CANPort*)port)->fd, m);
+}
+
+void canReceiveLoop(CAN_PORT port)
+{
+ Message m;
+
+ while (1) {
+ if (DLL_CALL(canReceive)(((CANPort*)port)->fd, &m) != 0)
+ break;
+
+ EnterMutex();
+ canDispatch(((CANPort*)port)->d, &m);
+ LeaveMutex();
+ }
+}
+CAN_PORT canOpen(s_BOARD *board, CO_Data * d)
+{
+ int i;
+ for(i=0; i < MAX_NB_CAN_PORTS; i++)
+ {
+ if(!canports[i].used)
+ break;
+ }
+
+#ifndef NOT_USE_DYNAMIC_LOADING
+ if (&DLL_CALL(canOpen)==NULL) {
+ fprintf(stderr,"CanOpen : Can Driver dll not loaded\n");
+ return NULL;
+ }
+#endif
+ CAN_HANDLE fd0 = DLL_CALL(canOpen)(board);
+
+ canports[i].used = 1;
+ canports[i].fd = fd0;
+ canports[i].d = d;
+
+ CreateReceiveTask(&(canports[i]), &canports[i].receiveTask, &canReceiveLoop);
+
+ return (CAN_PORT)&canports[i];
+}
+
+int canClose(CAN_PORT port)
+{
+ ((CANPort*)port)->used = 0;
+ int res = DLL_CALL(canClose)(((CANPort*)port)->fd);
+
+ WaitReceiveTaskEnd(((CANPort*)port)->receiveTask);
+ return res;
+}
+
+
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/win32/drivers_win32.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/win32/drivers_win32.cpp Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,290 @@
+/*
+This file is part of CanFestival, a library implementing CanOpen Stack.
+
+Copyright (C): Edouard TISSERANT and Francis DUPIN
+Copyright (C) Win32 Port Leonid Tochinski
+
+See COPYING file for copyrights details.
+
+This 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; either
+version 2.1 of the License, or (at your option) any later version.
+
+This 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 this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+/*
+ CAN driver interface.
+*/
+
+#include
+
+extern "C"
+ {
+#define DLL_CALL(funcname) (*_##funcname)
+#define FCT_PTR_INIT =NULL
+#include "canfestival.h"
+#include "timer.h"
+
+#include "nvram_driver.h"
+#include "lss_driver.h"
+#include "timers_driver.h"
+ };
+
+typedef UNS8 (*CANRECEIVE_DRIVER_PROC)(void* inst, Message *m);
+typedef UNS8 (*CANSEND_DRIVER_PROC)(void* inst, const Message *m);
+typedef void* (*CANOPEN_DRIVER_PROC)(s_BOARD *board);
+typedef int (*CANCLOSE_DRIVER_PROC)(void* inst);
+
+typedef int (*NVRAM_OPEN_PROC)(void);
+typedef void (*NVRAM_CLOSE_PROC)(void);
+typedef char (*NVRAM_WRITE_PROC)(int type, int access_attr, void *data);
+typedef char (*NVRAM_READ_PROC)(int type, int access_attr, void *data);
+
+typedef void (*LED_SET_REDGREEN_PROC)(CO_Data *d, unsigned char bits);
+
+typedef UNS8 (*BAUDRATE_VALID_PROC)(UNS32 table_index);
+typedef void (*BAUDRATE_SET_PROC)(UNS8 table_index);
+
+class driver_procs
+ {
+ public:
+ driver_procs();
+ ~driver_procs();
+
+ HMODULE load_canfestival_driver(LPCTSTR driver_name);
+ bool can_driver_valid() const;
+
+ public:
+ // can driver
+ CANRECEIVE_DRIVER_PROC m_canReceive;
+ CANSEND_DRIVER_PROC m_canSend;
+ CANOPEN_DRIVER_PROC m_canOpen;
+ CANCLOSE_DRIVER_PROC m_canClose;
+
+ // nvram driver
+ NVRAM_OPEN_PROC m_nvram_open;
+ NVRAM_CLOSE_PROC m_nvram_close;
+ NVRAM_WRITE_PROC m_nvram_write;
+ NVRAM_READ_PROC m_nvram_read;
+ // led driver
+ LED_SET_REDGREEN_PROC m_led_set_redgreen;
+ // lss driver
+ BAUDRATE_VALID_PROC m_baudrate_valid;
+ BAUDRATE_SET_PROC m_baudrate_set;
+
+ // driver module habndle
+ HMODULE m_driver_handle;
+ };
+
+driver_procs::driver_procs() : m_canReceive(0),
+ m_canSend(0),
+ m_canOpen(0),
+ m_canClose(0),
+ m_nvram_open(0),
+ m_nvram_close(0),
+ m_nvram_write(0),
+ m_nvram_read(0),
+ m_led_set_redgreen(),
+ m_baudrate_valid(0),
+ m_baudrate_set(0),
+ m_driver_handle(0)
+ {}
+
+driver_procs::~driver_procs()
+ {
+ if (m_driver_handle)
+ ::FreeLibrary(m_driver_handle);
+ }
+
+bool driver_procs::can_driver_valid() const
+ {
+ return ((m_canReceive != NULL) &&
+ (m_canSend != NULL) &&
+ (m_canOpen != NULL) &&
+ (m_canClose != NULL));
+ }
+
+// GetProcAddress doesn't have an UNICODE version for NT
+#ifdef UNDER_CE
+ #define myTEXT(str) TEXT(str)
+#else
+ #define myTEXT(str) str
+#endif
+
+HMODULE driver_procs::load_canfestival_driver(LPCTSTR driver_name)
+ {
+ if (can_driver_valid())
+ return m_driver_handle;
+ m_driver_handle = ::LoadLibrary(driver_name);
+ if (m_driver_handle == NULL)
+ return NULL;
+
+ m_canReceive = (CANRECEIVE_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canReceive_driver"));
+ m_canSend = (CANSEND_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canSend_driver"));
+ m_canOpen = (CANOPEN_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canOpen_driver"));
+ m_canClose = (CANCLOSE_DRIVER_PROC)::GetProcAddress(m_driver_handle, myTEXT("canClose_driver"));
+
+ m_nvram_open = (NVRAM_OPEN_PROC)::GetProcAddress(m_driver_handle, myTEXT("nvram_open_driver"));
+ m_nvram_close = (NVRAM_CLOSE_PROC)::GetProcAddress(m_driver_handle, myTEXT("nvram_close_driver"));
+ m_nvram_write = (NVRAM_WRITE_PROC)::GetProcAddress(m_driver_handle, myTEXT("nvram_write_driver"));
+ m_nvram_read = (NVRAM_READ_PROC)::GetProcAddress(m_driver_handle, myTEXT("nvram_read_driver"));
+
+ m_led_set_redgreen = (LED_SET_REDGREEN_PROC)::GetProcAddress(m_driver_handle, myTEXT("led_set_redgreen_driver"));
+
+ m_baudrate_valid = (BAUDRATE_VALID_PROC)::GetProcAddress(m_driver_handle, myTEXT("baudrate_valid_driver"));
+ m_baudrate_set = (BAUDRATE_SET_PROC)::GetProcAddress(m_driver_handle, myTEXT("baudrate_set_driver"));
+
+ return can_driver_valid()?m_driver_handle:NULL;
+ }
+
+struct driver_data
+ {
+ CO_Data * d;
+ HANDLE receive_thread;
+ void* inst;
+ volatile bool continue_receive_thread;
+ };
+
+driver_procs s_driver_procs;
+
+LIB_HANDLE LoadCanDriver(char* driver_name)
+ {
+ return s_driver_procs.load_canfestival_driver((LPCTSTR)driver_name);
+ }
+
+UNS8 canReceive(CAN_PORT fd0, Message *m)
+ {
+ if (fd0 != NULL && s_driver_procs.m_canReceive != NULL)
+ {
+ driver_data* data = (driver_data*)fd0;
+ return (*s_driver_procs.m_canReceive)(data->inst, m);
+ }
+ return 1;
+ }
+
+void* canReceiveLoop(CAN_PORT fd0)
+ {
+ driver_data* data = (driver_data*)fd0;
+ Message m;
+ while (data->continue_receive_thread)
+ {
+ if (!canReceive(fd0, &m))
+ {
+ EnterMutex();
+ canDispatch(data->d, &m);
+ LeaveMutex();
+ }
+ else
+ {
+ break;
+ ::Sleep(1);
+ }
+ }
+ return 0;
+ }
+
+/***************************************************************************/
+UNS8 canSend(CAN_PORT fd0, Message *m)
+ {
+ if (fd0 != NULL && s_driver_procs.m_canSend != NULL)
+ {
+ driver_data* data = (driver_data*)fd0;
+ if ((*s_driver_procs.m_canSend)(data->inst, m))
+ return 0;
+ }
+ return 1;
+ }
+
+/***************************************************************************/
+CAN_HANDLE canOpen(s_BOARD *board, CO_Data * d)
+ {
+ if (board != NULL && s_driver_procs.m_canOpen != NULL)
+ {
+ void* inst = (*s_driver_procs.m_canOpen)(board);
+ if (inst != NULL)
+ {
+ driver_data* data = new driver_data;
+ data->d = d;
+ data->inst = inst;
+ data->continue_receive_thread = true;
+ CreateReceiveTask(data, &data->receive_thread, &canReceiveLoop);
+ return data;
+ }
+ }
+ return NULL;
+ }
+
+/***************************************************************************/
+int canClose(CAN_PORT fd0)
+ {
+ if (fd0 != NULL && s_driver_procs.m_canClose != NULL)
+ {
+ driver_data* data = (driver_data*)fd0;
+ data->continue_receive_thread = false;
+ WaitReceiveTaskEnd(&data->receive_thread);
+ (*s_driver_procs.m_canClose)(data->inst);
+ delete data;
+ return 0;
+ }
+ return 0;
+ }
+
+/***************************************************************************/
+int nvram_open(void)
+ {
+ if (s_driver_procs.m_nvram_read != NULL)
+ return (*s_driver_procs.m_nvram_open)();
+ return -1;
+ }
+
+void nvram_close(void)
+ {
+ if (s_driver_procs.m_nvram_close != NULL)
+ (*s_driver_procs.m_nvram_close)();
+ }
+
+char nvram_write(int type, int access_attr, void *data)
+ {
+ if (s_driver_procs.m_nvram_write != NULL)
+ return (*s_driver_procs.m_nvram_write)(type, access_attr, data);
+ return 0;
+ }
+
+char nvram_read(int type, int access_attr, void *data)
+ {
+ if (s_driver_procs.m_nvram_read != NULL)
+ return (*s_driver_procs.m_nvram_read)(type, access_attr, data);
+ return 0;
+ }
+
+/***************************************************************************/
+
+void led_set_redgreen(CO_Data *d, unsigned char bits)
+ {
+ if (s_driver_procs.m_led_set_redgreen != NULL)
+ (*s_driver_procs.m_led_set_redgreen)(d, bits);
+ }
+
+/***************************************************************************/
+
+UNS8 baudrate_valid(UNS32 table_index)
+ {
+ if (s_driver_procs.m_baudrate_valid != NULL)
+ return (*s_driver_procs.m_baudrate_valid)(table_index);
+ return 0;
+ }
+
+void baudrate_set(UNS8 table_index)
+ {
+ if (s_driver_procs.m_baudrate_set != NULL)
+ (*s_driver_procs.m_baudrate_set)(table_index);
+ }
diff -r 3ebf16150b2e -r e747d2e26af0 drivers/win32/timers_win32.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/drivers/win32/timers_win32.cpp Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,241 @@
+/*
+This file is part of CanFestival, a library implementing CanOpen Stack.
+
+Copyright (C): Edouard TISSERANT and Francis DUPIN
+Copyright (C) Win32 Port Leonid Tochinski
+
+See COPYING file for copyrights details.
+
+This 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; either
+version 2.1 of the License, or (at your option) any later version.
+
+This 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 this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+
+
+#include
+#include
+
+extern "C"
+{
+#include "applicfg.h"
+#include "can_driver.h"
+#include "timer.h"
+#include "timers_driver.h"
+};
+
+// --------------- Synchronization Object Implementation ---------------
+class ccritical_section
+ {
+ public:
+ ccritical_section()
+ {
+ ::InitializeCriticalSection(&m_cs);
+ }
+ ~ccritical_section()
+ {
+ ::DeleteCriticalSection(&m_cs);
+ }
+ void enter()
+ {
+ ::EnterCriticalSection(&m_cs);
+ }
+ void leave()
+ {
+ ::LeaveCriticalSection(&m_cs);
+ }
+ private:
+ CRITICAL_SECTION m_cs;
+ };
+
+static ccritical_section g_cs;
+
+
+void EnterMutex(void)
+ {
+ g_cs.enter();
+ }
+
+void LeaveMutex(void)
+ {
+ g_cs.leave();
+ }
+// --------------- Synchronization Object Implementation ---------------
+
+
+// --------------- CAN Receive Thread Implementation ---------------
+
+void CreateReceiveTask(CAN_HANDLE fd0, TASK_HANDLE* Thread, void* ReceiveLoopPtr)
+ {
+ unsigned long thread_id = 0;
+ *Thread = ::CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ReceiveLoopPtr, fd0, 0, &thread_id);
+ }
+
+void WaitReceiveTaskEnd(TASK_HANDLE Thread)
+ {
+ ::WaitForSingleObject(Thread, INFINITE);
+ ::CloseHandle(Thread);
+ //*Thread = NULL;
+ }
+// --------------- CAN Receive Thread Implementation ---------------
+
+
+// --------------- Timer Thread Implementation ---------------
+class class_timers
+ {
+ public:
+ class_timers();
+ ~class_timers();
+ void start_timer_thread();
+ void resume_timer_thread();
+ void stop_timer_thread();
+ void set_timer(TIMEVAL value);
+ TIMEVAL get_elapsed_time();
+ private:
+ TIMEVAL get_timer() const;
+ static DWORD WINAPI timer_loop_thread_proc(void* arg);
+ private:
+ TIMEVAL m_last_occured_alarm_time;
+ volatile TIMEVAL m_last_alarm_set_time;
+ HANDLE m_timer_thread;
+ volatile bool m_continue_timer_loop;
+ bool m_use_hi_res_timer;
+ double m_counts_per_usec;
+ };
+
+class_timers::class_timers() : m_last_occured_alarm_time(TIMEVAL_MAX),
+ m_last_alarm_set_time(TIMEVAL_MAX),
+ m_timer_thread(0),
+ m_continue_timer_loop(false),
+ m_use_hi_res_timer(false),
+ m_counts_per_usec(0.)
+ {
+ // initialize hi resolution timer
+ LARGE_INTEGER counts_per_sec = {0, 0};
+ if (::QueryPerformanceFrequency(&counts_per_sec) && counts_per_sec.QuadPart > 0)
+ {
+ m_use_hi_res_timer = true;
+ m_counts_per_usec = counts_per_sec.QuadPart / 1000000.;
+ }
+ m_use_hi_res_timer = true;
+ }
+
+class_timers::~class_timers()
+ {
+ stop_timer_thread();
+ }
+
+// time is in micro seconds
+TIMEVAL class_timers::get_timer() const
+ {
+ if (m_use_hi_res_timer)
+ {
+ LARGE_INTEGER performance_count = {0, 0};
+ ::QueryPerformanceCounter(&performance_count);
+ return (TIMEVAL)(performance_count.QuadPart / m_counts_per_usec);
+ }
+ // hi-res timer is unavailable
+ return 1000 * ::GetTickCount();
+ }
+
+DWORD WINAPI class_timers::timer_loop_thread_proc(void* arg)
+ {
+ class_timers* This = reinterpret_cast(arg);
+ while (This->m_continue_timer_loop)
+ {
+ TIMEVAL cur_time = This->get_timer();
+ if (cur_time >= This->m_last_alarm_set_time)
+ {
+ This->m_last_occured_alarm_time = cur_time;
+ This->m_last_alarm_set_time = TIMEVAL_MAX;
+ EnterMutex();
+ TimeDispatch();
+ LeaveMutex();
+ }
+ else
+ {
+ ::Sleep(1);
+ }
+ }
+ return 0;
+ }
+
+void class_timers::start_timer_thread()
+ {
+ if (m_timer_thread == 0)
+ {
+ unsigned long thread_id = 0;
+ m_timer_thread = ::CreateThread(NULL, 0, &timer_loop_thread_proc, this, CREATE_SUSPENDED, &thread_id);
+ m_last_alarm_set_time = TIMEVAL_MAX;
+ m_last_occured_alarm_time = get_timer();
+ }
+ }
+
+void class_timers::resume_timer_thread()
+ {
+ if (m_timer_thread)
+ {
+ m_continue_timer_loop = true;
+ ::ResumeThread(m_timer_thread);
+ }
+ }
+
+void class_timers::stop_timer_thread()
+ {
+ if (m_timer_thread)
+ {
+ m_continue_timer_loop = false;
+ ::WaitForSingleObject(m_timer_thread, INFINITE);
+ ::CloseHandle(m_timer_thread);
+ m_timer_thread = 0;
+ }
+ }
+
+void class_timers::set_timer(TIMEVAL value)
+ {
+ m_last_alarm_set_time = (value == TIMEVAL_MAX) ? TIMEVAL_MAX : get_timer() + value;
+ }
+
+// elapsed time since last occured alarm
+TIMEVAL class_timers::get_elapsed_time()
+ {
+ return get_timer() - m_last_occured_alarm_time;
+ }
+
+// ----------------------------------------------------------
+
+static class_timers s_timers;
+
+void StartTimerLoop(TimerCallback_t init_callback)
+ {
+ s_timers.start_timer_thread();
+ // At first, TimeDispatch will call init_callback.
+ if (init_callback != NULL)
+ SetAlarm(NULL, 0, init_callback, (TIMEVAL)0, (TIMEVAL)0);
+ s_timers.resume_timer_thread();
+ }
+
+void StopTimerLoop(void)
+ {
+ s_timers.stop_timer_thread();
+ }
+
+void setTimer(TIMEVAL value)
+ {
+ s_timers.set_timer(value);
+ }
+
+TIMEVAL getElapsedTime(void)
+ {
+ return s_timers.get_elapsed_time();
+ }
diff -r 3ebf16150b2e -r e747d2e26af0 examples/TestMasterSlave/.cvsignore
--- a/examples/TestMasterSlave/.cvsignore Tue Apr 03 20:20:27 2007 +0200
+++ b/examples/TestMasterSlave/.cvsignore Wed Apr 04 13:04:31 2007 +0200
@@ -2,3 +2,5 @@
TestMasterSlave
result.txt
TestMasterSlave.exe
+TestMasterSalve.vcproj.KONG.edouard.user
+Release
diff -r 3ebf16150b2e -r e747d2e26af0 examples/TestMasterSlave/TestMaster.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/TestMasterSlave/TestMaster.c Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,339 @@
+
+/* File generated by gen_cfile.py. Should not be modified. */
+
+#include "TestMaster.h"
+
+/**************************************************************************/
+/* Declaration of the mapped variables */
+/**************************************************************************/
+UNS8 MasterMap1 = 0x0; /* Mapped at index 0x2000, subindex 0x00 */
+UNS8 MasterMap2 = 0x0; /* Mapped at index 0x2001, subindex 0x00 */
+UNS8 MasterMap3 = 0x0; /* Mapped at index 0x2002, subindex 0x00 */
+UNS8 MasterMap4 = 0x0; /* Mapped at index 0x2003, subindex 0x00 */
+
+/**************************************************************************/
+/* Declaration of the value range types */
+/**************************************************************************/
+
+UNS32 TestMaster_valueRangeTest (UNS8 typeValue, void * value)
+{
+ switch (typeValue) {
+ }
+ return 0;
+}
+
+/**************************************************************************/
+/* The node id */
+/**************************************************************************/
+/* node_id default value.*/
+UNS8 TestMaster_bDeviceNodeId = 0x00;
+
+/**************************************************************************/
+/* Array of message processing information */
+
+const UNS8 TestMaster_iam_a_slave = 0;
+
+TIMER_HANDLE TestMaster_heartBeatTimers[1] = {TIMER_NONE,};
+
+/*
+$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
+
+ OBJECT DICTIONARY
+
+$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
+*/
+
+/* index 0x1000 : Device Type. */
+ UNS32 TestMaster_obj1000 = 0x12D; /* 301 */
+ subindex TestMaster_Index1000[] =
+ {
+ { RO, uint32, sizeof (UNS32), (void*)&TestMaster_obj1000 }
+ };
+
+/* index 0x1001 : Error Register. */
+ UNS8 TestMaster_obj1001 = 0x0; /* 0 */
+ subindex TestMaster_Index1001[] =
+ {
+ { RO, uint8, sizeof (UNS8), (void*)&TestMaster_obj1001 }
+ };
+
+/* index 0x1005 : SYNC COB ID. */
+ UNS32 TestMaster_obj1005 = 0x40000080; /* 1073741952 */
+ ODCallback_t TestMaster_Index1005_callbacks[] =
+ {
+ NULL,
+ };
+ subindex TestMaster_Index1005[] =
+ {
+ { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1005 }
+ };
+
+/* index 0x1006 : Communication / Cycle Period. */
+ UNS32 TestMaster_obj1006 = 0xC350; /* 50000 */
+ ODCallback_t TestMaster_Index1006_callbacks[] =
+ {
+ NULL,
+ };
+ subindex TestMaster_Index1006[] =
+ {
+ { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1006 }
+ };
+
+/* index 0x1010 : Store parameters. */
+ UNS8 TestMaster_highestSubIndex_obj1010 = 4; /* number of subindex - 1*/
+ UNS32 TestMaster_obj1010_Save_All_Parameters = 0x0; /* 0 */
+ UNS32 TestMaster_obj1010_Save_Communication_Parameters = 0x0; /* 0 */
+ UNS32 TestMaster_obj1010_Save_Application_Parameters = 0x0; /* 0 */
+ UNS32 TestMaster_obj1010_Save_Manufacturer_Parameters = 0x0; /* 0 */
+ ODCallback_t TestMaster_Index1010_callbacks[] =
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ };
+ subindex TestMaster_Index1010[] =
+ {
+ { RO, uint8, sizeof (UNS8), (void*)&TestMaster_highestSubIndex_obj1010 },
+ { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1010_Save_All_Parameters },
+ { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1010_Save_Communication_Parameters },
+ { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1010_Save_Application_Parameters },
+ { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1010_Save_Manufacturer_Parameters }
+ };
+
+/* index 0x1011 : Restore Default Parameters. */
+ UNS8 TestMaster_highestSubIndex_obj1011 = 4; /* number of subindex - 1*/
+ UNS32 TestMaster_obj1011_Restore_All_Default_Parameters = 0x0; /* 0 */
+ UNS32 TestMaster_obj1011_Restore_Communication_Default_Parameters = 0x0; /* 0 */
+ UNS32 TestMaster_obj1011_Restore_Application_Default_Parameters = 0x0; /* 0 */
+ UNS32 TestMaster_obj1011_Restore_Manufacturer_Default_Parameters = 0x0; /* 0 */
+ ODCallback_t TestMaster_Index1011_callbacks[] =
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ };
+ subindex TestMaster_Index1011[] =
+ {
+ { RO, uint8, sizeof (UNS8), (void*)&TestMaster_highestSubIndex_obj1011 },
+ { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1011_Restore_All_Default_Parameters },
+ { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1011_Restore_Communication_Default_Parameters },
+ { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1011_Restore_Application_Default_Parameters },
+ { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1011_Restore_Manufacturer_Default_Parameters }
+ };
+
+/* index 0x1016 : Consumer Heartbeat Time. */
+ UNS8 TestMaster_highestSubIndex_obj1016 = 1; /* number of subindex - 1*/
+ UNS32 TestMaster_obj1016[] =
+ {
+ 0x20802 /* 133122 */
+ };
+ subindex TestMaster_Index1016[] =
+ {
+ { RO, uint8, sizeof (UNS8), (void*)&TestMaster_highestSubIndex_obj1016 },
+ { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1016[0] }
+ };
+
+/* index 0x1017 : Producer Heartbeat Time */
+ UNS16 TestMaster_obj1017 = 0x0; /* 0 */
+
+/* index 0x1018 : Identity. */
+ UNS8 TestMaster_highestSubIndex_obj1018 = 4; /* number of subindex - 1*/
+ UNS32 TestMaster_obj1018_Vendor_ID = 0x0; /* 0 */
+ UNS32 TestMaster_obj1018_Product_Code = 0x0; /* 0 */
+ UNS32 TestMaster_obj1018_Revision_Number = 0x0; /* 0 */
+ UNS32 TestMaster_obj1018_Serial_Number = 0x0; /* 0 */
+ subindex TestMaster_Index1018[] =
+ {
+ { RO, uint8, sizeof (UNS8), (void*)&TestMaster_highestSubIndex_obj1018 },
+ { RO, uint32, sizeof (UNS32), (void*)&TestMaster_obj1018_Vendor_ID },
+ { RO, uint32, sizeof (UNS32), (void*)&TestMaster_obj1018_Product_Code },
+ { RO, uint32, sizeof (UNS32), (void*)&TestMaster_obj1018_Revision_Number },
+ { RO, uint32, sizeof (UNS32), (void*)&TestMaster_obj1018_Serial_Number }
+ };
+
+/* index 0x1280 : Client SDO 1 Parameter. */
+ UNS8 TestMaster_highestSubIndex_obj1280 = 3; /* number of subindex - 1*/
+ UNS32 TestMaster_obj1280_COB_ID_Client_to_Server_Transmit_SDO = 0x602; /* 1538 */
+ UNS32 TestMaster_obj1280_COB_ID_Server_to_Client_Receive_SDO = 0x582; /* 1410 */
+ UNS32 TestMaster_obj1280_Node_ID_of_the_SDO_Server = 0x2; /* 2 */
+ subindex TestMaster_Index1280[] =
+ {
+ { RO, uint8, sizeof (UNS8), (void*)&TestMaster_highestSubIndex_obj1280 },
+ { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1280_COB_ID_Client_to_Server_Transmit_SDO },
+ { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1280_COB_ID_Server_to_Client_Receive_SDO },
+ { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1280_Node_ID_of_the_SDO_Server }
+ };
+
+/* index 0x1400 : Receive PDO 1 Parameter. */
+ UNS8 TestMaster_highestSubIndex_obj1400 = 5; /* number of subindex - 1*/
+ UNS32 TestMaster_obj1400_COB_ID_used_by_PDO = 0x182; /* 386 */
+ UNS8 TestMaster_obj1400_Transmission_Type = 0x1; /* 1 */
+ UNS16 TestMaster_obj1400_Inhibit_Time = 0x0; /* 0 */
+ UNS16 TestMaster_obj1400_Compatibility_Entry = 0x0; /* 0 */
+ UNS16 TestMaster_obj1400_Event_Timer = 0x0; /* 0 */
+ subindex TestMaster_Index1400[] =
+ {
+ { RO, uint8, sizeof (UNS8), (void*)&TestMaster_highestSubIndex_obj1400 },
+ { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1400_COB_ID_used_by_PDO },
+ { RW, uint8, sizeof (UNS8), (void*)&TestMaster_obj1400_Transmission_Type },
+ { RW, uint16, sizeof (UNS16), (void*)&TestMaster_obj1400_Inhibit_Time },
+ { RW, uint16, sizeof (UNS16), (void*)&TestMaster_obj1400_Compatibility_Entry },
+ { RW, uint16, sizeof (UNS16), (void*)&TestMaster_obj1400_Event_Timer }
+ };
+
+/* index 0x1401 : Receive PDO 2 Parameter. */
+ UNS8 TestMaster_highestSubIndex_obj1401 = 5; /* number of subindex - 1*/
+ UNS32 TestMaster_obj1401_COB_ID_used_by_PDO = 0x282; /* 642 */
+ UNS8 TestMaster_obj1401_Transmission_Type = 0x1; /* 1 */
+ UNS16 TestMaster_obj1401_Inhibit_Time = 0x0; /* 0 */
+ UNS16 TestMaster_obj1401_Compatibility_Entry = 0x0; /* 0 */
+ UNS16 TestMaster_obj1401_Event_Timer = 0x0; /* 0 */
+ subindex TestMaster_Index1401[] =
+ {
+ { RO, uint8, sizeof (UNS8), (void*)&TestMaster_highestSubIndex_obj1401 },
+ { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1401_COB_ID_used_by_PDO },
+ { RW, uint8, sizeof (UNS8), (void*)&TestMaster_obj1401_Transmission_Type },
+ { RW, uint16, sizeof (UNS16), (void*)&TestMaster_obj1401_Inhibit_Time },
+ { RW, uint16, sizeof (UNS16), (void*)&TestMaster_obj1401_Compatibility_Entry },
+ { RW, uint16, sizeof (UNS16), (void*)&TestMaster_obj1401_Event_Timer }
+ };
+
+/* index 0x1600 : Receive PDO 1 Mapping. */
+ UNS8 TestMaster_highestSubIndex_obj1600 = 2; /* number of subindex - 1*/
+ UNS32 TestMaster_obj1600[] =
+ {
+ 0x20000008, /* 536870920 */
+ 0x20010008 /* 536936456 */
+ };
+ subindex TestMaster_Index1600[] =
+ {
+ { RW, uint8, sizeof (UNS8), (void*)&TestMaster_highestSubIndex_obj1600 },
+ { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1600[0] },
+ { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1600[1] }
+ };
+
+/* index 0x1601 : Receive PDO 2 Mapping. */
+ UNS8 TestMaster_highestSubIndex_obj1601 = 2; /* number of subindex - 1*/
+ UNS32 TestMaster_obj1601[] =
+ {
+ 0x20020008, /* 537001992 */
+ 0x20030008 /* 537067528 */
+ };
+ subindex TestMaster_Index1601[] =
+ {
+ { RW, uint8, sizeof (UNS8), (void*)&TestMaster_highestSubIndex_obj1601 },
+ { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1601[0] },
+ { RW, uint32, sizeof (UNS32), (void*)&TestMaster_obj1601[1] }
+ };
+
+/* index 0x2000 : Mapped variable MasterMap1 */
+ ODCallback_t MasterMap1_callbacks[] =
+ {
+ NULL,
+ };
+ subindex TestMaster_Index2000[] =
+ {
+ { RW, uint8, sizeof (UNS8), (void*)&MasterMap1 }
+ };
+
+/* index 0x2001 : Mapped variable MasterMap2 */
+ subindex TestMaster_Index2001[] =
+ {
+ { RW, uint8, sizeof (UNS8), (void*)&MasterMap2 }
+ };
+
+/* index 0x2002 : Mapped variable MasterMap3 */
+ subindex TestMaster_Index2002[] =
+ {
+ { RW, uint8, sizeof (UNS8), (void*)&MasterMap3 }
+ };
+
+/* index 0x2003 : Mapped variable MasterMap4 */
+ subindex TestMaster_Index2003[] =
+ {
+ { RW, uint8, sizeof (UNS8), (void*)&MasterMap4 }
+ };
+
+const indextable TestMaster_objdict[] =
+{
+ { (subindex*)TestMaster_Index1000,sizeof(TestMaster_Index1000)/sizeof(TestMaster_Index1000[0]), 0x1000},
+ { (subindex*)TestMaster_Index1001,sizeof(TestMaster_Index1001)/sizeof(TestMaster_Index1001[0]), 0x1001},
+ { (subindex*)TestMaster_Index1005,sizeof(TestMaster_Index1005)/sizeof(TestMaster_Index1005[0]), 0x1005},
+ { (subindex*)TestMaster_Index1006,sizeof(TestMaster_Index1006)/sizeof(TestMaster_Index1006[0]), 0x1006},
+ { (subindex*)TestMaster_Index1010,sizeof(TestMaster_Index1010)/sizeof(TestMaster_Index1010[0]), 0x1010},
+ { (subindex*)TestMaster_Index1011,sizeof(TestMaster_Index1011)/sizeof(TestMaster_Index1011[0]), 0x1011},
+ { (subindex*)TestMaster_Index1016,sizeof(TestMaster_Index1016)/sizeof(TestMaster_Index1016[0]), 0x1016},
+ { (subindex*)TestMaster_Index1018,sizeof(TestMaster_Index1018)/sizeof(TestMaster_Index1018[0]), 0x1018},
+ { (subindex*)TestMaster_Index1280,sizeof(TestMaster_Index1280)/sizeof(TestMaster_Index1280[0]), 0x1280},
+ { (subindex*)TestMaster_Index1400,sizeof(TestMaster_Index1400)/sizeof(TestMaster_Index1400[0]), 0x1400},
+ { (subindex*)TestMaster_Index1401,sizeof(TestMaster_Index1401)/sizeof(TestMaster_Index1401[0]), 0x1401},
+ { (subindex*)TestMaster_Index1600,sizeof(TestMaster_Index1600)/sizeof(TestMaster_Index1600[0]), 0x1600},
+ { (subindex*)TestMaster_Index1601,sizeof(TestMaster_Index1601)/sizeof(TestMaster_Index1601[0]), 0x1601},
+ { (subindex*)TestMaster_Index2000,sizeof(TestMaster_Index2000)/sizeof(TestMaster_Index2000[0]), 0x2000},
+ { (subindex*)TestMaster_Index2001,sizeof(TestMaster_Index2001)/sizeof(TestMaster_Index2001[0]), 0x2001},
+ { (subindex*)TestMaster_Index2002,sizeof(TestMaster_Index2002)/sizeof(TestMaster_Index2002[0]), 0x2002},
+ { (subindex*)TestMaster_Index2003,sizeof(TestMaster_Index2003)/sizeof(TestMaster_Index2003[0]), 0x2003},
+};
+
+const indextable * TestMaster_scanIndexOD (UNS16 wIndex, UNS32 * errorCode, ODCallback_t **callbacks)
+{
+ int i;
+ *callbacks = NULL;
+ switch(wIndex){
+ case 0x1000: i = 0;break;
+ case 0x1001: i = 1;break;
+ case 0x1005: i = 2;*callbacks = TestMaster_Index1005_callbacks; break;
+ case 0x1006: i = 3;*callbacks = TestMaster_Index1006_callbacks; break;
+ case 0x1010: i = 4;*callbacks = TestMaster_Index1010_callbacks; break;
+ case 0x1011: i = 5;*callbacks = TestMaster_Index1011_callbacks; break;
+ case 0x1016: i = 6;break;
+ case 0x1018: i = 7;break;
+ case 0x1280: i = 8;break;
+ case 0x1400: i = 9;break;
+ case 0x1401: i = 10;break;
+ case 0x1600: i = 11;break;
+ case 0x1601: i = 12;break;
+ case 0x2000: i = 13;*callbacks = MasterMap1_callbacks; break;
+ case 0x2001: i = 14;break;
+ case 0x2002: i = 15;break;
+ case 0x2003: i = 16;break;
+ default:
+ *errorCode = OD_NO_SUCH_OBJECT;
+ return NULL;
+ }
+ *errorCode = OD_SUCCESSFUL;
+ return &TestMaster_objdict[i];
+}
+
+/* To count at which received SYNC a PDO must be sent.
+ * Even if no pdoTransmit are defined, at least one entry is computed
+ * for compilations issues.
+ */
+UNS8 TestMaster_count_sync[1] = {0,};
+
+quick_index TestMaster_firstIndex = {
+ 0, /* SDO_SVR */
+ 8, /* SDO_CLT */
+ 9, /* PDO_RCV */
+ 11, /* PDO_RCV_MAP */
+ 0, /* PDO_TRS */
+ 0 /* PDO_TRS_MAP */
+};
+
+quick_index TestMaster_lastIndex = {
+ 0, /* SDO_SVR */
+ 8, /* SDO_CLT */
+ 10, /* PDO_RCV */
+ 12, /* PDO_RCV_MAP */
+ 0, /* PDO_TRS */
+ 0 /* PDO_TRS_MAP */
+};
+
+UNS16 TestMaster_ObjdictSize = sizeof(TestMaster_objdict)/sizeof(TestMaster_objdict[0]);
+
+CO_Data TestMaster_Data = CANOPEN_NODE_DATA_INITIALIZER(TestMaster);
+
diff -r 3ebf16150b2e -r e747d2e26af0 examples/TestMasterSlave/TestMasterSalve.vcproj
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/TestMasterSlave/TestMasterSalve.vcproj Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,252 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 3ebf16150b2e -r e747d2e26af0 examples/TestMasterSlave/TestMasterSlave.c
--- a/examples/TestMasterSlave/TestMasterSlave.c Tue Apr 03 20:20:27 2007 +0200
+++ b/examples/TestMasterSlave/TestMasterSlave.c Wed Apr 04 13:04:31 2007 +0200
@@ -20,12 +20,21 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
+#if defined(WIN32) && !defined(__CYGWIN__)
+#include
+#include "getopt.h"
+void pause(void)
+{
+ system("PAUSE");
+}
+#else
#include
#include
-#include
-#include
+//#include
+//#include
#include
#include
+#endif
#include
#include
@@ -69,54 +78,20 @@
return 0;
}
-CAN_HANDLE SlaveCanHandle;
-CAN_HANDLE MasterCanHandle;
-
-// Baudrate values for Peak board :
-// CAN_BAUD_1M CAN_BAUD_500K CAN_BAUD_250K CAN_BAUD_125K CAN_BAUD_100K CAN_BAUD_50K
-// CAN_BAUD_20K CAN_BAUD_10K CAN_BAUD_5K
-
-#ifdef CAN_BAUD_500K
-int TranslateBaudeRate(char* optarg){
- if(!strcmp( optarg, "1M")) return CAN_BAUD_1M;
- if(!strcmp( optarg, "500K")) return CAN_BAUD_500K;
- if(!strcmp( optarg, "250K")) return CAN_BAUD_250K;
- if(!strcmp( optarg, "125K")) return CAN_BAUD_125K;
- if(!strcmp( optarg, "100K")) return CAN_BAUD_100K;
- if(!strcmp( optarg, "50K")) return CAN_BAUD_50K;
- if(!strcmp( optarg, "20K")) return CAN_BAUD_20K;
- if(!strcmp( optarg, "10K")) return CAN_BAUD_10K;
- if(!strcmp( optarg, "5K")) return CAN_BAUD_5K;
- if(!strcmp( optarg, "none")) return 0;
- return 0x0000;
-}
-s_BOARD SlaveBoard = {"0", CAN_BAUD_500K, &TestSlave_Data};
-s_BOARD MasterBoard = {"1", CAN_BAUD_500K, &TestMaster_Data};
-#else
-int TranslateBaudeRate(char* optarg){
- if(!strcmp( optarg, "1M")) return 1000;
- if(!strcmp( optarg, "500K")) return 500;
- if(!strcmp( optarg, "250K")) return 250;
- if(!strcmp( optarg, "125K")) return 125;
- if(!strcmp( optarg, "100K")) return 100;
- if(!strcmp( optarg, "50K")) return 50;
- if(!strcmp( optarg, "20K")) return 20;
- if(!strcmp( optarg, "10K")) return 10;
- if(!strcmp( optarg, "5K")) return 5;
- if(!strcmp( optarg, "none")) return 0;
- return 0;
-}
-s_BOARD SlaveBoard = {"0", 500, &TestSlave_Data};
-s_BOARD MasterBoard = {"1", 500, &TestMaster_Data};
-#endif
-
-
+CAN_PORT SlaveCanHandle;
+CAN_PORT MasterCanHandle;
+
+s_BOARD SlaveBoard = {"0", "500K"};
+s_BOARD MasterBoard = {"1", "500K"};
+
+#if !defined(WIN32) || defined(__CYGWIN__)
void catch_signal(int sig)
{
signal(SIGTERM, catch_signal);
signal(SIGINT, catch_signal);
eprintf("Got Signal %d\n",sig);
}
+#endif
void help()
{
@@ -132,6 +107,8 @@
printf("* ./TestMasterSlave [OPTIONS] *\n");
printf("* *\n");
printf("* OPTIONS: *\n");
+ printf("* -l : Can library [\"libcanfestival_can_virtual.so\"] *\n");
+ printf("* *\n");
printf("* Slave: *\n");
printf("* -s : bus name [\"0\"] *\n");
printf("* -S : 1M,500K,250K,125K,100K,50K,20K,10K,none(disable) *\n");
@@ -181,8 +158,9 @@
char c;
extern char *optarg;
-
- while ((c = getopt(argc, argv, "-m:s:M:S:")) != EOF)
+ char* LibraryPath="libcanfestival_can_virtual.so";
+
+ while ((c = getopt(argc, argv, "-m:s:M:S:l:")) != EOF)
{
switch(c)
{
@@ -208,7 +186,7 @@
help();
exit(1);
}
- SlaveBoard.baudrate = TranslateBaudeRate(optarg);
+ SlaveBoard.baudrate = optarg;
break;
case 'M' :
if (optarg[0] == 0)
@@ -216,7 +194,15 @@
help();
exit(1);
}
- MasterBoard.baudrate = TranslateBaudeRate(optarg);
+ MasterBoard.baudrate = optarg;
+ break;
+ case 'l' :
+ if (optarg[0] == 0)
+ {
+ help();
+ exit(1);
+ }
+ LibraryPath = optarg;
break;
default:
help();
@@ -224,16 +210,31 @@
}
}
- /* install signal handler for manual break */
+#if !defined(WIN32) || defined(__CYGWIN__)
+ /* install signal handler for manual break */
signal(SIGTERM, catch_signal);
signal(SIGINT, catch_signal);
-
+#endif
+
+#ifndef NOT_USE_DYNAMIC_LOADING
+ LoadCanDriver(LibraryPath);
+#endif
// Open CAN devices
- if(SlaveBoard.baudrate)
- if((SlaveCanHandle = canOpen(&SlaveBoard))==NULL) goto fail_slave;
-
- if(MasterBoard.baudrate)
- if((MasterCanHandle = canOpen(&MasterBoard))==NULL) goto fail_master;
+ if(SlaveBoard.baudrate){
+ SlaveCanHandle = canOpen(&SlaveBoard,&TestSlave_Data);
+ if(SlaveCanHandle == NULL){
+ eprintf("Cannot open Slave Board (%s,%s)\n",SlaveBoard.busname, SlaveBoard.baudrate);
+ goto fail_slave;
+ }
+ }
+
+ if(MasterBoard.baudrate){
+ MasterCanHandle = canOpen(&MasterBoard,&TestMaster_Data);
+ if(MasterCanHandle == NULL){
+ eprintf("Cannot open Master Board (%s,%s)\n",SlaveBoard.busname, SlaveBoard.baudrate);
+ goto fail_master;
+ }
+ }
// Start timer thread
StartTimerLoop(&InitNodes);
diff -r 3ebf16150b2e -r e747d2e26af0 examples/TestMasterSlave/TestMasterSlave.h
--- a/examples/TestMasterSlave/TestMasterSlave.h Tue Apr 03 20:20:27 2007 +0200
+++ b/examples/TestMasterSlave/TestMasterSlave.h Wed Apr 04 13:04:31 2007 +0200
@@ -26,10 +26,12 @@
#endif
void print_message(Message *m);
-UNS8 canSend(CAN_HANDLE fd0, Message *m);
+/*UNS8 canSend(CAN_HANDLE fd0, Message *m);*/
-extern CAN_HANDLE SlaveCanHandle;
-extern CAN_HANDLE MasterCanHandle;
+#include "canfestival.h"
+
+extern CAN_PORT SlaveCanHandle;
+extern CAN_PORT MasterCanHandle;
/*
diff -r 3ebf16150b2e -r e747d2e26af0 examples/TestMasterSlave/TestSlave.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/TestMasterSlave/TestSlave.c Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,329 @@
+
+/* File generated by gen_cfile.py. Should not be modified. */
+
+#include "TestSlave.h"
+
+/**************************************************************************/
+/* Declaration of the mapped variables */
+/**************************************************************************/
+UNS8 SlaveMap1 = 0x0; /* Mapped at index 0x2000, subindex 0x00 */
+UNS8 SlaveMap2 = 0x0; /* Mapped at index 0x2001, subindex 0x00 */
+UNS8 SlaveMap3 = 0x0; /* Mapped at index 0x2002, subindex 0x00 */
+UNS8 SlaveMap4 = 0x0; /* Mapped at index 0x2003, subindex 0x00 */
+
+/**************************************************************************/
+/* Declaration of the value range types */
+/**************************************************************************/
+
+UNS32 TestSlave_valueRangeTest (UNS8 typeValue, void * value)
+{
+ switch (typeValue) {
+ }
+ return 0;
+}
+
+/**************************************************************************/
+/* The node id */
+/**************************************************************************/
+/* node_id default value.*/
+UNS8 TestSlave_bDeviceNodeId = 0x00;
+
+/**************************************************************************/
+/* Array of message processing information */
+
+const UNS8 TestSlave_iam_a_slave = 1;
+
+TIMER_HANDLE TestSlave_heartBeatTimers[1];
+
+/*
+$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
+
+ OBJECT DICTIONARY
+
+$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
+*/
+
+/* index 0x1000 : Device Type. */
+ UNS32 TestSlave_obj1000 = 0x12D; /* 301 */
+ subindex TestSlave_Index1000[] =
+ {
+ { RO, uint32, sizeof (UNS32), (void*)&TestSlave_obj1000 }
+ };
+
+/* index 0x1001 : Error Register. */
+ UNS8 TestSlave_obj1001 = 0x0; /* 0 */
+ subindex TestSlave_Index1001[] =
+ {
+ { RO, uint8, sizeof (UNS8), (void*)&TestSlave_obj1001 }
+ };
+
+/* index 0x1005 : SYNC COB ID. */
+ UNS32 TestSlave_obj1005 = 0x80; /* 128 */
+ ODCallback_t TestSlave_Index1005_callbacks[] =
+ {
+ NULL,
+ };
+ subindex TestSlave_Index1005[] =
+ {
+ { RW, uint32, sizeof (UNS32), (void*)&TestSlave_obj1005 }
+ };
+
+/* index 0x1006 : Communication / Cycle Period. */
+ UNS32 TestSlave_obj1006 = 0x0; /* 0 */
+ ODCallback_t TestSlave_Index1006_callbacks[] =
+ {
+ NULL,
+ };
+ subindex TestSlave_Index1006[] =
+ {
+ { RW, uint32, sizeof (UNS32), (void*)&TestSlave_obj1006 }
+ };
+
+/* index 0x1010 : Store parameters. */
+ UNS8 TestSlave_highestSubIndex_obj1010 = 4; /* number of subindex - 1*/
+ UNS32 TestSlave_obj1010_Save_All_Parameters = 0x0; /* 0 */
+ UNS32 TestSlave_obj1010_Save_Communication_Parameters = 0x0; /* 0 */
+ UNS32 TestSlave_obj1010_Save_Application_Parameters = 0x0; /* 0 */
+ UNS32 TestSlave_obj1010_Save_Manufacturer_Parameters = 0x0; /* 0 */
+ ODCallback_t TestSlave_Index1010_callbacks[] =
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ };
+ subindex TestSlave_Index1010[] =
+ {
+ { RO, uint8, sizeof (UNS8), (void*)&TestSlave_highestSubIndex_obj1010 },
+ { RW, uint32, sizeof (UNS32), (void*)&TestSlave_obj1010_Save_All_Parameters },
+ { RW, uint32, sizeof (UNS32), (void*)&TestSlave_obj1010_Save_Communication_Parameters },
+ { RW, uint32, sizeof (UNS32), (void*)&TestSlave_obj1010_Save_Application_Parameters },
+ { RW, uint32, sizeof (UNS32), (void*)&TestSlave_obj1010_Save_Manufacturer_Parameters }
+ };
+
+/* index 0x1011 : Restore Default Parameters. */
+ UNS8 TestSlave_highestSubIndex_obj1011 = 4; /* number of subindex - 1*/
+ UNS32 TestSlave_obj1011_Restore_All_Default_Parameters = 0x0; /* 0 */
+ UNS32 TestSlave_obj1011_Restore_Communication_Default_Parameters = 0x0; /* 0 */
+ UNS32 TestSlave_obj1011_Restore_Application_Default_Parameters = 0x0; /* 0 */
+ UNS32 TestSlave_obj1011_Restore_Manufacturer_Default_Parameters = 0x0; /* 0 */
+ ODCallback_t TestSlave_Index1011_callbacks[] =
+ {
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ };
+ subindex TestSlave_Index1011[] =
+ {
+ { RO, uint8, sizeof (UNS8), (void*)&TestSlave_highestSubIndex_obj1011 },
+ { RW, uint32, sizeof (UNS32), (void*)&TestSlave_obj1011_Restore_All_Default_Parameters },
+ { RW, uint32, sizeof (UNS32), (void*)&TestSlave_obj1011_Restore_Communication_Default_Parameters },
+ { RW, uint32, sizeof (UNS32), (void*)&TestSlave_obj1011_Restore_Application_Default_Parameters },
+ { RW, uint32, sizeof (UNS32), (void*)&TestSlave_obj1011_Restore_Manufacturer_Default_Parameters }
+ };
+
+/* index 0x1016 : Consumer Heartbeat Time */
+ UNS8 TestSlave_highestSubIndex_obj1016 = 0;
+ UNS32 TestSlave_obj1016[]={0};
+
+/* index 0x1017 : Producer Heartbeat Time. */
+ UNS16 TestSlave_obj1017 = 0x3E8; /* 1000 */
+ subindex TestSlave_Index1017[] =
+ {
+ { RW, uint16, sizeof (UNS16), (void*)&TestSlave_obj1017 }
+ };
+
+/* index 0x1018 : Identity. */
+ UNS8 TestSlave_highestSubIndex_obj1018 = 4; /* number of subindex - 1*/
+ UNS32 TestSlave_obj1018_Vendor_ID = 0x0; /* 0 */
+ UNS32 TestSlave_obj1018_Product_Code = 0x0; /* 0 */
+ UNS32 TestSlave_obj1018_Revision_Number = 0x0; /* 0 */
+ UNS32 TestSlave_obj1018_Serial_Number = 0x0; /* 0 */
+ subindex TestSlave_Index1018[] =
+ {
+ { RO, uint8, sizeof (UNS8), (void*)&TestSlave_highestSubIndex_obj1018 },
+ { RO, uint32, sizeof (UNS32), (void*)&TestSlave_obj1018_Vendor_ID },
+ { RO, uint32, sizeof (UNS32), (void*)&TestSlave_obj1018_Product_Code },
+ { RO, uint32, sizeof (UNS32), (void*)&TestSlave_obj1018_Revision_Number },
+ { RO, uint32, sizeof (UNS32), (void*)&TestSlave_obj1018_Serial_Number }
+ };
+
+/* index 0x1200 : Server SDO Parameter. */
+ UNS8 TestSlave_highestSubIndex_obj1200 = 2; /* number of subindex - 1*/
+ UNS32 TestSlave_obj1200_COB_ID_Client_to_Server_Receive_SDO = 0x601; /* 1537 */
+ UNS32 TestSlave_obj1200_COB_ID_Server_to_Client_Transmit_SDO = 0x581; /* 1409 */
+ subindex TestSlave_Index1200[] =
+ {
+ { RO, uint8, sizeof (UNS8), (void*)&TestSlave_highestSubIndex_obj1200 },
+ { RO, uint32, sizeof (UNS32), (void*)&TestSlave_obj1200_COB_ID_Client_to_Server_Receive_SDO },
+ { RO, uint32, sizeof (UNS32), (void*)&TestSlave_obj1200_COB_ID_Server_to_Client_Transmit_SDO }
+ };
+
+/* index 0x1800 : Transmit PDO 1 Parameter. */
+ UNS8 TestSlave_highestSubIndex_obj1800 = 5; /* number of subindex - 1*/
+ UNS32 TestSlave_obj1800_COB_ID_used_by_PDO = 0x182; /* 386 */
+ UNS8 TestSlave_obj1800_Transmission_Type = 0x1; /* 1 */
+ UNS16 TestSlave_obj1800_Inhibit_Time = 0x0; /* 0 */
+ UNS16 TestSlave_obj1800_Compatibility_Entry = 0x0; /* 0 */
+ UNS16 TestSlave_obj1800_Event_Timer = 0x0; /* 0 */
+ subindex TestSlave_Index1800[] =
+ {
+ { RO, uint8, sizeof (UNS8), (void*)&TestSlave_highestSubIndex_obj1800 },
+ { RW, uint32, sizeof (UNS32), (void*)&TestSlave_obj1800_COB_ID_used_by_PDO },
+ { RW, uint8, sizeof (UNS8), (void*)&TestSlave_obj1800_Transmission_Type },
+ { RW, uint16, sizeof (UNS16), (void*)&TestSlave_obj1800_Inhibit_Time },
+ { RW, uint16, sizeof (UNS16), (void*)&TestSlave_obj1800_Compatibility_Entry },
+ { RW, uint16, sizeof (UNS16), (void*)&TestSlave_obj1800_Event_Timer }
+ };
+
+/* index 0x1801 : Transmit PDO 2 Parameter. */
+ UNS8 TestSlave_highestSubIndex_obj1801 = 5; /* number of subindex - 1*/
+ UNS32 TestSlave_obj1801_COB_ID_used_by_PDO = 0x282; /* 642 */
+ UNS8 TestSlave_obj1801_Transmission_Type = 0x1; /* 1 */
+ UNS16 TestSlave_obj1801_Inhibit_Time = 0x0; /* 0 */
+ UNS16 TestSlave_obj1801_Compatibility_Entry = 0x0; /* 0 */
+ UNS16 TestSlave_obj1801_Event_Timer = 0x0; /* 0 */
+ subindex TestSlave_Index1801[] =
+ {
+ { RO, uint8, sizeof (UNS8), (void*)&TestSlave_highestSubIndex_obj1801 },
+ { RW, uint32, sizeof (UNS32), (void*)&TestSlave_obj1801_COB_ID_used_by_PDO },
+ { RW, uint8, sizeof (UNS8), (void*)&TestSlave_obj1801_Transmission_Type },
+ { RW, uint16, sizeof (UNS16), (void*)&TestSlave_obj1801_Inhibit_Time },
+ { RW, uint16, sizeof (UNS16), (void*)&TestSlave_obj1801_Compatibility_Entry },
+ { RW, uint16, sizeof (UNS16), (void*)&TestSlave_obj1801_Event_Timer }
+ };
+
+/* index 0x1A00 : Transmit PDO 1 Mapping. */
+ UNS8 TestSlave_highestSubIndex_obj1A00 = 2; /* number of subindex - 1*/
+ UNS32 TestSlave_obj1A00[] =
+ {
+ 0x20000008, /* 536870920 */
+ 0x20010008 /* 536936456 */
+ };
+ subindex TestSlave_Index1A00[] =
+ {
+ { RW, uint8, sizeof (UNS8), (void*)&TestSlave_highestSubIndex_obj1A00 },
+ { RW, uint32, sizeof (UNS32), (void*)&TestSlave_obj1A00[0] },
+ { RW, uint32, sizeof (UNS32), (void*)&TestSlave_obj1A00[1] }
+ };
+
+/* index 0x1A01 : Transmit PDO 2 Mapping. */
+ UNS8 TestSlave_highestSubIndex_obj1A01 = 2; /* number of subindex - 1*/
+ UNS32 TestSlave_obj1A01[] =
+ {
+ 0x20020008, /* 537001992 */
+ 0x20030008 /* 537067528 */
+ };
+ subindex TestSlave_Index1A01[] =
+ {
+ { RW, uint8, sizeof (UNS8), (void*)&TestSlave_highestSubIndex_obj1A01 },
+ { RW, uint32, sizeof (UNS32), (void*)&TestSlave_obj1A01[0] },
+ { RW, uint32, sizeof (UNS32), (void*)&TestSlave_obj1A01[1] }
+ };
+
+/* index 0x2000 : Mapped variable SlaveMap1 */
+ subindex TestSlave_Index2000[] =
+ {
+ { RW, uint8, sizeof (UNS8), (void*)&SlaveMap1 }
+ };
+
+/* index 0x2001 : Mapped variable SlaveMap2 */
+ subindex TestSlave_Index2001[] =
+ {
+ { RW, uint8, sizeof (UNS8), (void*)&SlaveMap2 }
+ };
+
+/* index 0x2002 : Mapped variable SlaveMap3 */
+ subindex TestSlave_Index2002[] =
+ {
+ { RW, uint8, sizeof (UNS8), (void*)&SlaveMap3 }
+ };
+
+/* index 0x2003 : Mapped variable SlaveMap4 */
+ subindex TestSlave_Index2003[] =
+ {
+ { RW, uint8, sizeof (UNS8), (void*)&SlaveMap4 }
+ };
+
+const indextable TestSlave_objdict[] =
+{
+ { (subindex*)TestSlave_Index1000,sizeof(TestSlave_Index1000)/sizeof(TestSlave_Index1000[0]), 0x1000},
+ { (subindex*)TestSlave_Index1001,sizeof(TestSlave_Index1001)/sizeof(TestSlave_Index1001[0]), 0x1001},
+ { (subindex*)TestSlave_Index1005,sizeof(TestSlave_Index1005)/sizeof(TestSlave_Index1005[0]), 0x1005},
+ { (subindex*)TestSlave_Index1006,sizeof(TestSlave_Index1006)/sizeof(TestSlave_Index1006[0]), 0x1006},
+ { (subindex*)TestSlave_Index1010,sizeof(TestSlave_Index1010)/sizeof(TestSlave_Index1010[0]), 0x1010},
+ { (subindex*)TestSlave_Index1011,sizeof(TestSlave_Index1011)/sizeof(TestSlave_Index1011[0]), 0x1011},
+ { (subindex*)TestSlave_Index1017,sizeof(TestSlave_Index1017)/sizeof(TestSlave_Index1017[0]), 0x1017},
+ { (subindex*)TestSlave_Index1018,sizeof(TestSlave_Index1018)/sizeof(TestSlave_Index1018[0]), 0x1018},
+ { (subindex*)TestSlave_Index1200,sizeof(TestSlave_Index1200)/sizeof(TestSlave_Index1200[0]), 0x1200},
+ { (subindex*)TestSlave_Index1800,sizeof(TestSlave_Index1800)/sizeof(TestSlave_Index1800[0]), 0x1800},
+ { (subindex*)TestSlave_Index1801,sizeof(TestSlave_Index1801)/sizeof(TestSlave_Index1801[0]), 0x1801},
+ { (subindex*)TestSlave_Index1A00,sizeof(TestSlave_Index1A00)/sizeof(TestSlave_Index1A00[0]), 0x1A00},
+ { (subindex*)TestSlave_Index1A01,sizeof(TestSlave_Index1A01)/sizeof(TestSlave_Index1A01[0]), 0x1A01},
+ { (subindex*)TestSlave_Index2000,sizeof(TestSlave_Index2000)/sizeof(TestSlave_Index2000[0]), 0x2000},
+ { (subindex*)TestSlave_Index2001,sizeof(TestSlave_Index2001)/sizeof(TestSlave_Index2001[0]), 0x2001},
+ { (subindex*)TestSlave_Index2002,sizeof(TestSlave_Index2002)/sizeof(TestSlave_Index2002[0]), 0x2002},
+ { (subindex*)TestSlave_Index2003,sizeof(TestSlave_Index2003)/sizeof(TestSlave_Index2003[0]), 0x2003},
+};
+
+const indextable * TestSlave_scanIndexOD (UNS16 wIndex, UNS32 * errorCode, ODCallback_t **callbacks)
+{
+ int i;
+ *callbacks = NULL;
+ switch(wIndex){
+ case 0x1000: i = 0;break;
+ case 0x1001: i = 1;break;
+ case 0x1005: i = 2;*callbacks = TestSlave_Index1005_callbacks; break;
+ case 0x1006: i = 3;*callbacks = TestSlave_Index1006_callbacks; break;
+ case 0x1010: i = 4;*callbacks = TestSlave_Index1010_callbacks; break;
+ case 0x1011: i = 5;*callbacks = TestSlave_Index1011_callbacks; break;
+ case 0x1017: i = 6;break;
+ case 0x1018: i = 7;break;
+ case 0x1200: i = 8;break;
+ case 0x1800: i = 9;break;
+ case 0x1801: i = 10;break;
+ case 0x1A00: i = 11;break;
+ case 0x1A01: i = 12;break;
+ case 0x2000: i = 13;break;
+ case 0x2001: i = 14;break;
+ case 0x2002: i = 15;break;
+ case 0x2003: i = 16;break;
+ default:
+ *errorCode = OD_NO_SUCH_OBJECT;
+ return NULL;
+ }
+ *errorCode = OD_SUCCESSFUL;
+ return &TestSlave_objdict[i];
+}
+
+/* To count at which received SYNC a PDO must be sent.
+ * Even if no pdoTransmit are defined, at least one entry is computed
+ * for compilations issues.
+ */
+UNS8 TestSlave_count_sync[2] = {0,};
+
+quick_index TestSlave_firstIndex = {
+ 8, /* SDO_SVR */
+ 0, /* SDO_CLT */
+ 0, /* PDO_RCV */
+ 0, /* PDO_RCV_MAP */
+ 9, /* PDO_TRS */
+ 11 /* PDO_TRS_MAP */
+};
+
+quick_index TestSlave_lastIndex = {
+ 8, /* SDO_SVR */
+ 0, /* SDO_CLT */
+ 0, /* PDO_RCV */
+ 0, /* PDO_RCV_MAP */
+ 10, /* PDO_TRS */
+ 12 /* PDO_TRS_MAP */
+};
+
+UNS16 TestSlave_ObjdictSize = sizeof(TestSlave_objdict)/sizeof(TestSlave_objdict[0]);
+
+CO_Data TestSlave_Data = CANOPEN_NODE_DATA_INITIALIZER(TestSlave);
+
diff -r 3ebf16150b2e -r e747d2e26af0 examples/TestMasterSlave/getopt.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/TestMasterSlave/getopt.c Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,1260 @@
+/* from http://www.pwilson.net/getopt.html */
+
+/* Getopt for GNU.
+ NOTE: getopt is now part of the C library, so if you don't know what
+ "Keep this file name-space clean" means, talk to drepper@gnu.org
+ before changing it!
+ Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001
+ Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C 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; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C 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 GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+/* This tells Alpha OSF/1 not to define a getopt prototype in .
+ Ditto for AIX 3.2 and . */
+#ifndef _NO_PROTO
+# define _NO_PROTO
+#endif
+
+#ifdef HAVE_CONFIG_H
+# include
+#endif
+
+#if !defined __STDC__ || !__STDC__
+/* This is a separate conditional since some stdc systems
+ reject `defined (const)'. */
+# ifndef const
+# define const
+# endif
+#endif
+
+#include
+
+/* Comment out all this code if we are using the GNU C Library, and are not
+ actually compiling the library itself. This code is part of the GNU C
+ Library, but also included in many other GNU distributions. Compiling
+ and linking in this code is a waste when using the GNU C library
+ (especially if it is a shared library). Rather than having every GNU
+ program understand `configure --with-gnu-libc' and omit the object files,
+ it is simpler to just do this in the source for each such file. */
+
+#define GETOPT_INTERFACE_VERSION 2
+#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+# include
+# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+# define ELIDE_CODE
+# endif
+#endif
+
+#ifndef ELIDE_CODE
+
+
+/* This needs to come after some library #include
+ to get __GNU_LIBRARY__ defined. */
+#ifdef __GNU_LIBRARY__
+/* Don't include stdlib.h for non-GNU C libraries because some of them
+ contain conflicting prototypes for getopt. */
+# include
+# include
+#endif /* GNU C library. */
+
+#ifdef VMS
+# include
+# if HAVE_STRING_H - 0
+# include
+# endif
+#endif
+
+#ifndef _
+/* This is for other GNU distributions with internationalized messages. */
+# if (HAVE_LIBINTL_H && ENABLE_NLS) || defined _LIBC
+# include
+# ifndef _
+# define _(msgid) gettext (msgid)
+# endif
+# else
+# define _(msgid) (msgid)
+# endif
+# if defined _LIBC && defined USE_IN_LIBIO
+# include
+# endif
+#endif
+
+/* This version of `getopt' appears to the caller like standard Unix `getopt'
+ but it behaves differently for the user, since it allows the user
+ to intersperse the options with the other arguments.
+
+ As `getopt' works, it permutes the elements of ARGV so that,
+ when it is done, all the options precede everything else. Thus
+ all application programs are extended to handle flexible argument order.
+
+ Setting the environment variable POSIXLY_CORRECT disables permutation.
+ Then the behavior is completely standard.
+
+ GNU application programs can use a third alternative mode in which
+ they can distinguish the relative order of options and other arguments. */
+
+#include "getopt.h"
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns -1, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+/* 1003.2 says this must be 1 before any call. */
+int optind = 1;
+
+/* Formerly, initialization of getopt depended on optind==0, which
+ causes problems with re-calling getopt as programs generally don't
+ know that. */
+
+int __getopt_initialized;
+
+/* The next char to be scanned in the option-element
+ in which the last option character we returned was found.
+ This allows us to pick up the scan where we left off.
+
+ If this is zero, or a null string, it means resume the scan
+ by advancing to the next ARGV-element. */
+
+static char *nextchar;
+
+/* Callers store zero here to inhibit the error message
+ for unrecognized options. */
+
+int opterr = 1;
+
+/* Set to an option character which was unrecognized.
+ This must be initialized on some systems to avoid linking in the
+ system's own getopt implementation. */
+
+int optopt = '?';
+
+/* Describe how to deal with options that follow non-option ARGV-elements.
+
+ If the caller did not specify anything,
+ the default is REQUIRE_ORDER if the environment variable
+ POSIXLY_CORRECT is defined, PERMUTE otherwise.
+
+ REQUIRE_ORDER means don't recognize them as options;
+ stop option processing when the first non-option is seen.
+ This is what Unix does.
+ This mode of operation is selected by either setting the environment
+ variable POSIXLY_CORRECT, or using `+' as the first character
+ of the list of option characters.
+
+ PERMUTE is the default. We permute the contents of ARGV as we scan,
+ so that eventually all the non-options are at the end. This allows options
+ to be given in any order, even with programs that were not written to
+ expect this.
+
+ RETURN_IN_ORDER is an option available to programs that were written
+ to expect options and other ARGV-elements in any order and that care about
+ the ordering of the two. We describe each non-option ARGV-element
+ as if it were the argument of an option with character code 1.
+ Using `-' as the first character of the list of option characters
+ selects this mode of operation.
+
+ The special argument `--' forces an end of option-scanning regardless
+ of the value of `ordering'. In the case of RETURN_IN_ORDER, only
+ `--' can cause `getopt' to return -1 with `optind' != ARGC. */
+
+static enum
+{
+ REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+} ordering;
+
+/* Value of POSIXLY_CORRECT environment variable. */
+static char *posixly_correct;
+
+#ifdef __GNU_LIBRARY__
+/* We want to avoid inclusion of string.h with non-GNU libraries
+ because there are many ways it can cause trouble.
+ On some systems, it contains special magic macros that don't work
+ in GCC. */
+# include
+# define my_index strchr
+#else
+
+# if HAVE_STRING_H || WIN32 /* Pete Wilson mod 7/28/02 */
+# include
+# else
+# include
+# endif
+
+/* Avoid depending on library functions or files
+ whose names are inconsistent. */
+
+#ifndef getenv
+extern char *getenv ();
+#endif
+
+static char *
+my_index (str, chr)
+ const char *str;
+ int chr;
+{
+ while (*str)
+ {
+ if (*str == chr)
+ return (char *) str;
+ str++;
+ }
+ return 0;
+}
+
+/* If using GCC, we can safely declare strlen this way.
+ If not using GCC, it is ok not to declare it. */
+#ifdef __GNUC__
+/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
+ That was relevant to code that was here before. */
+# if (!defined __STDC__ || !__STDC__) && !defined strlen
+/* gcc with -traditional declares the built-in strlen to return int,
+ and has done so at least since version 2.4.5. -- rms. */
+extern int strlen (const char *);
+# endif /* not __STDC__ */
+#endif /* __GNUC__ */
+
+#endif /* not __GNU_LIBRARY__ */
+
+/* Handle permutation of arguments. */
+
+/* Describe the part of ARGV that contains non-options that have
+ been skipped. `first_nonopt' is the index in ARGV of the first of them;
+ `last_nonopt' is the index after the last of them. */
+
+static int first_nonopt;
+static int last_nonopt;
+
+#ifdef _LIBC
+/* Stored original parameters.
+ XXX This is no good solution. We should rather copy the args so
+ that we can compare them later. But we must not use malloc(3). */
+extern int __libc_argc;
+extern char **__libc_argv;
+
+/* Bash 2.0 gives us an environment variable containing flags
+ indicating ARGV elements that should not be considered arguments. */
+
+# ifdef USE_NONOPTION_FLAGS
+/* Defined in getopt_init.c */
+extern char *__getopt_nonoption_flags;
+
+static int nonoption_flags_max_len;
+static int nonoption_flags_len;
+# endif
+
+# ifdef USE_NONOPTION_FLAGS
+# define SWAP_FLAGS(ch1, ch2) \
+ if (nonoption_flags_len > 0) \
+ { \
+ char __tmp = __getopt_nonoption_flags[ch1]; \
+ __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2]; \
+ __getopt_nonoption_flags[ch2] = __tmp; \
+ }
+# else
+# define SWAP_FLAGS(ch1, ch2)
+# endif
+#else /* !_LIBC */
+# define SWAP_FLAGS(ch1, ch2)
+#endif /* _LIBC */
+
+/* Exchange two adjacent subsequences of ARGV.
+ One subsequence is elements [first_nonopt,last_nonopt)
+ which contains all the non-options that have been skipped so far.
+ The other is elements [last_nonopt,optind), which contains all
+ the options processed since those non-options were skipped.
+
+ `first_nonopt' and `last_nonopt' are relocated so that they describe
+ the new indices of the non-options in ARGV after they are moved. */
+
+#if defined __STDC__ && __STDC__
+static void exchange (char **);
+#endif
+
+static void
+exchange (argv)
+ char **argv;
+{
+ int bottom = first_nonopt;
+ int middle = last_nonopt;
+ int top = optind;
+ char *tem;
+
+ /* Exchange the shorter segment with the far end of the longer segment.
+ That puts the shorter segment into the right place.
+ It leaves the longer segment in the right place overall,
+ but it consists of two parts that need to be swapped next. */
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+ /* First make sure the handling of the `__getopt_nonoption_flags'
+ string can work normally. Our top argument must be in the range
+ of the string. */
+ if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
+ {
+ /* We must extend the array. The user plays games with us and
+ presents new arguments. */
+ char *new_str = malloc (top + 1);
+ if (new_str == NULL)
+ nonoption_flags_len = nonoption_flags_max_len = 0;
+ else
+ {
+ memset (__mempcpy (new_str, __getopt_nonoption_flags,
+ nonoption_flags_max_len),
+ '\0', top + 1 - nonoption_flags_max_len);
+ nonoption_flags_max_len = top + 1;
+ __getopt_nonoption_flags = new_str;
+ }
+ }
+#endif
+
+ while (top > middle && middle > bottom)
+ {
+ if (top - middle > middle - bottom)
+ {
+ /* Bottom segment is the short one. */
+ int len = middle - bottom;
+ register int i;
+
+ /* Swap it with the top part of the top segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[top - (middle - bottom) + i];
+ argv[top - (middle - bottom) + i] = tem;
+ SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
+ }
+ /* Exclude the moved bottom segment from further swapping. */
+ top -= len;
+ }
+ else
+ {
+ /* Top segment is the short one. */
+ int len = top - middle;
+ register int i;
+
+ /* Swap it with the bottom part of the bottom segment. */
+ for (i = 0; i < len; i++)
+ {
+ tem = argv[bottom + i];
+ argv[bottom + i] = argv[middle + i];
+ argv[middle + i] = tem;
+ SWAP_FLAGS (bottom + i, middle + i);
+ }
+ /* Exclude the moved top segment from further swapping. */
+ bottom += len;
+ }
+ }
+
+ /* Update records for the slots the non-options now occupy. */
+
+ first_nonopt += (optind - last_nonopt);
+ last_nonopt = optind;
+}
+
+/* Initialize the internal data when the first call is made. */
+
+#if defined __STDC__ && __STDC__
+static const char *_getopt_initialize (int, char *const *, const char *);
+#endif
+static const char *
+_getopt_initialize (argc, argv, optstring)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+{
+ /* Start processing options with ARGV-element 1 (since ARGV-element 0
+ is the program name); the sequence of previously skipped
+ non-option ARGV-elements is empty. */
+
+ first_nonopt = last_nonopt = optind;
+
+ nextchar = NULL;
+
+ posixly_correct = getenv ("POSIXLY_CORRECT");
+
+ /* Determine how to handle the ordering of options and nonoptions. */
+
+ if (optstring[0] == '-')
+ {
+ ordering = RETURN_IN_ORDER;
+ ++optstring;
+ }
+ else if (optstring[0] == '+')
+ {
+ ordering = REQUIRE_ORDER;
+ ++optstring;
+ }
+ else if (posixly_correct != NULL)
+ ordering = REQUIRE_ORDER;
+ else
+ ordering = PERMUTE;
+
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+ if (posixly_correct == NULL
+ && argc == __libc_argc && argv == __libc_argv)
+ {
+ if (nonoption_flags_max_len == 0)
+ {
+ if (__getopt_nonoption_flags == NULL
+ || __getopt_nonoption_flags[0] == '\0')
+ nonoption_flags_max_len = -1;
+ else
+ {
+ const char *orig_str = __getopt_nonoption_flags;
+ int len = nonoption_flags_max_len = strlen (orig_str);
+ if (nonoption_flags_max_len < argc)
+ nonoption_flags_max_len = argc;
+ __getopt_nonoption_flags =
+ (char *) malloc (nonoption_flags_max_len);
+ if (__getopt_nonoption_flags == NULL)
+ nonoption_flags_max_len = -1;
+ else
+ memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
+ '\0', nonoption_flags_max_len - len);
+ }
+ }
+ nonoption_flags_len = nonoption_flags_max_len;
+ }
+ else
+ nonoption_flags_len = 0;
+#endif
+
+ return optstring;
+}
+
+/* Scan elements of ARGV (whose length is ARGC) for option characters
+ given in OPTSTRING.
+
+ If an element of ARGV starts with '-', and is not exactly "-" or "--",
+ then it is an option element. The characters of this element
+ (aside from the initial '-') are option characters. If `getopt'
+ is called repeatedly, it returns successively each of the option characters
+ from each of the option elements.
+
+ If `getopt' finds another option character, it returns that character,
+ updating `optind' and `nextchar' so that the next call to `getopt' can
+ resume the scan with the following option character or ARGV-element.
+
+ If there are no more option characters, `getopt' returns -1.
+ Then `optind' is the index in ARGV of the first ARGV-element
+ that is not an option. (The ARGV-elements have been permuted
+ so that those that are not options now come last.)
+
+ OPTSTRING is a string containing the legitimate option characters.
+ If an option character is seen that is not listed in OPTSTRING,
+ return '?' after printing an error message. If you set `opterr' to
+ zero, the error message is suppressed but we still return '?'.
+
+ If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+ so the following text in the same ARGV-element, or the text of the following
+ ARGV-element, is returned in `optarg'. Two colons mean an option that
+ wants an optional arg; if there is text in the current ARGV-element,
+ it is returned in `optarg', otherwise `optarg' is set to zero.
+
+ If OPTSTRING starts with `-' or `+', it requests different methods of
+ handling the non-option ARGV-elements.
+ See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+
+ Long-named options begin with `--' instead of `-'.
+ Their names may be abbreviated as long as the abbreviation is unique
+ or is an exact match for some defined option. If they have an
+ argument, it follows the option name in the same ARGV-element, separated
+ from the option name by a `=', or else the in next ARGV-element.
+ When `getopt' finds a long-named option, it returns 0 if that option's
+ `flag' field is nonzero, the value of the option's `val' field
+ if the `flag' field is zero.
+
+ The elements of ARGV aren't really const, because we permute them.
+ But we pretend they're const in the prototype to be compatible
+ with other systems.
+
+ LONGOPTS is a vector of `struct option' terminated by an
+ element containing a name which is zero.
+
+ LONGIND returns the index in LONGOPT of the long-named option found.
+ It is only valid when a long-named option has been found by the most
+ recent call.
+
+ If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+ long-named options. */
+
+int
+_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+ const struct option *longopts;
+ int *longind;
+ int long_only;
+{
+ int print_errors = opterr;
+ if (optstring[0] == ':')
+ print_errors = 0;
+
+ if (argc < 1)
+ return -1;
+
+ optarg = NULL;
+
+ if (optind == 0 || !__getopt_initialized)
+ {
+ if (optind == 0)
+ optind = 1; /* Don't scan ARGV[0], the program name. */
+ optstring = _getopt_initialize (argc, argv, optstring);
+ __getopt_initialized = 1;
+ }
+
+ /* Test whether ARGV[optind] points to a non-option argument.
+ Either it does not have option syntax, or there is an environment flag
+ from the shell indicating it is not an option. The later information
+ is only used when the used in the GNU libc. */
+#if defined _LIBC && defined USE_NONOPTION_FLAGS
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0' \
+ || (optind < nonoption_flags_len \
+ && __getopt_nonoption_flags[optind] == '1'))
+#else
+# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
+#endif
+
+ if (nextchar == NULL || *nextchar == '\0')
+ {
+ /* Advance to the next ARGV-element. */
+
+ /* Give FIRST_NONOPT and LAST_NONOPT rational values if OPTIND has been
+ moved back by the user (who may also have changed the arguments). */
+ if (last_nonopt > optind)
+ last_nonopt = optind;
+ if (first_nonopt > optind)
+ first_nonopt = optind;
+
+ if (ordering == PERMUTE)
+ {
+ /* If we have just processed some options following some non-options,
+ exchange them so that the options come first. */
+
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
+ exchange ((char **) argv);
+ else if (last_nonopt != optind)
+ first_nonopt = optind;
+
+ /* Skip any additional non-options
+ and extend the range of non-options previously skipped. */
+
+ while (optind < argc && NONOPTION_P)
+ optind++;
+ last_nonopt = optind;
+ }
+
+ /* The special ARGV-element `--' means premature end of options.
+ Skip it like a null option,
+ then exchange with previous non-options as if it were an option,
+ then skip everything else like a non-option. */
+
+ if (optind != argc && !strcmp (argv[optind], "--"))
+ {
+ optind++;
+
+ if (first_nonopt != last_nonopt && last_nonopt != optind)
+ exchange ((char **) argv);
+ else if (first_nonopt == last_nonopt)
+ first_nonopt = optind;
+ last_nonopt = argc;
+
+ optind = argc;
+ }
+
+ /* If we have done all the ARGV-elements, stop the scan
+ and back over any non-options that we skipped and permuted. */
+
+ if (optind == argc)
+ {
+ /* Set the next-arg-index to point at the non-options
+ that we previously skipped, so the caller will digest them. */
+ if (first_nonopt != last_nonopt)
+ optind = first_nonopt;
+ return -1;
+ }
+
+ /* If we have come to a non-option and did not permute it,
+ either stop the scan or describe it to the caller and pass it by. */
+
+ if (NONOPTION_P)
+ {
+ if (ordering == REQUIRE_ORDER)
+ return -1;
+ optarg = argv[optind++];
+ return 1;
+ }
+
+ /* We have found another option-ARGV-element.
+ Skip the initial punctuation. */
+
+ nextchar = (argv[optind] + 1
+ + (longopts != NULL && argv[optind][1] == '-'));
+ }
+
+ /* Decode the current option-ARGV-element. */
+
+ /* Check whether the ARGV-element is a long option.
+
+ If long_only and the ARGV-element has the form "-f", where f is
+ a valid short option, don't consider it an abbreviated form of
+ a long option that starts with f. Otherwise there would be no
+ way to give the -f short option.
+
+ On the other hand, if there's a long option "fubar" and
+ the ARGV-element is "-fu", do consider that an abbreviation of
+ the long option, just like "--fu", and not "-f" with arg "u".
+
+ This distinction seems to be the most useful approach. */
+
+ if (longopts != NULL
+ && (argv[optind][1] == '-'
+ || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
+ {
+ char *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = -1;
+ int option_index;
+
+ for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, nextchar, nameend - nextchar))
+ {
+ if ((unsigned int) (nameend - nextchar)
+ == (unsigned int) strlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else if (long_only
+ || pfound->has_arg != p->has_arg
+ || pfound->flag != p->flag
+ || pfound->val != p->val)
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+
+ if (ambig && !exact)
+ {
+ if (print_errors)
+ {
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+
+ __asprintf (&buf, _("%s: option `%s' is ambiguous\n"),
+ argv[0], argv[optind]);
+
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ free (buf);
+#else
+ fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
+ argv[0], argv[optind]);
+#endif
+ }
+ nextchar += strlen (nextchar);
+ optind++;
+ optopt = 0;
+ return '?';
+ }
+
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ optind++;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ optarg = nameend + 1;
+ else
+ {
+ if (print_errors)
+ {
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+#endif
+
+ if (argv[optind - 1][1] == '-')
+ {
+ /* --option */
+#if defined _LIBC && defined USE_IN_LIBIO
+ __asprintf (&buf, _("\
+%s: option `--%s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+#else
+ fprintf (stderr, _("\
+%s: option `--%s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+#endif
+ }
+ else
+ {
+ /* +option or -option */
+#if defined _LIBC && defined USE_IN_LIBIO
+ __asprintf (&buf, _("\
+%s: option `%c%s' doesn't allow an argument\n"),
+ argv[0], argv[optind - 1][0],
+ pfound->name);
+#else
+ fprintf (stderr, _("\
+%s: option `%c%s' doesn't allow an argument\n"),
+ argv[0], argv[optind - 1][0], pfound->name);
+#endif
+ }
+
+#if defined _LIBC && defined USE_IN_LIBIO
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ free (buf);
+#endif
+ }
+
+ nextchar += strlen (nextchar);
+
+ optopt = pfound->val;
+ return '?';
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (optind < argc)
+ optarg = argv[optind++];
+ else
+ {
+ if (print_errors)
+ {
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+
+ __asprintf (&buf,
+ _("%s: option `%s' requires an argument\n"),
+ argv[0], argv[optind - 1]);
+
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ free (buf);
+#else
+ fprintf (stderr,
+ _("%s: option `%s' requires an argument\n"),
+ argv[0], argv[optind - 1]);
+#endif
+ }
+ nextchar += strlen (nextchar);
+ optopt = pfound->val;
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ nextchar += strlen (nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+
+ /* Can't find it as a long option. If this is not getopt_long_only,
+ or the option starts with '--' or is not a valid short
+ option, then it's an error.
+ Otherwise interpret it as a short option. */
+ if (!long_only || argv[optind][1] == '-'
+ || my_index (optstring, *nextchar) == NULL)
+ {
+ if (print_errors)
+ {
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+#endif
+
+ if (argv[optind][1] == '-')
+ {
+ /* --option */
+#if defined _LIBC && defined USE_IN_LIBIO
+ __asprintf (&buf, _("%s: unrecognized option `--%s'\n"),
+ argv[0], nextchar);
+#else
+ fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
+ argv[0], nextchar);
+#endif
+ }
+ else
+ {
+ /* +option or -option */
+#if defined _LIBC && defined USE_IN_LIBIO
+ __asprintf (&buf, _("%s: unrecognized option `%c%s'\n"),
+ argv[0], argv[optind][0], nextchar);
+#else
+ fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
+ argv[0], argv[optind][0], nextchar);
+#endif
+ }
+
+#if defined _LIBC && defined USE_IN_LIBIO
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ free (buf);
+#endif
+ }
+ nextchar = (char *) "";
+ optind++;
+ optopt = 0;
+ return '?';
+ }
+ }
+
+ /* Look at and handle the next short option-character. */
+
+ {
+ char c = *nextchar++;
+ char *temp = my_index (optstring, c);
+
+ /* Increment `optind' when we start to process its last character. */
+ if (*nextchar == '\0')
+ ++optind;
+
+ if (temp == NULL || c == ':')
+ {
+ if (print_errors)
+ {
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+#endif
+
+ if (posixly_correct)
+ {
+ /* 1003.2 specifies the format of this message. */
+#if defined _LIBC && defined USE_IN_LIBIO
+ __asprintf (&buf, _("%s: illegal option -- %c\n"),
+ argv[0], c);
+#else
+ fprintf (stderr, _("%s: illegal option -- %c\n"), argv[0], c);
+#endif
+ }
+ else
+ {
+#if defined _LIBC && defined USE_IN_LIBIO
+ __asprintf (&buf, _("%s: invalid option -- %c\n"),
+ argv[0], c);
+#else
+ fprintf (stderr, _("%s: invalid option -- %c\n"), argv[0], c);
+#endif
+ }
+
+#if defined _LIBC && defined USE_IN_LIBIO
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ free (buf);
+#endif
+ }
+ optopt = c;
+ return '?';
+ }
+ /* Convenience. Treat POSIX -W foo same as long option --foo */
+ if (temp[0] == 'W' && temp[1] == ';')
+ {
+ char *nameend;
+ const struct option *p;
+ const struct option *pfound = NULL;
+ int exact = 0;
+ int ambig = 0;
+ int indfound = 0;
+ int option_index;
+
+ /* This is an option that requires an argument. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ optind++;
+ }
+ else if (optind == argc)
+ {
+ if (print_errors)
+ {
+ /* 1003.2 specifies the format of this message. */
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+
+ __asprintf (&buf, _("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ free (buf);
+#else
+ fprintf (stderr, _("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+#endif
+ }
+ optopt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ return c;
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ optarg = argv[optind++];
+
+ /* optarg is now the argument, see if it's in the
+ table of longopts. */
+
+ for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
+ /* Do nothing. */ ;
+
+ /* Test all long options for either exact match
+ or abbreviated matches. */
+ for (p = longopts, option_index = 0; p->name; p++, option_index++)
+ if (!strncmp (p->name, nextchar, nameend - nextchar))
+ {
+ if ((unsigned int) (nameend - nextchar) == strlen (p->name))
+ {
+ /* Exact match found. */
+ pfound = p;
+ indfound = option_index;
+ exact = 1;
+ break;
+ }
+ else if (pfound == NULL)
+ {
+ /* First nonexact match found. */
+ pfound = p;
+ indfound = option_index;
+ }
+ else
+ /* Second or later nonexact match found. */
+ ambig = 1;
+ }
+ if (ambig && !exact)
+ {
+ if (print_errors)
+ {
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+
+ __asprintf (&buf, _("%s: option `-W %s' is ambiguous\n"),
+ argv[0], argv[optind]);
+
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ free (buf);
+#else
+ fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
+ argv[0], argv[optind]);
+#endif
+ }
+ nextchar += strlen (nextchar);
+ optind++;
+ return '?';
+ }
+ if (pfound != NULL)
+ {
+ option_index = indfound;
+ if (*nameend)
+ {
+ /* Don't test has_arg with >, because some C compilers don't
+ allow it to be used on enums. */
+ if (pfound->has_arg)
+ optarg = nameend + 1;
+ else
+ {
+ if (print_errors)
+ {
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+
+ __asprintf (&buf, _("\
+%s: option `-W %s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ free (buf);
+#else
+ fprintf (stderr, _("\
+%s: option `-W %s' doesn't allow an argument\n"),
+ argv[0], pfound->name);
+#endif
+ }
+
+ nextchar += strlen (nextchar);
+ return '?';
+ }
+ }
+ else if (pfound->has_arg == 1)
+ {
+ if (optind < argc)
+ optarg = argv[optind++];
+ else
+ {
+ if (print_errors)
+ {
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+
+ __asprintf (&buf, _("\
+%s: option `%s' requires an argument\n"),
+ argv[0], argv[optind - 1]);
+
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ free (buf);
+#else
+ fprintf (stderr,
+ _("%s: option `%s' requires an argument\n"),
+ argv[0], argv[optind - 1]);
+#endif
+ }
+ nextchar += strlen (nextchar);
+ return optstring[0] == ':' ? ':' : '?';
+ }
+ }
+ nextchar += strlen (nextchar);
+ if (longind != NULL)
+ *longind = option_index;
+ if (pfound->flag)
+ {
+ *(pfound->flag) = pfound->val;
+ return 0;
+ }
+ return pfound->val;
+ }
+ nextchar = NULL;
+ return 'W'; /* Let the application handle it. */
+ }
+ if (temp[1] == ':')
+ {
+ if (temp[2] == ':')
+ {
+ /* This is an option that accepts an argument optionally. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ optind++;
+ }
+ else
+ optarg = NULL;
+ nextchar = NULL;
+ }
+ else
+ {
+ /* This is an option that requires an argument. */
+ if (*nextchar != '\0')
+ {
+ optarg = nextchar;
+ /* If we end this ARGV-element by taking the rest as an arg,
+ we must advance to the next element now. */
+ optind++;
+ }
+ else if (optind == argc)
+ {
+ if (print_errors)
+ {
+ /* 1003.2 specifies the format of this message. */
+#if defined _LIBC && defined USE_IN_LIBIO
+ char *buf;
+
+ __asprintf (&buf,
+ _("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+
+ if (_IO_fwide (stderr, 0) > 0)
+ __fwprintf (stderr, L"%s", buf);
+ else
+ fputs (buf, stderr);
+
+ free (buf);
+#else
+ fprintf (stderr,
+ _("%s: option requires an argument -- %c\n"),
+ argv[0], c);
+#endif
+ }
+ optopt = c;
+ if (optstring[0] == ':')
+ c = ':';
+ else
+ c = '?';
+ }
+ else
+ /* We already incremented `optind' once;
+ increment it again when taking next ARGV-elt as argument. */
+ optarg = argv[optind++];
+ nextchar = NULL;
+ }
+ }
+ return c;
+ }
+}
+
+int
+getopt (argc, argv, optstring)
+ int argc;
+ char *const *argv;
+ const char *optstring;
+{
+ return _getopt_internal (argc, argv, optstring,
+ (const struct option *) 0,
+ (int *) 0,
+ 0);
+}
+
+#endif /* Not ELIDE_CODE. */
+
+
+/* Compile with -DTEST to make an executable for use in testing
+ the above definition of `getopt'. */
+
+/* #define TEST */ /* Pete Wilson mod 7/28/02 */
+#ifdef TEST
+
+#ifndef exit /* Pete Wilson mod 7/28/02 */
+ int exit(int); /* Pete Wilson mod 7/28/02 */
+#endif /* Pete Wilson mod 7/28/02 */
+
+int
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int c;
+ int digit_optind = 0;
+
+ while (1)
+ {
+ int this_option_optind = optind ? optind : 1;
+
+ c = getopt (argc, argv, "abc:d:0123456789");
+ if (c == -1)
+ break;
+
+ switch (c)
+ {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ if (digit_optind != 0 && digit_optind != this_option_optind)
+ printf ("digits occur in two different argv-elements.\n");
+ digit_optind = this_option_optind;
+ printf ("option %c\n", c);
+ break;
+
+ case 'a':
+ printf ("option a\n");
+ break;
+
+ case 'b':
+ printf ("option b\n");
+ break;
+
+ case 'c':
+ printf ("option c with value `%s'\n", optarg);
+ break;
+
+ case '?':
+ break;
+
+ default:
+ printf ("?? getopt returned character code 0%o ??\n", c);
+ }
+ }
+
+ if (optind < argc)
+ {
+ printf ("non-option ARGV-elements: ");
+ while (optind < argc)
+ printf ("%s ", argv[optind++]);
+ printf ("\n");
+ }
+
+ exit (0);
+}
+
+#endif /* TEST */
diff -r 3ebf16150b2e -r e747d2e26af0 examples/TestMasterSlave/getopt.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/TestMasterSlave/getopt.h Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,191 @@
+/* from http://www.pwilson.net/getopt.html */
+
+/* getopt.h */
+/* Declarations for getopt.
+ Copyright (C) 1989-1994, 1996-1999, 2001 Free Software
+ Foundation, Inc. This file is part of the GNU C Library.
+
+ The GNU C 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; either version 2.1 of the License, or
+ (at your option) any later version.
+
+ The GNU C 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 GNU C Library; if not, write
+ to the Free Software Foundation, Inc., 59 Temple Place,
+ Suite 330, Boston, MA 02111-1307 USA. */
+
+
+
+
+
+#ifndef _GETOPT_H
+
+#ifndef __need_getopt
+# define _GETOPT_H 1
+#endif
+
+/* If __GNU_LIBRARY__ is not already defined, either we are being used
+ standalone, or this is the first header included in the source file.
+ If we are being used with glibc, we need to include , but
+ that does not exist if we are standalone. So: if __GNU_LIBRARY__ is
+ not defined, include , which will pull in for us
+ if it's from glibc. (Why ctype.h? It's guaranteed to exist and it
+ doesn't flood the namespace with stuff the way some other headers do.) */
+#if !defined __GNU_LIBRARY__
+# include
+#endif
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* For communication from `getopt' to the caller.
+ When `getopt' finds an option that takes an argument,
+ the argument value is returned here.
+ Also, when `ordering' is RETURN_IN_ORDER,
+ each non-option ARGV-element is returned here. */
+
+extern char *optarg;
+
+/* Index in ARGV of the next element to be scanned.
+ This is used for communication to and from the caller
+ and for communication between successive calls to `getopt'.
+
+ On entry to `getopt', zero means this is the first call; initialize.
+
+ When `getopt' returns -1, this is the index of the first of the
+ non-option elements that the caller should itself scan.
+
+ Otherwise, `optind' communicates from one call to the next
+ how much of ARGV has been scanned so far. */
+
+extern int optind;
+
+/* Callers store zero here to inhibit the error message `getopt' prints
+ for unrecognized options. */
+
+extern int opterr;
+
+/* Set to an option character which was unrecognized. */
+
+extern int optopt;
+
+#ifndef __need_getopt
+/* Describe the long-named options requested by the application.
+ The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
+ of `struct option' terminated by an element containing a name which is
+ zero.
+
+ The field `has_arg' is:
+ no_argument (or 0) if the option does not take an argument,
+ required_argument (or 1) if the option requires an argument,
+ optional_argument (or 2) if the option takes an optional argument.
+
+ If the field `flag' is not NULL, it points to a variable that is set
+ to the value given in the field `val' when the option is found, but
+ left unchanged if the option is not found.
+
+ To have a long-named option do something other than set an `int' to
+ a compiled-in constant, such as set a value from `optarg', set the
+ option's `flag' field to zero and its `val' field to a nonzero
+ value (the equivalent single-letter option character, if there is
+ one). For long options that have a zero `flag' field, `getopt'
+ returns the contents of the `val' field. */
+
+struct option
+{
+# if (defined __STDC__ && __STDC__) || defined __cplusplus
+ const char *name;
+# else
+ char *name;
+# endif
+ /* has_arg can't be an enum because some compilers complain about
+ type mismatches in all the code that assumes it is an int. */
+ int has_arg;
+ int *flag;
+ int val;
+};
+
+/* Names for the values of the `has_arg' field of `struct option'. */
+
+# define no_argument 0
+# define required_argument 1
+# define optional_argument 2
+#endif /* need getopt */
+
+
+/* Get definitions and prototypes for functions to process the
+ arguments in ARGV (ARGC of them, minus the program name) for
+ options given in OPTS.
+
+ Return the option character from OPTS just read. Return -1 when
+ there are no more options. For unrecognized options, or options
+ missing arguments, `optopt' is set to the option letter, and '?' is
+ returned.
+
+ The OPTS string is a list of characters which are recognized option
+ letters, optionally followed by colons, specifying that that letter
+ takes an argument, to be placed in `optarg'.
+
+ If a letter in OPTS is followed by two colons, its argument is
+ optional. This behavior is specific to the GNU `getopt'.
+
+ The argument `--' causes premature termination of argument
+ scanning, explicitly telling `getopt' that there are no more
+ options.
+
+ If OPTS begins with `--', then non-option arguments are treated as
+ arguments to the option '\0'. This behavior is specific to the GNU
+ `getopt'. */
+
+#if (defined __STDC__ && __STDC__) || defined __cplusplus
+# ifdef __GNU_LIBRARY__
+/* Many other libraries have conflicting prototypes for getopt, with
+ differences in the consts, in stdlib.h. To avoid compilation
+ errors, only prototype getopt for the GNU C library. */
+extern int getopt (int ___argc, char *const *___argv, const char *__shortopts);
+# else /* not __GNU_LIBRARY__ */
+extern int getopt ();
+# endif /* __GNU_LIBRARY__ */
+
+# ifndef __need_getopt
+extern int getopt_long (int ___argc, char *const *___argv,
+ const char *__shortopts,
+ const struct option *__longopts, int *__longind);
+extern int getopt_long_only (int ___argc, char *const *___argv,
+ const char *__shortopts,
+ const struct option *__longopts, int *__longind);
+
+/* Internal only. Users should not call this directly. */
+extern int _getopt_internal (int ___argc, char *const *___argv,
+ const char *__shortopts,
+ const struct option *__longopts, int *__longind,
+ int __long_only);
+# endif
+#else /* not __STDC__ */
+extern int getopt ();
+# ifndef __need_getopt
+extern int getopt_long ();
+extern int getopt_long_only ();
+
+extern int _getopt_internal ();
+# endif
+#endif /* __STDC__ */
+
+#ifdef __cplusplus
+}
+#endif
+
+/* Make sure we later can get all the definitions and declarations. */
+#undef __need_getopt
+
+#endif /* getopt.h */
+
diff -r 3ebf16150b2e -r e747d2e26af0 examples/win32test/.cvsignore
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/win32test/.cvsignore Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,3 @@
+Debug
+win32test.vcproj.KONG.edouard.user
+Release
diff -r 3ebf16150b2e -r e747d2e26af0 examples/win32test/main.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/win32test/main.c Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,247 @@
+/**************************************************************************
+CanFestival3 win32 port example
+
+This sample demonstrates CanFestival usage with Win32
+
+Program implements master node. It starts CANOpen slave node, modifies OD,
+performs SDO reads and prints some slave node information.
+
+Usage:
+
+ win32test
+
+ where node_id is node ID in decimal format
+
+You should have CanFestival-3.dll CAN-uVCCM.dll in the search path to run this sample.
+Code will work with non-UNICODE CanFestival-3.dll CAN-uVCCM.dll libraries.
+
+Sample can work on other platdorms as well.
+
+Copyright (C) 2007 Leonid Tochinski (ltochinski AT chattenassociates DOT com)
+***************************************************************************/
+
+#include
+#include
+#include "win32test.h"
+#include "canfestival.h"
+
+#ifdef WIN32
+#define sleep_proc(ms) Sleep(ms)
+#define uptime_ms_proc() GetTickCount()
+#else
+#include
+#define sleep_proc(ms)
+#define uptime_ms_proc (1000*(time()%86400)) // TOD
+#endif
+
+/* required canfestival callbacks. */
+void win32test_SDOtimeoutError(UNS8 line)
+ {
+ }
+
+void win32test_heartbeatError(UNS8 node_id)
+ {
+ }
+
+void win32test_initialisation(void)
+ {
+ }
+
+void win32test_preOperational(void)
+ {
+ }
+
+void win32test_operational(void)
+ {
+ }
+
+void win32test_stopped(void)
+ {
+ }
+
+void win32test_post_sync(void)
+ {
+ }
+
+void win32test_post_TPDO(void)
+ {
+ }
+
+static CAN_HANDLE g_MasterCanHandle = NULL;
+
+UNS8 win32test_canSend(Message *m)
+ {
+ if (g_MasterCanHandle != NULL)
+ return canSend(g_MasterCanHandle, m);
+ return 1;
+ }
+
+UNS8 GetChangeStateResults(UNS8 node_id, UNS8 expected_state, unsigned long timeout_ms)
+ {
+ unsigned long start_time = 0;
+
+ // reset nodes state
+ win32test_Data.NMTable[node_id] = Unknown_state;
+
+ // request node state
+ masterRequestNodeState(&win32test_Data, node_id);
+
+ start_time = uptime_ms_proc();
+ while(uptime_ms_proc() - start_time < timeout_ms)
+ {
+ if (getNodeState(&win32test_Data, node_id) == expected_state)
+ return 0;
+ sleep_proc(1);
+ }
+ return 0xFF;
+ }
+
+UNS8 ReadSDO(UNS8 nodeId, UNS16 index, UNS8 subIndex, UNS8 dataType, void* data, UNS8* size)
+ {
+ UNS32 abortCode = 0;
+ UNS8 res = SDO_UPLOAD_IN_PROGRESS;
+ // Read SDO
+ UNS8 err = readNetworkDict (&win32test_Data, nodeId, index, subIndex, dataType);
+ if (err)
+ return 0xFF;
+ for(;;)
+ {
+ res = getReadResultNetworkDict (&win32test_Data, nodeId, data, size, &abortCode);
+ if (res != SDO_UPLOAD_IN_PROGRESS)
+ break;
+ sleep_proc(1);
+ continue;
+ }
+ closeSDOtransfer(&win32test_Data, nodeId, SDO_CLIENT);
+ if (res == SDO_FINISHED)
+ return 0;
+ return 0xFF;
+ }
+
+int main(int argc, char *argv[])
+ {
+ UNS8 node_id = 0;
+ s_BOARD MasterBoard = {"1", "125K"};
+ char* dll_file_name;
+
+ /* process command line arguments */
+ if (argc < 2)
+ {
+ printf("USAGE: win32test node_id [dll_file_name]\n");
+ return 1;
+ }
+
+ node_id = atoi(argv[1]);
+ if (node_id < 2 || node_id > 127)
+ {
+ printf("ERROR: node_id shoule be >=2 and <= 127\n");
+ return 1;
+ }
+
+ if (argc > 2)
+ dll_file_name = argv[2];
+ else
+ dll_file_name = "can_uvccm_win32.dll";
+
+ // load can driver
+ if (!LoadCanDriver(dll_file_name))
+ {
+ printf("ERROR: could not load diver %s\n", dll_file_name);
+ return 1;
+ }
+
+ g_MasterCanHandle = canOpen(&MasterBoard,&win32test_Data);
+
+ if (g_MasterCanHandle)
+ {
+ /* Defining the node Id */
+ setNodeId(&win32test_Data, 0x01);
+
+ /* init */
+ setState(&win32test_Data, Initialisation);
+
+ /****************************** START *******************************/
+ /* Put the master in operational mode */
+ setState(&win32test_Data, Operational);
+
+ /* Ask slave node to go in operational mode */
+ masterSendNMTstateChange (&win32test_Data, 0, NMT_Start_Node);
+
+ printf("\nStarting node %d (%xh) ...\n",(int)node_id,(int)node_id);
+
+ /* wait untill mode will switch to operational state*/
+ if (GetChangeStateResults(node_id, Operational, 3000) != 0xFF)
+ {
+ /* modify Client SDO 1 Parameter */
+ UNS32 COB_ID_Client_to_Server_Transmit_SDO = 0x600 + node_id;
+ UNS32 COB_ID_Server_to_Client_Receive_SDO = 0x580 + node_id;
+ UNS32 Node_ID_of_the_SDO_Server = node_id;
+ UNS8 ExpectedSize = sizeof (UNS32);
+
+ if (OD_SUCCESSFUL == setODentry(&win32test_Data, 0x1280, 1, &COB_ID_Client_to_Server_Transmit_SDO, &ExpectedSize, RW)
+ && OD_SUCCESSFUL == setODentry(&win32test_Data, 0x1280, 2, &COB_ID_Server_to_Client_Receive_SDO, &ExpectedSize, RW)
+ && OD_SUCCESSFUL == setODentry(&win32test_Data, 0x1280, 3, &Node_ID_of_the_SDO_Server, &ExpectedSize, RW))
+ {
+ UNS32 dev_type = 0;
+ char device_name[64]="";
+ char hw_ver[64]="";
+ char sw_ver[64]="";
+ UNS32 vendor_id = 0;
+ UNS32 prod_code = 0;
+ UNS32 ser_num = 0;
+ UNS8 size;
+ UNS8 res;
+
+ printf("\nnode_id: %d (%xh) info\n",(int)node_id,(int)node_id);
+ printf("********************************************\n");
+
+ size = sizeof (dev_type);
+ res = ReadSDO(node_id, 0x1000, 0, uint32, &dev_type, &size);
+ printf("device type: %d\n",dev_type & 0xFFFF);
+
+ size = sizeof (device_name);
+ res = ReadSDO(node_id, 0x1008, 0, visible_string, device_name, &size);
+ printf("device name: %s\n",device_name);
+
+ size = sizeof (hw_ver);
+ res = ReadSDO(node_id, 0x1009, 0, visible_string, hw_ver, &size);
+ printf("HW version: %s\n",hw_ver);
+
+ size = sizeof (sw_ver);
+ res = ReadSDO(node_id, 0x100A, 0, visible_string, sw_ver, &size);
+ printf("SW version: %s\n",sw_ver);
+
+ size = sizeof (vendor_id);
+ res = ReadSDO(node_id, 0x1018, 1, uint32, &vendor_id, &size);
+ printf("vendor id: %d\n",vendor_id);
+
+ size = sizeof (prod_code);
+ res = ReadSDO(node_id, 0x1018, 2, uint32, &prod_code, &size);
+ printf("product code: %d\n",prod_code);
+
+ size = sizeof (ser_num);
+ res = ReadSDO(node_id, 0x1018, 4, uint32, &ser_num, &size);
+ printf("serial number: %d\n",ser_num);
+
+ printf("********************************************\n");
+ }
+ else
+ {
+ printf("ERROR: Object dictionary access failed\n");
+ }
+ }
+ else
+ {
+ printf("ERROR: node_id %d (%xh) is not responding\n",(int)node_id,(int)node_id);
+ }
+
+ masterSendNMTstateChange (&win32test_Data, 0x02, NMT_Stop_Node);
+
+ setState(&win32test_Data, Stopped);
+
+ canClose(g_MasterCanHandle);
+ }
+ return 0;
+ }
+
+
\ No newline at end of file
diff -r 3ebf16150b2e -r e747d2e26af0 examples/win32test/win32test.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/win32test/win32test.c Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,159 @@
+
+/* File generated by gen_cfile.py. Should not be modified. */
+
+#include "win32test.h"
+
+/**************************************************************************/
+/* Declaration of the mapped variables */
+/**************************************************************************/
+
+/**************************************************************************/
+/* Declaration of the value range types */
+/**************************************************************************/
+
+UNS32 win32test_valueRangeTest (UNS8 typeValue, void * value)
+{
+ switch (typeValue) {
+ }
+ return 0;
+}
+
+/**************************************************************************/
+/* The node id */
+/**************************************************************************/
+/* node_id default value.*/
+UNS8 win32test_bDeviceNodeId = 0x01;
+
+/**************************************************************************/
+/* Array of message processing information */
+
+const UNS8 win32test_iam_a_slave = 0;
+
+TIMER_HANDLE win32test_heartBeatTimers[1];
+
+/*
+$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
+
+ OBJECT DICTIONARY
+
+$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
+*/
+
+/* index 0x1000 : Device Type. */
+ UNS32 win32test_obj1000 = 0x12D; /* 301 */
+ subindex win32test_Index1000[] =
+ {
+ { RO, uint32, sizeof (UNS32), (void*)&win32test_obj1000 }
+ };
+
+/* index 0x1001 : Error Register. */
+ UNS8 win32test_obj1001 = 0x0; /* 0 */
+ subindex win32test_Index1001[] =
+ {
+ { RO, uint8, sizeof (UNS8), (void*)&win32test_obj1001 }
+ };
+
+/* index 0x1005 : SYNC COB ID. */
+ UNS32 win32test_obj1005 = 0x0; /* 0 */
+ ODCallback_t win32test_Index1005_callbacks[] =
+ {
+ NULL,
+ };
+ subindex win32test_Index1005[] =
+ {
+ { RW, uint32, sizeof (UNS32), (void*)&win32test_obj1005 }
+ };
+
+/* index 0x1006 : Communication / Cycle Period */
+ UNS32 win32test_obj1006 = 0x0; /* 0 */
+
+/* index 0x1016 : Consumer Heartbeat Time */
+ UNS8 win32test_highestSubIndex_obj1016 = 0;
+ UNS32 win32test_obj1016[]={0};
+
+/* index 0x1017 : Producer Heartbeat Time */
+ UNS16 win32test_obj1017 = 0x0; /* 0 */
+
+/* index 0x1018 : Identity. */
+ UNS8 win32test_highestSubIndex_obj1018 = 4; /* number of subindex - 1*/
+ UNS32 win32test_obj1018_Vendor_ID = 0x0; /* 0 */
+ UNS32 win32test_obj1018_Product_Code = 0x0; /* 0 */
+ UNS32 win32test_obj1018_Revision_Number = 0x0; /* 0 */
+ UNS32 win32test_obj1018_Serial_Number = 0x0; /* 0 */
+ subindex win32test_Index1018[] =
+ {
+ { RO, uint8, sizeof (UNS8), (void*)&win32test_highestSubIndex_obj1018 },
+ { RO, uint32, sizeof (UNS32), (void*)&win32test_obj1018_Vendor_ID },
+ { RO, uint32, sizeof (UNS32), (void*)&win32test_obj1018_Product_Code },
+ { RO, uint32, sizeof (UNS32), (void*)&win32test_obj1018_Revision_Number },
+ { RO, uint32, sizeof (UNS32), (void*)&win32test_obj1018_Serial_Number }
+ };
+
+/* index 0x1280 : Client SDO 1 Parameter. */
+ UNS8 win32test_highestSubIndex_obj1280 = 3; /* number of subindex - 1*/
+ UNS32 win32test_obj1280_COB_ID_Client_to_Server_Transmit_SDO = 0x0; /* 0 */
+ UNS32 win32test_obj1280_COB_ID_Server_to_Client_Receive_SDO = 0x0; /* 0 */
+ UNS32 win32test_obj1280_Node_ID_of_the_SDO_Server = 0x0; /* 0 */
+ subindex win32test_Index1280[] =
+ {
+ { RO, uint8, sizeof (UNS8), (void*)&win32test_highestSubIndex_obj1280 },
+ { RW, uint32, sizeof (UNS32), (void*)&win32test_obj1280_COB_ID_Client_to_Server_Transmit_SDO },
+ { RW, uint32, sizeof (UNS32), (void*)&win32test_obj1280_COB_ID_Server_to_Client_Receive_SDO },
+ { RW, uint32, sizeof (UNS32), (void*)&win32test_obj1280_Node_ID_of_the_SDO_Server }
+ };
+
+const indextable win32test_objdict[] =
+{
+ { (subindex*)win32test_Index1000,sizeof(win32test_Index1000)/sizeof(win32test_Index1000[0]), 0x1000},
+ { (subindex*)win32test_Index1001,sizeof(win32test_Index1001)/sizeof(win32test_Index1001[0]), 0x1001},
+ { (subindex*)win32test_Index1005,sizeof(win32test_Index1005)/sizeof(win32test_Index1005[0]), 0x1005},
+ { (subindex*)win32test_Index1018,sizeof(win32test_Index1018)/sizeof(win32test_Index1018[0]), 0x1018},
+ { (subindex*)win32test_Index1280,sizeof(win32test_Index1280)/sizeof(win32test_Index1280[0]), 0x1280},
+};
+
+const indextable * win32test_scanIndexOD (UNS16 wIndex, UNS32 * errorCode, ODCallback_t **callbacks)
+{
+ int i;
+ *callbacks = NULL;
+ switch(wIndex){
+ case 0x1000: i = 0;break;
+ case 0x1001: i = 1;break;
+ case 0x1005: i = 2;*callbacks = win32test_Index1005_callbacks; break;
+ case 0x1018: i = 3;break;
+ case 0x1280: i = 4;break;
+ default:
+ *errorCode = OD_NO_SUCH_OBJECT;
+ return NULL;
+ }
+ *errorCode = OD_SUCCESSFUL;
+ return &win32test_objdict[i];
+}
+
+/* To count at which received SYNC a PDO must be sent.
+ * Even if no pdoTransmit are defined, at least one entry is computed
+ * for compilations issues.
+ */
+UNS8 win32test_count_sync[1] = {0,};
+
+quick_index win32test_firstIndex = {
+ 0, /* SDO_SVR */
+ 4, /* SDO_CLT */
+ 0, /* PDO_RCV */
+ 0, /* PDO_RCV_MAP */
+ 0, /* PDO_TRS */
+ 0 /* PDO_TRS_MAP */
+};
+
+quick_index win32test_lastIndex = {
+ 0, /* SDO_SVR */
+ 4, /* SDO_CLT */
+ 0, /* PDO_RCV */
+ 0, /* PDO_RCV_MAP */
+ 0, /* PDO_TRS */
+ 0 /* PDO_TRS_MAP */
+};
+
+UNS16 win32test_ObjdictSize = sizeof(win32test_objdict)/sizeof(win32test_objdict[0]);
+
+CO_Data win32test_Data = CANOPEN_NODE_DATA_INITIALIZER(win32test);
+
diff -r 3ebf16150b2e -r e747d2e26af0 examples/win32test/win32test.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/win32test/win32test.h Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,26 @@
+
+/* File generated by gen_cfile.py. Should not be modified. */
+
+#include "data.h"
+
+/* Prototypes of function provided by object dictionnary */
+UNS32 win32test_valueRangeTest (UNS8 typeValue, void * value);
+const indextable * win32test_scanIndexOD (UNS16 wIndex, UNS32 * errorCode, ODCallback_t **callbacks);
+
+/* prototypes of function to be filled by app. */
+void win32test_SDOtimeoutError(UNS8 line);
+void win32test_heartbeatError(UNS8);
+
+UNS8 win32test_canSend(Message *);
+
+void win32test_initialisation(void);
+void win32test_preOperational(void);
+void win32test_operational(void);
+void win32test_stopped(void);
+
+void win32test_post_sync(void);
+void win32test_post_TPDO(void);
+
+/* Master node data struct */
+extern CO_Data win32test_Data;
+
diff -r 3ebf16150b2e -r e747d2e26af0 examples/win32test/win32test.od
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/win32test/win32test.od Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 3ebf16150b2e -r e747d2e26af0 examples/win32test/win32test.vcproj
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/examples/win32test/win32test.vcproj Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,216 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -r 3ebf16150b2e -r e747d2e26af0 include/can.h
--- a/include/can.h Tue Apr 03 20:20:27 2007 +0200
+++ b/include/can.h Wed Apr 04 13:04:31 2007 +0200
@@ -22,6 +22,8 @@
#ifndef __can_h__
#define __can_h__
+
+#include "applicfg.h"
/** Used for the Can message structure */
/*
union SHORT_CAN {
diff -r 3ebf16150b2e -r e747d2e26af0 include/can_driver.h
--- a/include/can_driver.h Tue Apr 03 20:20:27 2007 +0200
+++ b/include/can_driver.h Wed Apr 04 13:04:31 2007 +0200
@@ -27,20 +27,26 @@
typedef struct struct_s_BOARD s_BOARD;
+#include "applicfg.h"
#include "can.h"
-UNS8 canReceive(CAN_HANDLE fd0, Message *m);
-UNS8 canSend(CAN_HANDLE fd0, Message *m);
-CAN_HANDLE canOpen(s_BOARD *board);
-int canClose(CAN_HANDLE fd0);
-void canReceiveLoop(CAN_HANDLE fd0);
-
-#include "data.h"
-
struct struct_s_BOARD {
char * busname;
- int baudrate;
- CO_Data * d;
+ char * baudrate;
};
+#ifndef DLL_CALL
+#define DLL_CALL(funcname) funcname##_driver
#endif
+
+#ifndef FCT_PTR_INIT
+#define FCT_PTR_INIT
+#endif
+
+
+UNS8 DLL_CALL(canReceive)(CAN_HANDLE, Message *)FCT_PTR_INIT;
+UNS8 DLL_CALL(canSend)(CAN_HANDLE, Message *)FCT_PTR_INIT;
+CAN_HANDLE DLL_CALL(canOpen)(s_BOARD *)FCT_PTR_INIT;
+int DLL_CALL(canClose)(CAN_HANDLE)FCT_PTR_INIT;
+
+#endif
diff -r 3ebf16150b2e -r e747d2e26af0 include/data.h
--- a/include/data.h Tue Apr 03 20:20:27 2007 +0200
+++ b/include/data.h Wed Apr 04 13:04:31 2007 +0200
@@ -29,7 +29,7 @@
*/
typedef struct struct_CO_Data CO_Data;
-#include
+#include "applicfg.h"
#include "def.h"
#include "can.h"
#include "objdictdef.h"
diff -r 3ebf16150b2e -r e747d2e26af0 include/timer.h
--- a/include/timer.h Tue Apr 03 20:20:27 2007 +0200
+++ b/include/timer.h Wed Apr 04 13:04:31 2007 +0200
@@ -23,6 +23,7 @@
#ifndef __timer_h__
#define __timer_h__
+#include
#include
#define TIMER_HANDLE INTEGER16
diff -r 3ebf16150b2e -r e747d2e26af0 include/timers_driver.h
--- a/include/timers_driver.h Tue Apr 03 20:20:27 2007 +0200
+++ b/include/timers_driver.h Wed Apr 04 13:04:31 2007 +0200
@@ -23,17 +23,18 @@
#ifndef __timer_driver_h__
#define __timer_driver_h__
+#include "timerscfg.h"
#include "timer.h"
/*void initTimer();*/
// For use from CAN driver
void EnterMutex(void);
void LeaveMutex(void);
-void WaitReceiveTaskEnd(TASK_HANDLE*);
+void WaitReceiveTaskEnd(TASK_HANDLE);
// For use from application
void StartTimerLoop(TimerCallback_t init_callback);
void StopTimerLoop(void);
-void CreateReceiveTask(CAN_HANDLE fd0, TASK_HANDLE *ReceiveLoop_task);
+void CreateReceiveTask(CAN_PORT , TASK_HANDLE* , void* );
#endif
diff -r 3ebf16150b2e -r e747d2e26af0 include/unix/applicfg.h
--- a/include/unix/applicfg.h Tue Apr 03 20:20:27 2007 +0200
+++ b/include/unix/applicfg.h Wed Apr 04 13:04:31 2007 +0200
@@ -26,9 +26,6 @@
#include
#include
-#include "cancfg.h"
-#include "timerscfg.h"
-
/* Define the architecture : little_endian or big_endian
-----------------------------------------------------
Test :
@@ -96,4 +93,8 @@
# define MSG_WAR(num, str, val)
#endif
+typedef void* CAN_HANDLE;
+
+typedef void* CAN_PORT;
+
#endif
diff -r 3ebf16150b2e -r e747d2e26af0 include/unix/canfestival.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/unix/canfestival.h Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,21 @@
+#ifndef UNIX_H_
+#define UNIX_H_
+
+#include "timerscfg.h"
+#include "can_driver.h"
+#include "data.h"
+#ifdef WIN32
+#include
+typedef HINSTANCE LIB_HANDLE;
+#else
+#include
+typedef void* LIB_HANDLE;
+#endif
+
+UNS8 UnLoadCanDriver(LIB_HANDLE handle);
+LIB_HANDLE LoadCanDriver(char* driver_name);
+UNS8 canSend(CAN_PORT port, Message *m);
+CAN_PORT canOpen(s_BOARD *board, CO_Data * d);
+int canClose(CAN_PORT port);
+
+#endif /*UNIX_H_*/
diff -r 3ebf16150b2e -r e747d2e26af0 include/win32/applicfg.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/win32/applicfg.h Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,133 @@
+/*
+This file is part of CanFestival, a library implementing CanOpen Stack.
+
+Copyright (C): Edouard TISSERANT and Francis DUPIN
+
+See COPYING file for copyrights details.
+
+This 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; either
+version 2.1 of the License, or (at your option) any later version.
+
+This 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 this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef __APPLICFG_WIN32__
+#define __APPLICFG_WIN32__
+
+#include
+#include
+#include
+
+// Define the architecture : little_endian or big_endian
+// -----------------------------------------------------
+// Test :
+// UNS32 v = 0x1234ABCD;
+// char *data = &v;
+//
+// Result for a little_endian architecture :
+// data[0] = 0xCD;
+// data[1] = 0xAB;
+// data[2] = 0x34;
+// data[3] = 0x12;
+//
+// Result for a big_endian architecture :
+// data[0] = 0x12;
+// data[1] = 0x34;
+// data[2] = 0xAB;
+// data[3] = 0xCD;
+
+// Integers
+#define INTEGER8 char
+#define INTEGER16 short
+#define INTEGER24 long
+#define INTEGER32 long
+#define INTEGER40 long long
+#define INTEGER48 long long
+#define INTEGER56 long long
+#define INTEGER64 long long
+
+// Unsigned integers
+#define UNS8 unsigned char
+#define UNS16 unsigned short
+#define UNS32 unsigned long
+#define UNS24 unsigned long
+#define UNS40 unsigned long long
+#define UNS48 unsigned long long
+#define UNS56 unsigned long long
+#define UNS64 unsigned long long
+
+// Reals
+#define REAL32 float
+#define REAL64 double
+
+// Custom integer types sizes
+#define sizeof_INTEGER24 3
+#define sizeof_INTEGER40 5
+#define sizeof_INTEGER48 6
+#define sizeof_INTEGER56 7
+
+#define sizeof_UNS24 3
+#define sizeof_UNS40 5
+#define sizeof_UNS48 6
+#define sizeof_UNS56 7
+
+// Non integral integers conversion macros
+#define INT24_2_32(a) (a <= 0x7FFFFF ? a : a|0xFF000000)
+#define INT40_2_64(a) (a <= 0x0000007FFFFFFFFF ? a : a|0xFFFFFF0000000000)
+#define INT48_2_64(a) (a <= 0x00007FFFFFFFFFFF ? a : a|0xFFFF000000000000)
+#define INT56_2_64(a) (a <= 0x007FFFFFFFFFFFFF ? a : a|0xFF00000000000000)
+
+#define INT32_2_24(a) (a&0x00FFFFFF)
+#define INT64_2_40(a) (a&0x000000FFFFFFFFFF)
+#define INT64_2_48(a) (a&0x0000FFFFFFFFFFFF)
+#define INT64_2_56(a) (a&0x00FFFFFFFFFFFFFF)
+
+/// Definition of error and warning macros
+// --------------------------------------
+
+#ifdef UNICODE
+ #define CANFESTIVAL_DEBUG_MSG(num, str, val)\
+ {wchar_t msg[300];\
+ unsigned long value = val;\
+ swprintf(msg,L"%s(%d) : 0x%X %s 0x%X\n",__FILE__, __LINE__,num, str, value);\
+ OutputDebugString(msg);}
+#else
+ #define CANFESTIVAL_DEBUG_MSG(num, str, val)\
+ {char msg[300];\
+ unsigned long value = val;\
+ sprintf(msg,"%s(%d) : 0x%X %s 0x%X\n",__FILE__, __LINE__,num, str, value);\
+ OutputDebugString(msg);}
+#endif
+
+/// Definition of MSG_WAR
+// ---------------------
+#ifdef DEBUG_WAR_CONSOLE_ON
+ #define MSG_WAR(num, str, val) CANFESTIVAL_DEBUG_MSG(num, str, val)
+#else
+# define MSG_WAR(num, str, val)
+#endif
+
+/// Definition of MSG_ERR
+// ---------------------
+#ifdef DEBUG_ERR_CONSOLE_ON
+# define MSG_ERR(num, str, val) CANFESTIVAL_DEBUG_MSG(num, str, val)
+#else
+# define MSG_ERR(num, str, val)
+#endif
+
+
+
+typedef void* CAN_HANDLE;
+
+typedef void* CAN_PORT;
+
+#endif // __APPLICFG_WIN32__
diff -r 3ebf16150b2e -r e747d2e26af0 include/win32/canfestival.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/win32/canfestival.h Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,39 @@
+/*
+This file is part of CanFestival, a library implementing CanOpen Stack.
+
+Copyright (C): Edouard TISSERANT and Francis DUPIN
+Win32 Port Leonid Tochinski
+
+See COPYING file for copyrights details.
+
+This 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; either
+version 2.1 of the License, or (at your option) any later version.
+
+This 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 this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+#ifndef CANFESTIVAL_H_
+#define CANFESTIVAL_H_
+
+#include "timerscfg.h"
+#include "can_driver.h"
+#include "data.h"
+
+#include
+typedef HINSTANCE LIB_HANDLE;
+
+UNS8 UnLoadCanDriver(LIB_HANDLE handle);
+LIB_HANDLE LoadCanDriver(char* driver_name);
+UNS8 canSend(CAN_PORT port, Message *m);
+CAN_PORT canOpen(s_BOARD *board, CO_Data * d);
+int canClose(CAN_PORT port);
+
+#endif /*CANFESTIVAL_H_*/
diff -r 3ebf16150b2e -r e747d2e26af0 include/win32/config.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/win32/config.h Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,41 @@
+/*
+This file is part of CanFestival, a library implementing CanOpen Stack.
+
+Copyright (C): Edouard TISSERANT and Francis DUPIN
+See COPYING file for copyrights details.
+
+This 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; either
+version 2.1 of the License, or (at your option) any later version.
+
+This 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 this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef _CONFIG_H_
+#define _CONFIG_H_
+
+#define MAX_CAN_BUS_ID 1
+#define SDO_MAX_LENGTH_TRANSFERT 32
+#define SDO_MAX_SIMULTANEOUS_TRANSFERTS 4
+#define NMT_MAX_NODE_ID 128
+#define SDO_TIMEOUT_MS 3000
+#define MAX_NB_TIMER 32
+// CANOPEN_BIG_ENDIAN is not defined
+#define CANOPEN_LITTLE_ENDIAN 1
+
+#define US_TO_TIMEVAL_FACTOR 1
+
+#define REPEAT_SDO_MAX_SIMULTANEOUS_TRANSFERTS_TIMES(repeat)\
+repeat repeat repeat repeat
+#define REPEAT_NMT_MAX_NODE_ID_TIMES(repeat)\
+repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat repeat
+
+#endif /* _CONFIG_H_ */
diff -r 3ebf16150b2e -r e747d2e26af0 include/win32/timerscfg.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/include/win32/timerscfg.h Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,38 @@
+/*
+This file is part of CanFestival, a library implementing CanOpen Stack.
+
+Copyright (C): Edouard TISSERANT and Francis DUPIN
+Win32 port by Leonid Tochinski
+
+See COPYING file for copyrights details.
+
+This 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; either
+version 2.1 of the License, or (at your option) any later version.
+
+This 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 this library; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+*/
+
+#ifndef __TIMERSCFG_H__
+#define __TIMERSCFG_H__
+
+#include
+
+// Time unit : us
+// Time resolution : 64bit (~584942 years)
+#define TIMEVAL unsigned long long
+#define TIMEVAL_MAX ~(TIMEVAL)0
+#define MS_TO_TIMEVAL(ms) ms*1000
+#define US_TO_TIMEVAL(us) us
+
+#define TASK_HANDLE HANDLE
+
+#endif
diff -r 3ebf16150b2e -r e747d2e26af0 src/Makefile.in
--- a/src/Makefile.in Tue Apr 03 20:20:27 2007 +0200
+++ b/src/Makefile.in Wed Apr 04 13:04:31 2007 +0200
@@ -23,8 +23,6 @@
CC = SUB_CC
PROG_CFLAGS = SUB_PROG_CFLAGS
-LIBS = -lm
-SHAREDLIBOPT = -shared
OS_NAME = SUB_OS_NAME
ARCH_NAME = SUB_ARCH_NAME
PREFIX = SUB_PREFIX
diff -r 3ebf16150b2e -r e747d2e26af0 src/sdo.c
--- a/src/sdo.c Tue Apr 03 20:20:27 2007 +0200
+++ b/src/sdo.c Wed Apr 04 13:04:31 2007 +0200
@@ -98,12 +98,12 @@
/* Reset timer handler */
d->transfers[id].timer = TIMER_NONE;
/* Call the user function to inform of the problem.*/
- (*d->SDOtimeoutError)(id);
+ (*d->SDOtimeoutError)((UNS8)id);
/* Sending a SDO abort */
sendSDOabort(d, d->transfers[id].whoami,
d->transfers[id].index, d->transfers[id].subIndex, SDOABT_TIMED_OUT);
/* Reset the line*/
- resetSDOline(d, id);
+ resetSDOline(d, (UNS8)id);
}
#define StopSDO_TIMER(id) \
@@ -136,7 +136,7 @@
UNS8 size;
UNS32 errorCode;
MSG_WAR(0x3A08, "Enter in SDOlineToObjdict ", line);
- size = d->transfers[line].count;
+ size = (UNS8)d->transfers[line].count;
errorCode = setODentry(d, d->transfers[line].index, d->transfers[line].subIndex,
(void *) d->transfers[line].data, &size, 1);
if (errorCode != OD_SUCCESSFUL)
@@ -191,7 +191,7 @@
MSG_ERR(0x1A11,"SDO Size of data too large. Exceed count", nbBytes);
return 0xFF;
}
- offset = d->transfers[line].offset;
+ offset = (UNS8)d->transfers[line].offset;
for (i = 0 ; i < nbBytes ; i++)
* (data + i) = d->transfers[line].data[offset + i];
d->transfers[line].offset = d->transfers[line].offset + nbBytes;
@@ -209,7 +209,7 @@
MSG_ERR(0x1A15,"SDO Size of data too large. Exceed SDO_MAX_LENGTH_TRANSFERT", nbBytes);
return 0xFF;
}
- offset = d->transfers[line].offset;
+ offset = (UNS8)d->transfers[line].offset;
for (i = 0 ; i < nbBytes ; i++)
d->transfers[line].data[offset + i] = * (data + i);
d->transfers[line].offset = d->transfers[line].offset + nbBytes;
@@ -327,7 +327,7 @@
if (d->transfers[line].count == 0) /* if received initiate SDO protocol with e=0 and s=0 */
* nbBytes = 0;
else
- * nbBytes = d->transfers[line].count - d->transfers[line].offset;
+ * nbBytes = (UNS8)d->transfers[line].count - (UNS8)d->transfers[line].offset;
return 0;
}
@@ -1298,7 +1298,7 @@
return d->transfers[line].state;
/* Transfert is finished. Put the value in the data. */
- * size = d->transfers[line].count;
+ * size = (UNS8)d->transfers[line].count;
for ( i = 0 ; i < *size ; i++) {
# ifdef CANOPEN_BIG_ENDIAN
if (d->transfers[line].dataType != visible_string)
diff -r 3ebf16150b2e -r e747d2e26af0 src/win32/CanFestival-3.def
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/win32/CanFestival-3.def Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,85 @@
+; CanFestival-3.def : Declares the module parameters.
+
+LIBRARY "CanFestival-3.DLL"
+
+EXPORTS
+ getNodeState
+ heartbeatInit
+ heartbeatStop
+ proceedNODE_GUARD
+ masterSendNMTstateChange
+ masterSendNMTnodeguard
+ masterRequestNodeState
+ proceedNMTstateChange
+ slaveSendBootUp
+ accessDictionaryError
+ getODentry
+ setODentry
+ scanIndexOD
+ RegisterSetODentryCallBack
+ sendPDO
+ PDOmGR
+ buildPDO
+ sendPDOrequest
+ proceedPDO
+; sendPDOevent
+ SDOlineToObjdict
+ objdictToSDOline
+ lineToSDO
+ SDOtoLine
+ failedSDO
+ resetSDO
+ resetSDOline
+ initSDOline
+ getSDOfreeLine
+ getSDOlineOnUse
+ closeSDOtransfer
+ getSDOlineRestBytes
+ setSDOlineRestBytes
+ sendSDO
+ sendSDOabort
+ proceedSDO
+ writeNetworkDict
+ readNetworkDict
+ readNetworkDictCallback
+ getReadResultNetworkDict
+ getWriteResultNetworkDict
+ canDispatch
+ getState
+ setState
+ getNodeId
+ setNodeId
+; initPreOperationalMode
+ sendSYNC
+ proceedSYNC
+ SetAlarm
+ DelAlarm
+ TimeDispatch
+ setTimer
+ getElapsedTime
+ StartTimerLoop
+ StopTimerLoop
+ CreateReceiveTask
+ LoadCanDriver
+ canSend
+ canReceive
+ canOpen
+ canClose
+ lss_SwitchModeGlobal
+ lss_ConfigureNode_ID
+ lss_ConfigureBitTimingParameters
+ lss_ActivateBitTimingParameters_master
+ lss_ActivateBitTimingParameters_slave
+ lss_StoreConfiguredParameters
+ lss_InquireLSSAddress_master
+ lss_InquireLSSAddress_slave
+ lss_IdentifyRemoteSlaves
+ lss_validate_address
+ lss_IdentifySlave
+ canSaveData
+ canReadData
+ nvram_open
+ nvram_close
+ nvram_write
+ nvram_read
+ led_set_state
diff -r 3ebf16150b2e -r e747d2e26af0 src/win32/CanFestival-3.rc
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/win32/CanFestival-3.rc Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,104 @@
+// Microsoft Visual C++ generated resource script.
+//
+#include "resource.h"
+
+#define APSTUDIO_READONLY_SYMBOLS
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 2 resource.
+//
+#include "afxres.h"
+
+/////////////////////////////////////////////////////////////////////////////
+#undef APSTUDIO_READONLY_SYMBOLS
+
+/////////////////////////////////////////////////////////////////////////////
+// English (U.S.) resources
+
+#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
+#ifdef _WIN32
+LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
+#pragma code_page(1252)
+#endif //_WIN32
+
+#ifdef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// TEXTINCLUDE
+//
+
+1 TEXTINCLUDE
+BEGIN
+ "resource.h\0"
+END
+
+2 TEXTINCLUDE
+BEGIN
+ "#include ""afxres.h""\r\n"
+ "\0"
+END
+
+3 TEXTINCLUDE
+BEGIN
+ "\r\n"
+ "\0"
+END
+
+#endif // APSTUDIO_INVOKED
+
+
+/////////////////////////////////////////////////////////////////////////////
+//
+// Version
+//
+
+VS_VERSION_INFO VERSIONINFO
+ FILEVERSION 3,0,0,0
+ PRODUCTVERSION 3,0,0,0
+ FILEFLAGSMASK 0x17L
+#ifdef _DEBUG
+ FILEFLAGS 0x1L
+#else
+ FILEFLAGS 0x0L
+#endif
+ FILEOS 0x4L
+ FILETYPE 0x2L
+ FILESUBTYPE 0x0L
+BEGIN
+ BLOCK "StringFileInfo"
+ BEGIN
+ BLOCK "040904b0"
+ BEGIN
+ VALUE "Comments", "Win32 CanFestival port"
+ VALUE "CompanyName", "http://canfestival.sourceforge.net/"
+ VALUE "FileDescription", "CanFestival-3 Win32 port"
+ VALUE "FileVersion", "3, 0, 0, 0"
+ VALUE "InternalName", "CanFestival"
+ VALUE "LegalCopyright", "Copyright (C) 2007"
+ VALUE "LegalTrademarks", "CanFestival is an OpenSource (LGPL) CANOpen framework"
+ VALUE "OriginalFilename", "CanFestival-3.dll"
+ VALUE "ProductName", "CanFestival-3 Win32 port"
+ VALUE "ProductVersion", "3, 0, 0, 0"
+ END
+ END
+ BLOCK "VarFileInfo"
+ BEGIN
+ VALUE "Translation", 0x409, 1200
+ END
+END
+
+#endif // English (U.S.) resources
+/////////////////////////////////////////////////////////////////////////////
+
+
+
+#ifndef APSTUDIO_INVOKED
+/////////////////////////////////////////////////////////////////////////////
+//
+// Generated from the TEXTINCLUDE 3 resource.
+//
+
+
+/////////////////////////////////////////////////////////////////////////////
+#endif // not APSTUDIO_INVOKED
+
diff -r 3ebf16150b2e -r e747d2e26af0 src/win32/resource.h
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/win32/resource.h Wed Apr 04 13:04:31 2007 +0200
@@ -0,0 +1,14 @@
+//{{NO_DEPENDENCIES}}
+// Microsoft Visual C++ generated include file.
+// Used by CanFestival-3.rc
+
+// Next default values for new objects
+//
+#ifdef APSTUDIO_INVOKED
+#ifndef APSTUDIO_READONLY_SYMBOLS
+#define _APS_NEXT_RESOURCE_VALUE 101
+#define _APS_NEXT_COMMAND_VALUE 40001
+#define _APS_NEXT_CONTROL_VALUE 1001
+#define _APS_NEXT_SYMED_VALUE 101
+#endif
+#endif